This is v3 of the patch series for implementing clock tree for DaVinci SoCs
using common clk framework.
supported platforms: DM644x
This code base can be accessed at
https://gitorious.org/~m-karicheri/linux-davinci/linux-davinci-clk/commits/common-clk-v3
The patch series is split in two parts:-
patches prefixed with "clk" are for clk drivers
patches prefixed with "ARM" are for davinci machine specific code.
revision history:
-----------------
updates in v3:
- Major changes done based on review of v2 to move the clock data and
initialization code to drivers/clk/davinci. There is a soc specific
code (for example dm644x-clock.c) for doing clock initialization.
- Files renamed based on the review comments.
- Only DM644x is supported. Other devices will be added as the code
matures so that unnecessary rework can be avoided.
- Incorporated comments from Nori Sekhar and Linus (comments coding
style)
- Added clk-div clock to represent DaVinci pll divider clocks
- Removed clk-keystone-pll.c (will be added later)
updates in v2:
- updates to davinci_clk to use union for clk driver platform data
- Fixed Linus Walleij' comment on code comment
- added code clean up that takes out the ifdef used in previous patches
updates in v1:
- Added DM365 and DM355
- updates to davinci_clk struct to accomodate clk-fixed-factor data
initial version:-
Currently arch/arm/mach-davinci/clock.c and arch/arm/mach-davinci/psc.c
implements clock drivers for DaVinci. This patch makes these code obsolete
and migrate the SoC code to use the common clk based drivers. This adds
two clk drivers specific to DaVinci and Keystone (found in c6x arch such
as C6678) devices. Some of the existing clk drivers such as clk-fixed-rate,
clk-divider, and clk-mux are re-used in addition to the DaVinci specific
drivers to initialize the clock tree for the SoCs. Please refer chapter 6
of http://www.ti.com/lit/ug/sprue14c/sprue14c.pdf for details of the
PLL hardware in DM6446 and chapter 7 for defails of the PSC hardware.
There are two Main PLLs in DM644x. PLL1 and PLL2. Each of these generate
different clocks in the DM device through PLL dividers. Figure above shows this
for PLL1. Similar hardware exists for PLL2 and the related output clocks. The
hardware is similar in most of the DM SoCs. Some of the recent Keystone devices
(c6678 under c6x architecture) include a slight variant of the PLL that
implemented different registers for the multipliers and dividers. All of these
devices include PLL dividers (PLLDIVx) and Power Sleep controllers (PSC). The
SoCs defines various Power Domains and Clock domains and there are PSC modules
that controls power and clocks to various hardware IPs of the SoC.
Following drivers are used for various clock hardware blocks:-
CLKIN and OSCIN - clk-fixed-rate (existing driver)
MUX - clk-mux (existing driver)
PLLDIVx - davinci/clk-div (new driver)
PLL mult/div - clk-pll (new driver)
PSC - clk-psc.c (new driver)
Please note that initially only platforms listed above are supported. The
idea is to review the initial patch set and get a feedback on the overall
structure of the code organization. The other SoCs will be added in subsequent
patch revisions.
The driver code implements the features needed to support the platforms
listed above. It is expected that these drivers get updated in subsequent
patch revisions to support additional SoCs. I have boot tested this on DM6446
EVM. Also verified reboot command works and the clock rates are set as before.
The patches depends on the following patches that I had sent for review earlier:
davinci spi driver preparation @
https://patchwork.kernel.org/patch/1389321/
davinci watchdog driver preparation @
https://lkml.org/lkml/2012/9/7/634
davinci nand driver preparation @
https://lkml.org/lkml/2012/9/7/635
davinci i2c driver preparation @
https://patchwork.kernel.org/patch/1388841/
davinci gpio driver preparation @
https://lkml.org/lkml/2012/8/31/341
[RFC - PATCH] base:pm: prepare driver for common clock framework
ISSUES to discuss
-----------------
Following are to be discussed as part of this patch review.
1. arch/arm/pm.c. This is configuring PLL controller registers for suspend and
resume. It appears that we need to move this code to clk-pll.c?? But
I can't find APIs for suspend and resume in the common clk framework. How
is this expected to work? Currently i have kept the code ASIS.
2. There are usecount=1 in the old clock implementation for dsp, vicp and timer2
clocks. CLK_IGNORE_UNUSED flag is used currently to implement the same as
disabling these unused clocks causes issues in boot up,
HELP NEEDED!!:
--------------
I am doing this work as a background activity and hence the progress will be
slow. Please volunteer to help me in this effort by offering to test or migrating
other devices to this framework.
Murali Karicheri (11):
clk: davinci - add main PLL clock driver
clk: davinci - add PSC clock driver
clk: davinci - common clk utilities to init clk driver
clk: davinci - add pll divider clock driver
clk: davinci - add dm644x clock initialization
clk: davinci - add build infrastructure for DaVinci clock drivers
ARM: davinci - restructure header files for common clock migration
ARM: davinci - migrating to use common clock init code
ARM: davinci - dm644x: update SoC code to remove the clock data
ARM: davinci - migrate to common clock
ARM: davinci - common clock migration: clean up the old code
arch/arm/Kconfig | 1 +
arch/arm/mach-davinci/Kconfig | 2 +
arch/arm/mach-davinci/Makefile | 15 +-
arch/arm/mach-davinci/clock.c | 669 ---------------------------
arch/arm/mach-davinci/clock.h | 135 ------
arch/arm/mach-davinci/common.c | 10 -
arch/arm/mach-davinci/cpufreq.c | 2 -
arch/arm/mach-davinci/davinci.h | 3 +
arch/arm/mach-davinci/devices.c | 1 -
arch/arm/mach-davinci/dm644x.c | 302 +-----------
arch/arm/mach-davinci/include/mach/clock.h | 21 -
arch/arm/mach-davinci/include/mach/common.h | 10 +-
arch/arm/mach-davinci/include/mach/pll.h | 46 ++
arch/arm/mach-davinci/include/mach/psc.h | 209 ---------
arch/arm/mach-davinci/include/mach/time.h | 2 +-
arch/arm/mach-davinci/pm.c | 3 +-
arch/arm/mach-davinci/psc.c | 112 -----
arch/arm/mach-davinci/sleep.S | 3 +-
arch/arm/mach-davinci/time.c | 6 +-
drivers/clk/Kconfig | 2 +
drivers/clk/Makefile | 1 +
drivers/clk/davinci/Kconfig | 44 ++
drivers/clk/davinci/Makefile | 5 +
drivers/clk/davinci/clk-div.c | 124 +++++
drivers/clk/davinci/clk-div.h | 42 ++
drivers/clk/davinci/clk-pll.c | 146 ++++++
drivers/clk/davinci/clk-pll.h | 57 +++
drivers/clk/davinci/clk-psc.c | 207 +++++++++
drivers/clk/davinci/clk-psc.h | 46 ++
drivers/clk/davinci/clock.c | 112 +++++
drivers/clk/davinci/clock.h | 80 ++++
drivers/clk/davinci/dm644x-clock.c | 304 ++++++++++++
drivers/clk/davinci/pll.h | 83 ++++
drivers/clk/davinci/psc.h | 215 +++++++++
34 files changed, 1530 insertions(+), 1490 deletions(-)
delete mode 100644 arch/arm/mach-davinci/clock.c
delete mode 100644 arch/arm/mach-davinci/clock.h
delete mode 100644 arch/arm/mach-davinci/include/mach/clock.h
create mode 100644 arch/arm/mach-davinci/include/mach/pll.h
delete mode 100644 arch/arm/mach-davinci/psc.c
create mode 100644 drivers/clk/davinci/Kconfig
create mode 100644 drivers/clk/davinci/Makefile
create mode 100644 drivers/clk/davinci/clk-div.c
create mode 100644 drivers/clk/davinci/clk-div.h
create mode 100644 drivers/clk/davinci/clk-pll.c
create mode 100644 drivers/clk/davinci/clk-pll.h
create mode 100644 drivers/clk/davinci/clk-psc.c
create mode 100644 drivers/clk/davinci/clk-psc.h
create mode 100644 drivers/clk/davinci/clock.c
create mode 100644 drivers/clk/davinci/clock.h
create mode 100644 drivers/clk/davinci/dm644x-clock.c
create mode 100644 drivers/clk/davinci/pll.h
create mode 100644 drivers/clk/davinci/psc.h
--
1.7.9.5
pll.h is added to migrate some of the PLL controller defines for sleep.S.
psc.h is modified to keep only PSC modules definitions needed by sleep.S
after migrating to common clock. The definitions under
ifdef CONFIG_COMMON_CLK will be removed in a subsequent patch.
davinci_watchdog_reset prototype is moved to time.h as clock.h is
being obsoleted. sleep.S and pm.c is modified to include the new header
file replacements.
Signed-off-by: Murali Karicheri <[email protected]>
---
arch/arm/mach-davinci/devices.c | 2 ++
arch/arm/mach-davinci/include/mach/pll.h | 46 +++++++++++++++++++++++++++++
arch/arm/mach-davinci/include/mach/psc.h | 4 +++
arch/arm/mach-davinci/include/mach/time.h | 4 ++-
arch/arm/mach-davinci/pm.c | 4 +++
arch/arm/mach-davinci/sleep.S | 4 +++
6 files changed, 63 insertions(+), 1 deletion(-)
create mode 100644 arch/arm/mach-davinci/include/mach/pll.h
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index d2f96662..96ee175 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -24,7 +24,9 @@
#include <mach/time.h>
#include "davinci.h"
+#ifndef CONFIG_COMMON_CLK
#include "clock.h"
+#endif
#define DAVINCI_I2C_BASE 0x01C21000
#define DAVINCI_ATA_BASE 0x01C66000
diff --git a/arch/arm/mach-davinci/include/mach/pll.h b/arch/arm/mach-davinci/include/mach/pll.h
new file mode 100644
index 0000000..fa51bc4
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/pll.h
@@ -0,0 +1,46 @@
+/*
+ * TI DaVinci PLL definitions
+ *
+ * Copyright (C) 2006-2012 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __ASM_ARCH_PLL_H
+#define __ASM_ARCH_PLL_H
+
+/* PLL/Reset register offsets */
+#define PLLCTL 0x100
+#define PLLCTL_PLLEN BIT(0)
+#define PLLCTL_PLLPWRDN BIT(1)
+#define PLLCTL_PLLRST BIT(3)
+#define PLLCTL_PLLDIS BIT(4)
+#define PLLCTL_PLLENSRC BIT(5)
+#define PLLCTL_CLKMODE BIT(8)
+#define PLLDIV_EN BIT(15)
+#define PLLDIV1 0x118
+/*
+ * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN
+ * cycles to ensure that the PLLC has switched to bypass mode. Delay of 1us
+ * ensures we are good for all > 4MHz OSCIN/CLKIN inputs. Typically the input
+ * is ~25MHz. Units are micro seconds.
+ */
+#define PLL_BYPASS_TIME 1
+/* From OMAP-L138 datasheet table 6-4. Units are micro seconds */
+#define PLL_RESET_TIME 1
+/*
+ * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4
+ * Units are micro seconds.
+ */
+#define PLL_LOCK_TIME 20
+#define PLLSTAT_GOSTAT BIT(0)
+#define PLLCMD_GOSET BIT(0)
+
+#endif /* __ASM_ARCH_PLL_H */
diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h
index 405318e..eb464d3 100644
--- a/arch/arm/mach-davinci/include/mach/psc.h
+++ b/arch/arm/mach-davinci/include/mach/psc.h
@@ -27,6 +27,7 @@
#ifndef __ASM_ARCH_PSC_H
#define __ASM_ARCH_PSC_H
+#ifndef CONFIG_COMMON_CLK
#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000
/* Power and Sleep Controller (PSC) Domains */
@@ -227,6 +228,7 @@
#define TNETV107X_LPSC_DDR2_EMIF1_VRST 42
#define TNETV107X_LPSC_DDR2_EMIF2_VCTL_RST 43
#define TNETV107X_LPSC_MAX 44
+#endif
/* PSC register offsets */
#define EPCPR 0x070
@@ -251,9 +253,11 @@
#ifndef __ASSEMBLER__
+#ifndef CONFIG_COMMON_CLK
extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
unsigned int id, bool enable, u32 flags);
+#endif
#endif
diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h
index 1c971d8..7faa530 100644
--- a/arch/arm/mach-davinci/include/mach/time.h
+++ b/arch/arm/mach-davinci/include/mach/time.h
@@ -31,5 +31,7 @@ enum {
#define ID_TO_TIMER(id) (IS_TIMER1(id) != 0)
extern struct davinci_timer_instance davinci_timer_instance[];
-
+#ifdef CONFIG_COMMON_CLK
+extern void davinci_watchdog_reset(struct platform_device *);
+#endif
#endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */
diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c
index eb8360b..8802fdc 100644
--- a/arch/arm/mach-davinci/pm.c
+++ b/arch/arm/mach-davinci/pm.c
@@ -23,7 +23,11 @@
#include <mach/sram.h>
#include <mach/pm.h>
+#ifndef CONFIG_COMMON_CLK
#include "clock.h"
+#else
+#include <mach/pll.h>
+#endif
#define DEEPSLEEP_SLEEPCOUNT_MASK 0xFFFF
diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S
index d4e9316..a3bd60d 100644
--- a/arch/arm/mach-davinci/sleep.S
+++ b/arch/arm/mach-davinci/sleep.S
@@ -24,7 +24,11 @@
#include <mach/psc.h>
#include <mach/ddr2.h>
+#ifndef CONFIG_COMMON_CLK
#include "clock.h"
+#else
+#include <mach/pll.h>
+#endif
/* Arbitrary, hardware currently does not update PHYRDY correctly */
#define PHYRDY_CYCLES 0x1000
--
1.7.9.5
This updates clk Makefile and Kconfig to integrate the DaVinci specific
clock drivers. Also add new Kconfig and Makefile for these drivers.
Signed-off-by: Murali Karicheri <[email protected]>
---
drivers/clk/Kconfig | 2 ++
drivers/clk/Makefile | 1 +
drivers/clk/davinci/Kconfig | 44 ++++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/Makefile | 5 +++++
4 files changed, 52 insertions(+)
create mode 100644 drivers/clk/davinci/Kconfig
create mode 100644 drivers/clk/davinci/Makefile
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 7f0b5ca..1ad2ab0 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -33,6 +33,8 @@ config COMMON_CLK_DEBUG
clk_flags, clk_prepare_count, clk_enable_count &
clk_notifier_count.
+source "drivers/clk/davinci/Kconfig"
+
config COMMON_CLK_WM831X
tristate "Clock driver for WM831x/2x PMICs"
depends on MFD_WM831X
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 5869ea3..b127b6f 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
obj-$(CONFIG_PLAT_SPEAR) += spear/
obj-$(CONFIG_ARCH_U300) += clk-u300.o
obj-$(CONFIG_ARCH_INTEGRATOR) += versatile/
+obj-$(CONFIG_DAVINCI_CLKS) += davinci/
# Chip specific
obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
diff --git a/drivers/clk/davinci/Kconfig b/drivers/clk/davinci/Kconfig
new file mode 100644
index 0000000..e53bbc3
--- /dev/null
+++ b/drivers/clk/davinci/Kconfig
@@ -0,0 +1,44 @@
+menu "TI DaVinci Clock drivers"
+ depends on COMMON_CLK
+
+config CLK_DAVINCI_PSC
+ bool "TI DaVici PSC clock driver"
+ default n
+ ---help---
+ Selects clock driver for DaVinci PSC clocks. This clock
+ hardware is found on TI DaVinci SoCs and other SoCs that
+ uses this hardware IP. This hardware has a local power
+ sleep control module that gate the clock to the IP.
+
+config CLK_DAVINCI_PLL
+ bool "DaVici main PLL clock"
+ ---help---
+ Selects clock driver for DaVinci main PLL. This clock
+ hardware is found on TI DaVinci SoCs. This typically has
+ a multiplier, a pre divider and post driver. Some of the
+ SoCs has the the dividers fixed, and others have it
+ programmable
+
+config CLK_DAVINCI_PLLDIV
+ bool "DaVici PLL divider clock"
+ ---help---
+ Selects clock driver for DaVinci PLL divider. This clock
+ hardware is found on TI DaVinci SoCs. This typically has
+ a divider and an enable bit to bypass or enable the
+ divider.
+
+config DAVINCI_CLKS
+ bool "TI DaVinci common clocks"
+ default n
+ select CLK_DAVINCI_PSC
+ select CLK_DAVINCI_PLLDIV
+ ---help---
+ Selects common clock drivers for DaVinci. These clocks
+ are re-used across many TI SoCs that are based on DaVinci and
+ Keystone (c6x) families. This config option is used to select
+ the common clock driver for DaVinci based SoCs. SoCs specific
+ Kconfig option needs to select the driver for clocks specific
+ to the SoC.
+
+endmenu
+
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
new file mode 100644
index 0000000..0e13986
--- /dev/null
+++ b/drivers/clk/davinci/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_CLK_DAVINCI_PLL) += clk-pll.o
+obj-$(CONFIG_CLK_DAVINCI_PLLDIV) += clk-div.o
+obj-$(CONFIG_CLK_DAVINCI_PSC) += clk-psc.o
+obj-$(CONFIG_DAVINCI_CLKS) += clock.o
+obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x-clock.o
--
1.7.9.5
This is the common clk driver initialization functions for DaVinci
SoCs and other SoCs that uses similar hardware architecture.
clock.h also defines struct types for clock definitions in a SoC
and clock data type for configuring clk-mux. The initialization
functions are used by clock initialization code in a specific
platform/SoC.
Signed-off-by: Murali Karicheri <[email protected]>
---
drivers/clk/davinci/clock.c | 112 +++++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/clock.h | 80 +++++++++++++++++++++++++++++++
2 files changed, 192 insertions(+)
create mode 100644 drivers/clk/davinci/clock.c
create mode 100644 drivers/clk/davinci/clock.h
diff --git a/drivers/clk/davinci/clock.c b/drivers/clk/davinci/clock.c
new file mode 100644
index 0000000..ad02149
--- /dev/null
+++ b/drivers/clk/davinci/clock.c
@@ -0,0 +1,112 @@
+/*
+ * clock.c - davinci clock initialization functions for various clocks
+ *
+ * Copyright (C) 2006-2012 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/init.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include "clk-pll.h"
+#include "clk-psc.h"
+#include "clk-div.h"
+#include "clock.h"
+
+static DEFINE_SPINLOCK(_lock);
+
+#ifdef CONFIG_CLK_DAVINCI_PLL
+struct clk *davinci_pll_clk(const char *name, const char *parent,
+ u32 phys_pllm, u32 phys_prediv, u32 phys_postdiv,
+ struct clk_pll_data *pll_data)
+{
+ struct clk *clkp = NULL;
+
+ pll_data->reg_pllm = ioremap(phys_pllm, 4);
+ if (WARN_ON(!pll_data->reg_pllm))
+ return clkp;
+
+ pll_data->reg_prediv = ioremap(phys_prediv, 4);
+ if (WARN_ON(!pll_data->reg_prediv))
+ goto error1;
+
+ pll_data->reg_postdiv = ioremap(phys_postdiv, 4);
+ if (WARN_ON(!pll_data->reg_postdiv))
+ goto error2;
+
+ return clk_register_davinci_pll(NULL, name, parent, pll_data);
+error1:
+ iounmap(pll_data->reg_pllm);
+error2:
+ iounmap(pll_data->reg_prediv);
+ return clkp;
+}
+#else
+struct clk *davinci_pll_clk(const char *name, const char *parent,
+ u32 phys_pllm, u32 phys_prediv, u32 phys_postdiv,
+ struct clk_pll_data *pll_data)
+{
+ return NULL;
+}
+#endif
+
+struct clk *davinci_mux_clk(const char *name, u8 num_parents,
+ const char **parents, struct clk_mux_data *data)
+
+{
+ void __iomem *reg;
+
+ reg = ioremap(data->phys_reg, 4);
+ if (WARN_ON(!reg))
+ return NULL;
+
+ return clk_register_mux(NULL, name, parents, num_parents, data->flags,
+ reg, data->shift, data->width, data->mux_flags,
+ &_lock);
+}
+
+struct clk *davinci_plldiv_clk(const char *name, const char *parent,
+ struct clk_plldiv_data *data)
+{
+ /*
+ * This is a PLL divider clock with divider specified by
+ * div_reg in pll_div_data.
+ */
+ data->reg = ioremap(data->phys_div_reg, 4);
+ if (WARN_ON(!data->reg))
+ return NULL;
+
+ return clk_register_davinci_plldiv(NULL, name, parent, data, &_lock);
+}
+
+inline struct clk *davinci_fixed_factor_clk(const char *name,
+ const char *parent, unsigned long flags,
+ unsigned int mult, unsigned int div)
+{
+ if (WARN_ON(!mult))
+ return NULL;
+
+ if (WARN_ON(!div))
+ return NULL;
+
+ return clk_register_fixed_factor(NULL, name, parent, flags, mult, div);
+}
+
+inline struct clk *davinci_fixed_ref_clk(const char *name,
+ unsigned long rate)
+{
+ return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
+}
+
+inline struct clk *davinci_psc_clk(const char *name, const char *parent,
+ struct clk_psc_data *data)
+{
+ return clk_register_davinci_psc(NULL, name, parent, data);
+}
diff --git a/drivers/clk/davinci/clock.h b/drivers/clk/davinci/clock.h
new file mode 100644
index 0000000..73204b8
--- /dev/null
+++ b/drivers/clk/davinci/clock.h
@@ -0,0 +1,80 @@
+/*
+ * TI DaVinci Clock definitions - Contains Macros and Types used for
+ * defining various clocks on a DaVinci SoC
+ *
+ * Copyright (C) 2012 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __DAVINCI_CLOCK_H
+#define __DAVINCI_CLOCK_H
+
+#include <linux/types.h>
+
+/* general flags: */
+#define ALWAYS_ENABLED BIT(0)
+
+/**
+ * struct clk_mux_data - struct for clk mux data to configure clk-mux
+ *
+ * @flags: base flags for clk driver
+ * @mux_flags: mux driver flags
+ * @shift: shift applied to mux selector bits
+ * @width: width of the mux selctor bits
+ * @phys_reg: physical address of the mux register
+ */
+struct clk_mux_data {
+ u32 flags;
+ u8 mux_flags;
+ u8 shift;
+ u8 width;
+ u32 phys_reg;
+};
+
+/**
+ * struct davinci_clk - struct for defining DaVinci clocks for a SoC.
+ *
+ * @name: name of the clock
+ * @parent: name of parent clock
+ * @flags: General flags for all drivers used by platform clock init code
+ * @data: data specific to a clock used by the driver
+ * @dev_id: dev_id used to look up this clock. If this is NULL
+ * clock name is used for lookup.
+ */
+struct davinci_clk {
+ const char *name;
+ const char *parent;
+ u32 flags;
+ void *data;
+ char *dev_id;
+};
+
+/* function prototypes for initializing various clocks */
+struct clk *davinci_fixed_ref_clk(const char *name,
+ unsigned long rate);
+
+struct clk *davinci_pll_clk(const char *name, const char *parent,
+ u32 phys_pllm, u32 phys_prediv, u32 phys_postdiv,
+ struct clk_pll_data *pll_data);
+
+
+struct clk *davinci_mux_clk(const char *name, u8 num_parents,
+ const char **parents, struct clk_mux_data *data);
+
+struct clk *davinci_plldiv_clk(const char *name, const char *parent,
+ struct clk_plldiv_data *data);
+
+struct clk *davinci_psc_clk(const char *name, const char *parent,
+ struct clk_psc_data *data);
+
+struct clk *davinci_fixed_factor_clk(const char *name,
+ const char *parent, unsigned long flags,
+ unsigned int mult, unsigned int div);
+#endif
--
1.7.9.5
This is the driver for the main PLL clock hardware found on DM SoCs.
This driver borrowed code from arch/arm/mach-davinci/clock.c and
implemented the driver as per common clock provider API. The main PLL
hardware typically has a multiplier, a pre-divider and a post-divider.
Some of the SoCs has the divider fixed meaning they can not be
configured through a register. HAS_PREDIV and HAS_POSTDIV flags are used
to tell the driver if a hardware has these dividers present or not.
Driver is configured through the struct clk_pll_data that has the
SoC specific clock data.
Signed-off-by: Murali Karicheri <[email protected]>
---
drivers/clk/davinci/clk-pll.c | 146 +++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/clk-pll.h | 57 ++++++++++++++++
2 files changed, 203 insertions(+)
create mode 100644 drivers/clk/davinci/clk-pll.c
create mode 100644 drivers/clk/davinci/clk-pll.h
diff --git a/drivers/clk/davinci/clk-pll.c b/drivers/clk/davinci/clk-pll.c
new file mode 100644
index 0000000..337e9af
--- /dev/null
+++ b/drivers/clk/davinci/clk-pll.c
@@ -0,0 +1,146 @@
+/*
+ * DaVinci main pll clk driver
+ *
+ * Copyright (C) 2006-2012 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * DaVinci PLL clk driver implementation
+ *
+ * TODO - Add set_parent_rate()
+ */
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include "clk-pll.h"
+
+#define PLLDIV_EN BIT(15)
+
+/**
+ * struct clk_pll - DaVinci main pll clock
+ * @hw: clk_hw for the pll
+ * @pll_data: ptr to driver specific data
+ */
+struct clk_pll {
+ struct clk_hw hw;
+ struct clk_pll_data *pll_data;
+};
+
+#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
+
+/**
+ * clk_pllclk_recalc() - function to calculate rate
+ *
+ * @hw: clk_hw for the pll
+ * @parent_rate: Parent clk rate
+ */
+static unsigned long clk_pllclk_recalc(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pll *pll = to_clk_pll(hw);
+ struct clk_pll_data *pll_data = pll->pll_data;
+ u32 mult = 1, prediv = 1, postdiv = 1;
+ unsigned long rate = parent_rate;
+
+ mult = readl(pll_data->reg_pllm);
+
+ /*
+ * if fixed_multiplier is non zero, multiply pllm value by this
+ * value.
+ */
+ if (pll_data->fixed_multiplier)
+ mult = pll_data->fixed_multiplier *
+ (mult & pll_data->pllm_mask);
+ else
+ mult = (mult & pll_data->pllm_mask) + 1;
+
+ if (pll_data->pll_flags & CLK_DAVINCI_PLL_HAS_PREDIV) {
+ /*
+ * prediv register is not present, take fixed_prediv value from
+ * pll_data for prediv
+ */
+ if (pll_data->fixed_prediv) {
+ prediv = pll_data->fixed_prediv;
+ } else {
+ prediv = readl(pll_data->reg_prediv);
+ if (prediv & PLLDIV_EN)
+ prediv = (prediv & pll_data->prediv_mask) + 1;
+ else
+ prediv = 1;
+ }
+ }
+
+ if (pll_data->pll_flags & CLK_DAVINCI_PLL_HAS_POSTDIV) {
+ postdiv = readl(pll_data->reg_postdiv);
+ if (postdiv & PLLDIV_EN)
+ postdiv = (postdiv & pll_data->postdiv_mask) + 1;
+ else
+ postdiv = 1;
+ }
+
+ rate /= prediv;
+ rate *= mult;
+ rate /= postdiv;
+
+ pr_debug("PLL%d: input = %lu MHz [ ",
+ pll_data->num, parent_rate / 1000000);
+ if (prediv > 1)
+ pr_debug("/ %d ", prediv);
+ if (mult > 1)
+ pr_debug("* %d ", mult);
+ if (postdiv > 1)
+ pr_debug("/ %d ", postdiv);
+ pr_debug("] --> %lu MHz output.\n", rate / 1000000);
+
+ return rate;
+}
+
+static const struct clk_ops clk_pll_ops = {
+ .recalc_rate = clk_pllclk_recalc,
+};
+
+/**
+ * clk_register_davinci_pll() - register function for DaVinci main pll clk
+ *
+ * @dev: device ptr
+ * @name: name of the clk
+ * @parent_name: name of the parent clk
+ * @pll_data: ptr to pll clk data
+ */
+struct clk *clk_register_davinci_pll(struct device *dev, const char *name,
+ const char *parent_name,
+ struct clk_pll_data *pll_data)
+{
+ struct clk_init_data init;
+ struct clk_pll *pll;
+ struct clk *clk;
+
+ if (!pll_data)
+ return ERR_PTR(-ENODEV);
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &clk_pll_ops;
+ init.flags = pll_data->flags;
+ init.parent_names = (parent_name ? &parent_name : NULL);
+ init.num_parents = (parent_name ? 1 : 0);
+
+ pll->pll_data = pll_data;
+ pll->hw.init = &init;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
diff --git a/drivers/clk/davinci/clk-pll.h b/drivers/clk/davinci/clk-pll.h
new file mode 100644
index 0000000..c9e4826
--- /dev/null
+++ b/drivers/clk/davinci/clk-pll.h
@@ -0,0 +1,57 @@
+/*
+ * Header file for DaVinci main pll clk driver
+ *
+ * Copyright (C) 2006-2012 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * DaVinci PLL clk driver implementation
+ *
+ * TODO - Add set_parent_rate()
+ */
+
+#ifndef __CLK_DAVINCI_PLL_H
+#define __CLK_DAVINCI_PLL_H
+
+/* PLL flags */
+#define CLK_DAVINCI_PLL_HAS_PREDIV BIT(0)
+#define CLK_DAVINCI_PLL_HAS_POSTDIV BIT(1)
+
+/**
+ * struct clk_pll_data - configuration for DaVinci main PLL clk driver
+ *
+ * @reg_pllm: io mapped address of pllm register
+ * @reg_prediv: io mapped address of prediv register
+ * @reg_postdiv: io mapped address of postdiv register
+ * @pllm_mask: mask bits for pllm val
+ * @prediv_mask: mask bits for prediv val
+ * @postdiv_mask: mask bits for postdiv val
+ * @num: PLL number. Some SoCs have more than one main PLL
+ * 0 - PLL0 and 1 - PLL1
+ * @flags - clk driver base flags
+ * @pll_flags - clk_pll driver flags
+ * @fixed_prediv - fixed value of prediv used instead of value from prediv reg
+ * @fixed_multiplier - pllm register value is multiplied by this factor on a
+ * a particular SoC. For other SoCs, this is set to zero.
+ */
+struct clk_pll_data {
+ void __iomem *reg_pllm;
+ void __iomem *reg_prediv;
+ void __iomem *reg_postdiv;
+ u32 pllm_mask;
+ u32 prediv_mask;
+ u32 postdiv_mask;
+ u32 num;
+ u32 flags;
+ u32 pll_flags;
+ u32 fixed_prediv;
+ u32 fixed_multiplier;
+};
+
+struct clk *clk_register_davinci_pll(struct device *dev,
+ const char *name, const char *parent_name,
+ struct clk_pll_data *pll_data);
+#endif /* CLK_DAVINCI_PLL_H */
--
1.7.9.5
This is the driver for the Power Sleep Controller (PSC) hardware
found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed
code from arch/arm/mach-davinci/psc.c and implemented the driver
as per common clock provider API. The PSC module is responsible for
enabling/disabling the Power Domain and Clock domain for different IPs
present in the SoC. The driver is configured through the clock data
passed to the driver through struct clk_psc_data.
Signed-off-by: Murali Karicheri <[email protected]>
---
drivers/clk/davinci/clk-psc.c | 207 +++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/clk-psc.h | 46 +++++++++
2 files changed, 253 insertions(+)
create mode 100644 drivers/clk/davinci/clk-psc.c
create mode 100644 drivers/clk/davinci/clk-psc.h
diff --git a/drivers/clk/davinci/clk-psc.c b/drivers/clk/davinci/clk-psc.c
new file mode 100644
index 0000000..40d5f06
--- /dev/null
+++ b/drivers/clk/davinci/clk-psc.c
@@ -0,0 +1,207 @@
+/*
+ * PSC clk driver for DaVinci devices
+ *
+ * Copyright (C) 2006-2012 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include "clk-psc.h"
+
+/* PSC register offsets */
+#define EPCPR 0x070
+#define PTCMD 0x120
+#define PTSTAT 0x128
+#define PDSTAT 0x200
+#define PDCTL 0x300
+#define MDSTAT 0x800
+#define MDCTL 0xA00
+
+/* PSC module states */
+#define PSC_STATE_SWRSTDISABLE 0
+#define PSC_STATE_SYNCRST 1
+#define PSC_STATE_DISABLE 2
+#define PSC_STATE_ENABLE 3
+
+#define MDSTAT_STATE_MASK 0x3f
+#define PDSTAT_STATE_MASK 0x1f
+#define MDCTL_FORCE BIT(31)
+#define PDCTL_NEXT BIT(0)
+#define PDCTL_EPCGOOD BIT(8)
+
+/**
+ * struct clk_psc - DaVinci PSC clock driver data
+ *
+ * @hw: clk_hw for the psc
+ * @psc_data: Driver specific data
+ */
+struct clk_psc {
+ struct clk_hw hw;
+ struct clk_psc_data *psc_data;
+ spinlock_t *lock;
+};
+
+#define to_clk_psc(_hw) container_of(_hw, struct clk_psc, hw)
+
+/**
+ * clk_psc_config() - configure psc hardware
+ *
+ * @base: io mapped base address of the psc
+ * @domain: Power Domain id of the module
+ * @id: lpsc id
+ * @enable: 1 - enable psc, 0 - disable psc
+ * @flags: psc driver specific flags
+ */
+static void clk_psc_config(void __iomem *base, unsigned int domain,
+ unsigned int id, bool enable, u32 flags)
+{
+ u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl;
+ u32 next_state = PSC_STATE_ENABLE;
+ void __iomem *psc_base = base;
+
+ if (!enable) {
+ if (flags & CLK_PSC_SWRSTDISABLE)
+ next_state = PSC_STATE_SWRSTDISABLE;
+ else
+ next_state = PSC_STATE_DISABLE;
+ }
+
+ mdctl = readl(psc_base + MDCTL + 4 * id);
+ mdctl &= ~MDSTAT_STATE_MASK;
+ mdctl |= next_state;
+ if (flags & CLK_PSC_FORCE)
+ mdctl |= MDCTL_FORCE;
+ writel(mdctl, psc_base + MDCTL + 4 * id);
+
+ pdstat = readl(psc_base + PDSTAT + 4 * domain);
+ if ((pdstat & PDSTAT_STATE_MASK) == 0) {
+ pdctl = readl(psc_base + PDCTL + 4 * domain);
+ pdctl |= PDCTL_NEXT;
+ writel(pdctl, psc_base + PDCTL + 4 * domain);
+
+ ptcmd = 1 << domain;
+ writel(ptcmd, psc_base + PTCMD);
+
+ if (flags & CLK_PSC_HAS_EXT_POWER_CNTL) {
+ do {
+ epcpr = readl(psc_base + EPCPR);
+ } while ((((epcpr >> domain) & 1) == 0));
+ }
+
+ pdctl = readl(psc_base + PDCTL + 4 * domain);
+ pdctl |= 0x100;
+ writel(pdctl, psc_base + PDCTL + 4 * domain);
+
+ pdctl = readl(psc_base + PDCTL + 4 * domain);
+ pdctl |= PDCTL_EPCGOOD;
+ writel(pdctl, psc_base + PDCTL + 4 * domain);
+ } else {
+ ptcmd = 1 << domain;
+ writel(ptcmd, psc_base + PTCMD);
+ }
+
+ do {
+ ptstat = readl(psc_base + PTSTAT);
+ } while (!(((ptstat >> domain) & 1) == 0));
+
+ do {
+ mdstat = readl(psc_base + MDSTAT + 4 * id);
+ } while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
+}
+
+/**
+ * clk_psc_is_enabled() - Is psc clock enabled
+ *
+ * @hw: clk hw for the psc
+ */
+static int clk_psc_is_enabled(struct clk_hw *hw)
+{
+ struct clk_psc *psc = to_clk_psc(hw);
+ struct clk_psc_data *psc_data = psc->psc_data;
+ u32 mdstat;
+
+ mdstat = readl(psc_data->reg_base + MDSTAT + 4 * psc_data->lpsc_id);
+
+ /* if clocked, state can be "Enable" or "SyncReset" */
+ return (mdstat & BIT(12)) ? 1 : 0;
+}
+
+/**
+ * clk_psc_enable() - Enable psc clock
+ *
+ * @hw: clk hw for the psc
+ */
+static int clk_psc_enable(struct clk_hw *hw)
+{
+ struct clk_psc *psc = to_clk_psc(hw);
+ struct clk_psc_data *psc_data = psc->psc_data;
+
+ clk_psc_config(psc_data->reg_base, psc_data->domain_id,
+ psc_data->lpsc_id, 1, psc_data->psc_flags);
+ return 0;
+}
+
+/**
+ * clk_psc_disable() - disable psc clock
+ *
+ * @hw: clk hw for the psc
+ */
+static void clk_psc_disable(struct clk_hw *hw)
+{
+ struct clk_psc *psc = to_clk_psc(hw);
+ struct clk_psc_data *psc_data = psc->psc_data;
+
+ clk_psc_config(psc_data->reg_base, psc_data->domain_id,
+ psc_data->lpsc_id, 0, psc_data->psc_flags);
+}
+
+static const struct clk_ops clk_psc_ops = {
+ .enable = clk_psc_enable,
+ .disable = clk_psc_disable,
+ .is_enabled = clk_psc_is_enabled,
+};
+
+/**
+ * clk_register_davinci_psc() - register function for DaVinci PSC clock
+ *
+ * @dev: clk device
+ * @name: name of the clock
+ * @parent_name: name of the parent clock
+ * @psc_data: ptr to psc clk data
+ */
+struct clk *clk_register_davinci_psc(struct device *dev, const char *name,
+ const char *parent_name, struct clk_psc_data *psc_data)
+{
+ struct clk_init_data init;
+ struct clk_psc *psc;
+ struct clk *clk;
+
+ psc = kzalloc(sizeof(*psc), GFP_KERNEL);
+ if (!psc)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &clk_psc_ops;
+ init.flags = psc_data->flags;
+ init.parent_names = (parent_name ? &parent_name : NULL);
+ init.num_parents = (parent_name ? 1 : 0);
+
+ psc->psc_data = psc_data;
+ psc->hw.init = &init;
+
+ clk = clk_register(NULL, &psc->hw);
+ if (IS_ERR(clk))
+ kfree(psc);
+
+ return clk;
+}
diff --git a/drivers/clk/davinci/clk-psc.h b/drivers/clk/davinci/clk-psc.h
new file mode 100644
index 0000000..26327d6
--- /dev/null
+++ b/drivers/clk/davinci/clk-psc.h
@@ -0,0 +1,46 @@
+/*
+ * PSC clk driver for DaVinci devices
+ *
+ * Copyright (C) 2006-2012 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __CLK_DAVINCI_PSC_H
+#define __CLK_DAVINCI_PSC_H
+
+/* PSC flags */
+
+/* Disable state is SwRstDisable */
+#define CLK_PSC_SWRSTDISABLE BIT(0)
+/* Force module state transtition */
+#define CLK_PSC_FORCE BIT(1)
+/* PSC has external power control available (for DM6446 SoC) */
+#define CLK_PSC_HAS_EXT_POWER_CNTL BIT(2)
+
+/**
+ * struct clk_psc_data - configuration for DaVinci psc clk driver
+ *
+ * @reg_base: io mapped address of psc register base
+ * @flags: clk driver base flags
+ * @psc_flags: clk_psc driver flags
+ * @lpsc_id: local power sleep controller id
+ * @gpsc_id: global power sleep controller id
+ * @domain_id: Power domain id
+ */
+struct clk_psc_data {
+ void __iomem *reg_base;
+ u32 flags;
+ u32 psc_flags;
+ u8 lpsc_id;
+ u8 gpsc_id;
+ u8 domain_id;
+};
+
+struct clk *clk_register_davinci_psc(struct device *dev,
+ const char *name, const char *parent_name,
+ struct clk_psc_data *psc_data);
+#endif /* __CLK_DAVINCI_PSC_H */
--
1.7.9.5
This patch clean up the obsoleted code after migrating to the
common clock framwork based code. Currently only dm644x is
supported as part of davinci_all_defconfig and other davinci
variants may not be buildable. But once all SoCs and machines
are migrated, some of these changes will be removed. However
this shows how the migration will happen.
Signed-off-by: Murali Karicheri <[email protected]>
---
arch/arm/mach-davinci/Makefile | 22 -
arch/arm/mach-davinci/clock.c | 669 ---------------------------
arch/arm/mach-davinci/clock.h | 135 ------
arch/arm/mach-davinci/common.c | 16 -
arch/arm/mach-davinci/cpufreq.c | 2 -
arch/arm/mach-davinci/devices.c | 3 -
arch/arm/mach-davinci/dm644x.c | 316 -------------
arch/arm/mach-davinci/include/mach/clock.h | 21 -
arch/arm/mach-davinci/include/mach/common.h | 12 -
arch/arm/mach-davinci/include/mach/psc.h | 213 ---------
arch/arm/mach-davinci/include/mach/time.h | 2 -
arch/arm/mach-davinci/pm.c | 5 -
arch/arm/mach-davinci/psc.c | 112 -----
arch/arm/mach-davinci/sleep.S | 5 -
arch/arm/mach-davinci/time.c | 7 +-
15 files changed, 1 insertion(+), 1539 deletions(-)
delete mode 100644 arch/arm/mach-davinci/clock.c
delete mode 100644 arch/arm/mach-davinci/clock.h
delete mode 100644 arch/arm/mach-davinci/include/mach/clock.h
delete mode 100644 arch/arm/mach-davinci/psc.c
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index 5a5b3dc..e0f7b6c 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -4,25 +4,13 @@
#
# Common objects
-ifndef CONFIG_COMMON_CLK
-obj-y := time.o clock.o serial.o psc.o \
- dma.o usb.o common.o sram.o aemif.o
-else
obj-y := time.o serial.o \
dma.o usb.o common.o sram.o aemif.o
-endif
obj-$(CONFIG_DAVINCI_MUX) += mux.o
# Chip specific
obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o devices.o
-ifndef CONFIG_COMMON_CLK
-obj-$(CONFIG_ARCH_DAVINCI_DM355) += dm355.o devices.o
-obj-$(CONFIG_ARCH_DAVINCI_DM365) += dm365.o devices.o
-obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o
-obj-$(CONFIG_ARCH_DAVINCI_DA830) += da830.o devices-da8xx.o
-obj-$(CONFIG_ARCH_DAVINCI_DA850) += da850.o devices-da8xx.o
-endif
obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += tnetv107x.o devices-tnetv107x.o
obj-$(CONFIG_AINTC) += irq.o
@@ -30,16 +18,6 @@ obj-$(CONFIG_CP_INTC) += cp_intc.o
# Board specific
obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o
-ifndef CONFIG_COMMON_CLK
-obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o
-obj-$(CONFIG_MACH_NEUROS_OSD2) += board-neuros-osd2.o
-obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-dm355-evm.o
-obj-$(CONFIG_MACH_DM355_LEOPARD) += board-dm355-leopard.o
-obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o cdce949.o
-obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o
-obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o
-obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o
-endif
obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o
obj-$(CONFIG_MACH_MITYOMAPL138) += board-mityomapl138.o
obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
deleted file mode 100644
index 34668ea..0000000
--- a/arch/arm/mach-davinci/clock.c
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
- * Clock and PLL control for DaVinci devices
- *
- * Copyright (C) 2006-2007 Texas Instruments.
- * Copyright (C) 2008-2009 Deep Root Systems, LLC
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/mutex.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-
-#include <mach/hardware.h>
-
-#include <mach/clock.h>
-#include <mach/psc.h>
-#include <mach/cputype.h>
-#include "clock.h"
-
-static LIST_HEAD(clocks);
-static DEFINE_MUTEX(clocks_mutex);
-static DEFINE_SPINLOCK(clockfw_lock);
-
-static void __clk_enable(struct clk *clk)
-{
- if (clk->parent)
- __clk_enable(clk->parent);
- if (clk->usecount++ == 0 && (clk->flags & CLK_PSC))
- davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
- true, clk->flags);
-}
-
-static void __clk_disable(struct clk *clk)
-{
- if (WARN_ON(clk->usecount == 0))
- return;
- if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) &&
- (clk->flags & CLK_PSC))
- davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
- false, clk->flags);
- if (clk->parent)
- __clk_disable(clk->parent);
-}
-
-int clk_enable(struct clk *clk)
-{
- unsigned long flags;
-
- if (clk == NULL || IS_ERR(clk))
- return -EINVAL;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- __clk_enable(clk);
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
- unsigned long flags;
-
- if (clk == NULL || IS_ERR(clk))
- return;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- __clk_disable(clk);
- spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
- if (clk == NULL || IS_ERR(clk))
- return -EINVAL;
-
- return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
- if (clk == NULL || IS_ERR(clk))
- return -EINVAL;
-
- if (clk->round_rate)
- return clk->round_rate(clk, rate);
-
- return clk->rate;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-/* Propagate rate to children */
-static void propagate_rate(struct clk *root)
-{
- struct clk *clk;
-
- list_for_each_entry(clk, &root->children, childnode) {
- if (clk->recalc)
- clk->rate = clk->recalc(clk);
- propagate_rate(clk);
- }
-}
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned long flags;
- int ret = -EINVAL;
-
- if (clk == NULL || IS_ERR(clk))
- return ret;
-
- if (clk->set_rate)
- ret = clk->set_rate(clk, rate);
-
- spin_lock_irqsave(&clockfw_lock, flags);
- if (ret == 0) {
- if (clk->recalc)
- clk->rate = clk->recalc(clk);
- propagate_rate(clk);
- }
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
- unsigned long flags;
-
- if (clk == NULL || IS_ERR(clk))
- return -EINVAL;
-
- /* Cannot change parent on enabled clock */
- if (WARN_ON(clk->usecount))
- return -EINVAL;
-
- mutex_lock(&clocks_mutex);
- clk->parent = parent;
- list_del_init(&clk->childnode);
- list_add(&clk->childnode, &clk->parent->children);
- mutex_unlock(&clocks_mutex);
-
- spin_lock_irqsave(&clockfw_lock, flags);
- if (clk->recalc)
- clk->rate = clk->recalc(clk);
- propagate_rate(clk);
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-int clk_register(struct clk *clk)
-{
- if (clk == NULL || IS_ERR(clk))
- return -EINVAL;
-
- if (WARN(clk->parent && !clk->parent->rate,
- "CLK: %s parent %s has no rate!\n",
- clk->name, clk->parent->name))
- return -EINVAL;
-
- INIT_LIST_HEAD(&clk->children);
-
- mutex_lock(&clocks_mutex);
- list_add_tail(&clk->node, &clocks);
- if (clk->parent)
- list_add_tail(&clk->childnode, &clk->parent->children);
- mutex_unlock(&clocks_mutex);
-
- /* If rate is already set, use it */
- if (clk->rate)
- return 0;
-
- /* Else, see if there is a way to calculate it */
- if (clk->recalc)
- clk->rate = clk->recalc(clk);
-
- /* Otherwise, default to parent rate */
- else if (clk->parent)
- clk->rate = clk->parent->rate;
-
- return 0;
-}
-EXPORT_SYMBOL(clk_register);
-
-void clk_unregister(struct clk *clk)
-{
- if (clk == NULL || IS_ERR(clk))
- return;
-
- mutex_lock(&clocks_mutex);
- list_del(&clk->node);
- list_del(&clk->childnode);
- mutex_unlock(&clocks_mutex);
-}
-EXPORT_SYMBOL(clk_unregister);
-
-#ifdef CONFIG_DAVINCI_RESET_CLOCKS
-/*
- * Disable any unused clocks left on by the bootloader
- */
-int __init davinci_clk_disable_unused(void)
-{
- struct clk *ck;
-
- spin_lock_irq(&clockfw_lock);
- list_for_each_entry(ck, &clocks, node) {
- if (ck->usecount > 0)
- continue;
- if (!(ck->flags & CLK_PSC))
- continue;
-
- /* ignore if in Disabled or SwRstDisable states */
- if (!davinci_psc_is_clk_active(ck->gpsc, ck->lpsc))
- continue;
-
- pr_debug("Clocks: disable unused %s\n", ck->name);
-
- davinci_psc_config(ck->domain, ck->gpsc, ck->lpsc,
- false, ck->flags);
- }
- spin_unlock_irq(&clockfw_lock);
-
- return 0;
-}
-#endif
-
-static unsigned long clk_sysclk_recalc(struct clk *clk)
-{
- u32 v, plldiv;
- struct pll_data *pll;
- unsigned long rate = clk->rate;
-
- /* If this is the PLL base clock, no more calculations needed */
- if (clk->pll_data)
- return rate;
-
- if (WARN_ON(!clk->parent))
- return rate;
-
- rate = clk->parent->rate;
-
- /* Otherwise, the parent must be a PLL */
- if (WARN_ON(!clk->parent->pll_data))
- return rate;
-
- pll = clk->parent->pll_data;
-
- /* If pre-PLL, source clock is before the multiplier and divider(s) */
- if (clk->flags & PRE_PLL)
- rate = pll->input_rate;
-
- if (!clk->div_reg)
- return rate;
-
- v = __raw_readl(pll->base + clk->div_reg);
- if (v & PLLDIV_EN) {
- plldiv = (v & pll->div_ratio_mask) + 1;
- if (plldiv)
- rate /= plldiv;
- }
-
- return rate;
-}
-
-int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate)
-{
- unsigned v;
- struct pll_data *pll;
- unsigned long input;
- unsigned ratio = 0;
-
- /* If this is the PLL base clock, wrong function to call */
- if (clk->pll_data)
- return -EINVAL;
-
- /* There must be a parent... */
- if (WARN_ON(!clk->parent))
- return -EINVAL;
-
- /* ... the parent must be a PLL... */
- if (WARN_ON(!clk->parent->pll_data))
- return -EINVAL;
-
- /* ... and this clock must have a divider. */
- if (WARN_ON(!clk->div_reg))
- return -EINVAL;
-
- pll = clk->parent->pll_data;
-
- input = clk->parent->rate;
-
- /* If pre-PLL, source clock is before the multiplier and divider(s) */
- if (clk->flags & PRE_PLL)
- input = pll->input_rate;
-
- if (input > rate) {
- /*
- * Can afford to provide an output little higher than requested
- * only if maximum rate supported by hardware on this sysclk
- * is known.
- */
- if (clk->maxrate) {
- ratio = DIV_ROUND_CLOSEST(input, rate);
- if (input / ratio > clk->maxrate)
- ratio = 0;
- }
-
- if (ratio == 0)
- ratio = DIV_ROUND_UP(input, rate);
-
- ratio--;
- }
-
- if (ratio > pll->div_ratio_mask)
- return -EINVAL;
-
- do {
- v = __raw_readl(pll->base + PLLSTAT);
- } while (v & PLLSTAT_GOSTAT);
-
- v = __raw_readl(pll->base + clk->div_reg);
- v &= ~pll->div_ratio_mask;
- v |= ratio | PLLDIV_EN;
- __raw_writel(v, pll->base + clk->div_reg);
-
- v = __raw_readl(pll->base + PLLCMD);
- v |= PLLCMD_GOSET;
- __raw_writel(v, pll->base + PLLCMD);
-
- do {
- v = __raw_readl(pll->base + PLLSTAT);
- } while (v & PLLSTAT_GOSTAT);
-
- return 0;
-}
-EXPORT_SYMBOL(davinci_set_sysclk_rate);
-
-static unsigned long clk_leafclk_recalc(struct clk *clk)
-{
- if (WARN_ON(!clk->parent))
- return clk->rate;
-
- return clk->parent->rate;
-}
-
-int davinci_simple_set_rate(struct clk *clk, unsigned long rate)
-{
- clk->rate = rate;
- return 0;
-}
-
-static unsigned long clk_pllclk_recalc(struct clk *clk)
-{
- u32 ctrl, mult = 1, prediv = 1, postdiv = 1;
- u8 bypass;
- struct pll_data *pll = clk->pll_data;
- unsigned long rate = clk->rate;
-
- ctrl = __raw_readl(pll->base + PLLCTL);
- rate = pll->input_rate = clk->parent->rate;
-
- if (ctrl & PLLCTL_PLLEN) {
- bypass = 0;
- mult = __raw_readl(pll->base + PLLM);
- if (cpu_is_davinci_dm365())
- mult = 2 * (mult & PLLM_PLLM_MASK);
- else
- mult = (mult & PLLM_PLLM_MASK) + 1;
- } else
- bypass = 1;
-
- if (pll->flags & PLL_HAS_PREDIV) {
- prediv = __raw_readl(pll->base + PREDIV);
- if (prediv & PLLDIV_EN)
- prediv = (prediv & pll->div_ratio_mask) + 1;
- else
- prediv = 1;
- }
-
- /* pre-divider is fixed, but (some?) chips won't report that */
- if (cpu_is_davinci_dm355() && pll->num == 1)
- prediv = 8;
-
- if (pll->flags & PLL_HAS_POSTDIV) {
- postdiv = __raw_readl(pll->base + POSTDIV);
- if (postdiv & PLLDIV_EN)
- postdiv = (postdiv & pll->div_ratio_mask) + 1;
- else
- postdiv = 1;
- }
-
- if (!bypass) {
- rate /= prediv;
- rate *= mult;
- rate /= postdiv;
- }
-
- pr_debug("PLL%d: input = %lu MHz [ ",
- pll->num, clk->parent->rate / 1000000);
- if (bypass)
- pr_debug("bypass ");
- if (prediv > 1)
- pr_debug("/ %d ", prediv);
- if (mult > 1)
- pr_debug("* %d ", mult);
- if (postdiv > 1)
- pr_debug("/ %d ", postdiv);
- pr_debug("] --> %lu MHz output.\n", rate / 1000000);
-
- return rate;
-}
-
-/**
- * davinci_set_pllrate - set the output rate of a given PLL.
- *
- * Note: Currently tested to work with OMAP-L138 only.
- *
- * @pll: pll whose rate needs to be changed.
- * @prediv: The pre divider value. Passing 0 disables the pre-divider.
- * @pllm: The multiplier value. Passing 0 leads to multiply-by-one.
- * @postdiv: The post divider value. Passing 0 disables the post-divider.
- */
-int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
- unsigned int mult, unsigned int postdiv)
-{
- u32 ctrl;
- unsigned int locktime;
- unsigned long flags;
-
- if (pll->base == NULL)
- return -EINVAL;
-
- /*
- * PLL lock time required per OMAP-L138 datasheet is
- * (2000 * prediv)/sqrt(pllm) OSCIN cycles. We approximate sqrt(pllm)
- * as 4 and OSCIN cycle as 25 MHz.
- */
- if (prediv) {
- locktime = ((2000 * prediv) / 100);
- prediv = (prediv - 1) | PLLDIV_EN;
- } else {
- locktime = PLL_LOCK_TIME;
- }
- if (postdiv)
- postdiv = (postdiv - 1) | PLLDIV_EN;
- if (mult)
- mult = mult - 1;
-
- /* Protect against simultaneous calls to PLL setting seqeunce */
- spin_lock_irqsave(&clockfw_lock, flags);
-
- ctrl = __raw_readl(pll->base + PLLCTL);
-
- /* Switch the PLL to bypass mode */
- ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
- __raw_writel(ctrl, pll->base + PLLCTL);
-
- udelay(PLL_BYPASS_TIME);
-
- /* Reset and enable PLL */
- ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
- __raw_writel(ctrl, pll->base + PLLCTL);
-
- if (pll->flags & PLL_HAS_PREDIV)
- __raw_writel(prediv, pll->base + PREDIV);
-
- __raw_writel(mult, pll->base + PLLM);
-
- if (pll->flags & PLL_HAS_POSTDIV)
- __raw_writel(postdiv, pll->base + POSTDIV);
-
- udelay(PLL_RESET_TIME);
-
- /* Bring PLL out of reset */
- ctrl |= PLLCTL_PLLRST;
- __raw_writel(ctrl, pll->base + PLLCTL);
-
- udelay(locktime);
-
- /* Remove PLL from bypass mode */
- ctrl |= PLLCTL_PLLEN;
- __raw_writel(ctrl, pll->base + PLLCTL);
-
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL(davinci_set_pllrate);
-
-/**
- * davinci_set_refclk_rate() - Set the reference clock rate
- * @rate: The new rate.
- *
- * Sets the reference clock rate to a given value. This will most likely
- * result in the entire clock tree getting updated.
- *
- * This is used to support boards which use a reference clock different
- * than that used by default in <soc>.c file. The reference clock rate
- * should be updated early in the boot process; ideally soon after the
- * clock tree has been initialized once with the default reference clock
- * rate (davinci_common_init()).
- *
- * Returns 0 on success, error otherwise.
- */
-int davinci_set_refclk_rate(unsigned long rate)
-{
- struct clk *refclk;
-
- refclk = clk_get(NULL, "ref");
- if (IS_ERR(refclk)) {
- pr_err("%s: failed to get reference clock.\n", __func__);
- return PTR_ERR(refclk);
- }
-
- clk_set_rate(refclk, rate);
-
- clk_put(refclk);
-
- return 0;
-}
-
-int __init davinci_clk_init(struct clk_lookup *clocks)
- {
- struct clk_lookup *c;
- struct clk *clk;
- size_t num_clocks = 0;
-
- for (c = clocks; c->clk; c++) {
- clk = c->clk;
-
- if (!clk->recalc) {
-
- /* Check if clock is a PLL */
- if (clk->pll_data)
- clk->recalc = clk_pllclk_recalc;
-
- /* Else, if it is a PLL-derived clock */
- else if (clk->flags & CLK_PLL)
- clk->recalc = clk_sysclk_recalc;
-
- /* Otherwise, it is a leaf clock (PSC clock) */
- else if (clk->parent)
- clk->recalc = clk_leafclk_recalc;
- }
-
- if (clk->pll_data) {
- struct pll_data *pll = clk->pll_data;
-
- if (!pll->div_ratio_mask)
- pll->div_ratio_mask = PLLDIV_RATIO_MASK;
-
- if (pll->phys_base && !pll->base) {
- pll->base = ioremap(pll->phys_base, SZ_4K);
- WARN_ON(!pll->base);
- }
- }
-
- if (clk->recalc)
- clk->rate = clk->recalc(clk);
-
- if (clk->lpsc)
- clk->flags |= CLK_PSC;
-
- clk_register(clk);
- num_clocks++;
-
- /* Turn on clocks that Linux doesn't otherwise manage */
- if (clk->flags & ALWAYS_ENABLED)
- clk_enable(clk);
- }
-
- clkdev_add_table(clocks, num_clocks);
-
- return 0;
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-
-#define CLKNAME_MAX 10 /* longest clock name */
-#define NEST_DELTA 2
-#define NEST_MAX 4
-
-static void
-dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
-{
- char *state;
- char buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX];
- struct clk *clk;
- unsigned i;
-
- if (parent->flags & CLK_PLL)
- state = "pll";
- else if (parent->flags & CLK_PSC)
- state = "psc";
- else
- state = "";
-
- /* <nest spaces> name <pad to end> */
- memset(buf, ' ', sizeof(buf) - 1);
- buf[sizeof(buf) - 1] = 0;
- i = strlen(parent->name);
- memcpy(buf + nest, parent->name,
- min(i, (unsigned)(sizeof(buf) - 1 - nest)));
-
- seq_printf(s, "%s users=%2d %-3s %9ld Hz\n",
- buf, parent->usecount, state, clk_get_rate(parent));
- /* REVISIT show device associations too */
-
- /* cost is now small, but not linear... */
- list_for_each_entry(clk, &parent->children, childnode) {
- dump_clock(s, nest + NEST_DELTA, clk);
- }
-}
-
-static int davinci_ck_show(struct seq_file *m, void *v)
-{
- struct clk *clk;
-
- /*
- * Show clock tree; We trust nonzero usecounts equate to PSC enables...
- */
- mutex_lock(&clocks_mutex);
- list_for_each_entry(clk, &clocks, node)
- if (!clk->parent)
- dump_clock(m, 0, clk);
- mutex_unlock(&clocks_mutex);
-
- return 0;
-}
-
-static int davinci_ck_open(struct inode *inode, struct file *file)
-{
- return single_open(file, davinci_ck_show, NULL);
-}
-
-static const struct file_operations davinci_ck_operations = {
- .open = davinci_ck_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int __init davinci_clk_debugfs_init(void)
-{
- debugfs_create_file("davinci_clocks", S_IFREG | S_IRUGO, NULL, NULL,
- &davinci_ck_operations);
- return 0;
-
-}
-device_initcall(davinci_clk_debugfs_init);
-#endif /* CONFIG_DEBUG_FS */
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
deleted file mode 100644
index 46f0f1b..0000000
--- a/arch/arm/mach-davinci/clock.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * TI DaVinci clock definitions
- *
- * Copyright (C) 2006-2007 Texas Instruments.
- * Copyright (C) 2008-2009 Deep Root Systems, LLC
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ARCH_ARM_DAVINCI_CLOCK_H
-#define __ARCH_ARM_DAVINCI_CLOCK_H
-
-#define DAVINCI_PLL1_BASE 0x01c40800
-#define DAVINCI_PLL2_BASE 0x01c40c00
-#define MAX_PLL 2
-
-/* PLL/Reset register offsets */
-#define PLLCTL 0x100
-#define PLLCTL_PLLEN BIT(0)
-#define PLLCTL_PLLPWRDN BIT(1)
-#define PLLCTL_PLLRST BIT(3)
-#define PLLCTL_PLLDIS BIT(4)
-#define PLLCTL_PLLENSRC BIT(5)
-#define PLLCTL_CLKMODE BIT(8)
-
-#define PLLM 0x110
-#define PLLM_PLLM_MASK 0xff
-
-#define PREDIV 0x114
-#define PLLDIV1 0x118
-#define PLLDIV2 0x11c
-#define PLLDIV3 0x120
-#define POSTDIV 0x128
-#define BPDIV 0x12c
-#define PLLCMD 0x138
-#define PLLSTAT 0x13c
-#define PLLALNCTL 0x140
-#define PLLDCHANGE 0x144
-#define PLLCKEN 0x148
-#define PLLCKSTAT 0x14c
-#define PLLSYSTAT 0x150
-#define PLLDIV4 0x160
-#define PLLDIV5 0x164
-#define PLLDIV6 0x168
-#define PLLDIV7 0x16c
-#define PLLDIV8 0x170
-#define PLLDIV9 0x174
-#define PLLDIV_EN BIT(15)
-#define PLLDIV_RATIO_MASK 0x1f
-
-/*
- * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN
- * cycles to ensure that the PLLC has switched to bypass mode. Delay of 1us
- * ensures we are good for all > 4MHz OSCIN/CLKIN inputs. Typically the input
- * is ~25MHz. Units are micro seconds.
- */
-#define PLL_BYPASS_TIME 1
-/* From OMAP-L138 datasheet table 6-4. Units are micro seconds */
-#define PLL_RESET_TIME 1
-/*
- * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4
- * Units are micro seconds.
- */
-#define PLL_LOCK_TIME 20
-
-#ifndef __ASSEMBLER__
-
-#include <linux/list.h>
-#include <linux/clkdev.h>
-
-#define PLLSTAT_GOSTAT BIT(0)
-#define PLLCMD_GOSET BIT(0)
-
-struct pll_data {
- u32 phys_base;
- void __iomem *base;
- u32 num;
- u32 flags;
- u32 input_rate;
- u32 div_ratio_mask;
-};
-#define PLL_HAS_PREDIV 0x01
-#define PLL_HAS_POSTDIV 0x02
-
-struct clk {
- struct list_head node;
- struct module *owner;
- const char *name;
- unsigned long rate;
- unsigned long maxrate; /* H/W supported max rate */
- u8 usecount;
- u8 lpsc;
- u8 gpsc;
- u8 domain;
- u32 flags;
- struct clk *parent;
- struct list_head children; /* list of children */
- struct list_head childnode; /* parent's child list node */
- struct pll_data *pll_data;
- u32 div_reg;
- unsigned long (*recalc) (struct clk *);
- int (*set_rate) (struct clk *clk, unsigned long rate);
- int (*round_rate) (struct clk *clk, unsigned long rate);
-};
-
-/* Clock flags: SoC-specific flags start at BIT(16) */
-#define ALWAYS_ENABLED BIT(1)
-#define CLK_PSC BIT(2)
-#define CLK_PLL BIT(3) /* PLL-derived clock */
-#define PRE_PLL BIT(4) /* source is before PLL mult/div */
-#define PSC_SWRSTDISABLE BIT(5) /* Disable state is SwRstDisable */
-#define PSC_FORCE BIT(6) /* Force module state transtition */
-
-#define CLK(dev, con, ck) \
- { \
- .dev_id = dev, \
- .con_id = con, \
- .clk = ck, \
- } \
-
-int davinci_clk_init(struct clk_lookup *clocks);
-int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
- unsigned int mult, unsigned int postdiv);
-int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate);
-int davinci_set_refclk_rate(unsigned long rate);
-int davinci_simple_set_rate(struct clk *clk, unsigned long rate);
-
-extern struct platform_device davinci_wdt_device;
-extern void davinci_watchdog_reset(struct platform_device *);
-
-#endif
-
-#endif
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
index 039494e..57f64b0 100644
--- a/arch/arm/mach-davinci/common.c
+++ b/arch/arm/mach-davinci/common.c
@@ -20,10 +20,6 @@
#include <mach/common.h>
#include <mach/cputype.h>
-#ifndef CONFIG_COMMON_CLK
-#include "clock.h"
-#endif
-
struct davinci_soc_info davinci_soc_info;
EXPORT_SYMBOL(davinci_soc_info);
@@ -107,15 +103,6 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info)
if (ret < 0)
goto err;
-#ifndef CONFIG_COMMON_CLK
- if (davinci_soc_info.cpu_clks) {
- ret = davinci_clk_init(davinci_soc_info.cpu_clks);
-
- if (ret != 0)
- goto err;
- }
-#endif
-
return;
err:
@@ -126,7 +113,4 @@ void __init davinci_init_late(void)
{
davinci_cpufreq_init();
davinci_pm_init();
-#ifndef CONFIG_COMMON_CLK
- davinci_clk_disable_unused();
-#endif
}
diff --git a/arch/arm/mach-davinci/cpufreq.c b/arch/arm/mach-davinci/cpufreq.c
index 4729eaa..4af8ceb 100644
--- a/arch/arm/mach-davinci/cpufreq.c
+++ b/arch/arm/mach-davinci/cpufreq.c
@@ -30,8 +30,6 @@
#include <mach/cpufreq.h>
#include <mach/common.h>
-#include "clock.h"
-
struct davinci_cpufreq {
struct device *dev;
struct clk *armclk;
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index 96ee175..eb8098e 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -24,9 +24,6 @@
#include <mach/time.h>
#include "davinci.h"
-#ifndef CONFIG_COMMON_CLK
-#include "clock.h"
-#endif
#define DAVINCI_I2C_BASE 0x01C21000
#define DAVINCI_ATA_BASE 0x01C66000
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index bf64b75..533c2e3 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -9,9 +9,6 @@
* or implied.
*/
#include <linux/init.h>
-#ifndef CONFIG_COMMON_CLK
-#include <linux/clk.h>
-#endif
#include <linux/serial_8250.h>
#include <linux/platform_device.h>
@@ -20,9 +17,6 @@
#include <mach/cputype.h>
#include <mach/edma.h>
#include <mach/irqs.h>
-#ifndef CONFIG_COMMON_CLK
-#include <mach/psc.h>
-#endif
#include <mach/mux.h>
#include <mach/time.h>
#include <mach/serial.h>
@@ -32,9 +26,6 @@
#include "davinci.h"
#include "mux.h"
#include "asp.h"
-#ifndef CONFIG_COMMON_CLK
-#include "clock.h"
-#endif
#define DM644X_EMAC_BASE 0x01c80000
#define DM644X_EMAC_MDIO_BASE (DM644X_EMAC_BASE + 0x4000)
@@ -43,296 +34,6 @@
#define DM644X_EMAC_CNTRL_RAM_OFFSET 0x2000
#define DM644X_EMAC_CNTRL_RAM_SIZE 0x2000
-#ifndef CONFIG_COMMON_CLK
-/*
- * Device specific clocks
- */
-#define DM644X_REF_FREQ 27000000
-
-static struct pll_data pll1_data = {
- .num = 1,
- .phys_base = DAVINCI_PLL1_BASE,
-};
-
-static struct pll_data pll2_data = {
- .num = 2,
- .phys_base = DAVINCI_PLL2_BASE,
-};
-
-static struct clk ref_clk = {
- .name = "ref_clk",
- .rate = DM644X_REF_FREQ,
-};
-
-static struct clk pll1_clk = {
- .name = "pll1",
- .parent = &ref_clk,
- .pll_data = &pll1_data,
- .flags = CLK_PLL,
-};
-
-static struct clk pll1_sysclk1 = {
- .name = "pll1_sysclk1",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV1,
-};
-
-static struct clk pll1_sysclk2 = {
- .name = "pll1_sysclk2",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV2,
-};
-
-static struct clk pll1_sysclk3 = {
- .name = "pll1_sysclk3",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV3,
-};
-
-static struct clk pll1_sysclk5 = {
- .name = "pll1_sysclk5",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV5,
-};
-
-static struct clk pll1_aux_clk = {
- .name = "pll1_aux_clk",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclkbp = {
- .name = "pll1_sysclkbp",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
- .div_reg = BPDIV
-};
-
-static struct clk pll2_clk = {
- .name = "pll2",
- .parent = &ref_clk,
- .pll_data = &pll2_data,
- .flags = CLK_PLL,
-};
-
-static struct clk pll2_sysclk1 = {
- .name = "pll2_sysclk1",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV1,
-};
-
-static struct clk pll2_sysclk2 = {
- .name = "pll2_sysclk2",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV2,
-};
-
-static struct clk pll2_sysclkbp = {
- .name = "pll2_sysclkbp",
- .parent = &pll2_clk,
- .flags = CLK_PLL | PRE_PLL,
- .div_reg = BPDIV
-};
-
-static struct clk dsp_clk = {
- .name = "dsp",
- .parent = &pll1_sysclk1,
- .lpsc = DAVINCI_LPSC_GEM,
- .domain = DAVINCI_GPSC_DSPDOMAIN,
- .usecount = 1, /* REVISIT how to disable? */
-};
-
-static struct clk arm_clk = {
- .name = "arm",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_ARM,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk vicp_clk = {
- .name = "vicp",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_IMCOP,
- .domain = DAVINCI_GPSC_DSPDOMAIN,
- .usecount = 1, /* REVISIT how to disable? */
-};
-
-static struct clk vpss_master_clk = {
- .name = "vpss_master",
- .parent = &pll1_sysclk3,
- .lpsc = DAVINCI_LPSC_VPSSMSTR,
- .flags = CLK_PSC,
-};
-
-static struct clk vpss_slave_clk = {
- .name = "vpss_slave",
- .parent = &pll1_sysclk3,
- .lpsc = DAVINCI_LPSC_VPSSSLV,
-};
-
-static struct clk uart0_clk = {
- .name = "uart0",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_UART0,
-};
-
-static struct clk uart1_clk = {
- .name = "uart1",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_UART1,
-};
-
-static struct clk uart2_clk = {
- .name = "uart2",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_UART2,
-};
-
-static struct clk emac_clk = {
- .name = "emac",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
-};
-
-static struct clk i2c_clk = {
- .name = "i2c",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_I2C,
-};
-
-static struct clk ide_clk = {
- .name = "ide",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_ATA,
-};
-
-static struct clk asp_clk = {
- .name = "asp0",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_McBSP,
-};
-
-static struct clk mmcsd_clk = {
- .name = "mmcsd",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_MMC_SD,
-};
-
-static struct clk spi_clk = {
- .name = "spi",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_SPI,
-};
-
-static struct clk gpio_clk = {
- .name = "gpio",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_GPIO,
-};
-
-static struct clk usb_clk = {
- .name = "usb",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_USB,
-};
-
-static struct clk vlynq_clk = {
- .name = "vlynq",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_VLYNQ,
-};
-
-static struct clk aemif_clk = {
- .name = "aemif",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_AEMIF,
-};
-
-static struct clk pwm0_clk = {
- .name = "pwm0",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_PWM0,
-};
-
-static struct clk pwm1_clk = {
- .name = "pwm1",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_PWM1,
-};
-
-static struct clk pwm2_clk = {
- .name = "pwm2",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_PWM2,
-};
-
-static struct clk timer0_clk = {
- .name = "timer0",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_TIMER0,
-};
-
-static struct clk timer1_clk = {
- .name = "timer1",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_TIMER1,
-};
-
-static struct clk timer2_clk = {
- .name = "timer2",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_TIMER2,
- .usecount = 1, /* REVISIT: why can't this be disabled? */
-};
-
-static struct clk_lookup dm644x_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "pll1", &pll1_clk),
- CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
- CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
- CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
- CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
- CLK(NULL, "pll1_aux", &pll1_aux_clk),
- CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
- CLK(NULL, "pll2", &pll2_clk),
- CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
- CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
- CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
- CLK(NULL, "dsp", &dsp_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "vicp", &vicp_clk),
- CLK(NULL, "vpss_master", &vpss_master_clk),
- CLK(NULL, "vpss_slave", &vpss_slave_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "uart0", &uart0_clk),
- CLK(NULL, "uart1", &uart1_clk),
- CLK(NULL, "uart2", &uart2_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("i2c_davinci.1", NULL, &i2c_clk),
- CLK("palm_bk3710", NULL, &ide_clk),
- CLK("davinci-mcbsp", NULL, &asp_clk),
- CLK("davinci_mmc.0", NULL, &mmcsd_clk),
- CLK(NULL, "spi", &spi_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK(NULL, "usb", &usb_clk),
- CLK(NULL, "vlynq", &vlynq_clk),
- CLK(NULL, "aemif", &aemif_clk),
- CLK(NULL, "pwm0", &pwm0_clk),
- CLK(NULL, "pwm1", &pwm1_clk),
- CLK(NULL, "pwm2", &pwm2_clk),
- CLK(NULL, "timer0", &timer0_clk),
- CLK(NULL, "timer1", &timer1_clk),
- CLK("watchdog", NULL, &timer2_clk),
- CLK(NULL, NULL, NULL),
-};
-#endif
-
static struct emac_platform_data dm644x_emac_pdata = {
.ctrl_reg_offset = DM644X_EMAC_CNTRL_OFFSET,
.ctrl_mod_reg_offset = DM644X_EMAC_CNTRL_MOD_OFFSET,
@@ -829,10 +530,6 @@ static struct davinci_id dm644x_ids[] = {
},
};
-#ifndef CONFIG_COMMON_CLK
-static u32 dm644x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-#endif
-
/*
* T0_BOT: Timer 0, bottom: clockevent source for hrtimers
* T0_TOP: Timer 0, top : clocksource for generic timekeeping
@@ -889,13 +586,7 @@ static struct davinci_soc_info davinci_soc_info_dm644x = {
.jtag_id_reg = 0x01c40028,
.ids = dm644x_ids,
.ids_num = ARRAY_SIZE(dm644x_ids),
-#ifdef CONFIG_COMMON_CLK
.clk_init = dm644x_clk_init,
-#else
- .cpu_clks = dm644x_clks,
- .psc_bases = dm644x_psc_bases,
- .psc_bases_num = ARRAY_SIZE(dm644x_psc_bases),
-#endif
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
.pinmux_pins = dm644x_pins,
.pinmux_pins_num = ARRAY_SIZE(dm644x_pins),
@@ -937,13 +628,6 @@ int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
dm644x_vpfe_dev.dev.platform_data = vpfe_cfg;
platform_device_register(&dm644x_ccdc_dev);
platform_device_register(&dm644x_vpfe_dev);
-#ifndef CONFIG_COMMON_CLK
- /* Add ccdc clock aliases */
- clk_add_alias("master", dm644x_ccdc_dev.name,
- "vpss_master", NULL);
- clk_add_alias("slave", dm644x_ccdc_dev.name,
- "vpss_slave", NULL);
-#endif
}
if (vpbe_cfg) {
diff --git a/arch/arm/mach-davinci/include/mach/clock.h b/arch/arm/mach-davinci/include/mach/clock.h
deleted file mode 100644
index a3b0402..0000000
--- a/arch/arm/mach-davinci/include/mach/clock.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * arch/arm/mach-davinci/include/mach/clock.h
- *
- * Clock control driver for DaVinci - header file
- *
- * Authors: Vladimir Barinov <[email protected]>
- *
- * 2007 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#ifndef __ASM_ARCH_DAVINCI_CLOCK_H
-#define __ASM_ARCH_DAVINCI_CLOCK_H
-
-struct clk;
-
-extern int clk_register(struct clk *clk);
-extern void clk_unregister(struct clk *clk);
-
-#endif
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 040db17..7572fae 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -54,13 +54,7 @@ struct davinci_soc_info {
u32 jtag_id_reg;
struct davinci_id *ids;
unsigned long ids_num;
-#ifdef CONFIG_COMMON_CLK
void (*clk_init)(void);
-#else
- struct clk_lookup *cpu_clks;
- u32 *psc_bases;
- unsigned long psc_bases_num;
-#endif
u32 pinmux_base;
const struct mux_config *pinmux_pins;
unsigned long pinmux_pins_num;
@@ -90,12 +84,6 @@ extern void davinci_init_ide(void);
void davinci_restart(char mode, const char *cmd);
void davinci_init_late(void);
-#ifdef CONFIG_DAVINCI_RESET_CLOCKS
-int davinci_clk_disable_unused(void);
-#else
-static inline int davinci_clk_disable_unused(void) { return 0; }
-#endif
-
#ifdef CONFIG_CPU_FREQ
int davinci_cpufreq_init(void);
#else
diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h
index eb464d3..ce792b8 100644
--- a/arch/arm/mach-davinci/include/mach/psc.h
+++ b/arch/arm/mach-davinci/include/mach/psc.h
@@ -27,209 +27,6 @@
#ifndef __ASM_ARCH_PSC_H
#define __ASM_ARCH_PSC_H
-#ifndef CONFIG_COMMON_CLK
-#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000
-
-/* Power and Sleep Controller (PSC) Domains */
-#define DAVINCI_GPSC_ARMDOMAIN 0
-#define DAVINCI_GPSC_DSPDOMAIN 1
-
-#define DAVINCI_LPSC_VPSSMSTR 0
-#define DAVINCI_LPSC_VPSSSLV 1
-#define DAVINCI_LPSC_TPCC 2
-#define DAVINCI_LPSC_TPTC0 3
-#define DAVINCI_LPSC_TPTC1 4
-#define DAVINCI_LPSC_EMAC 5
-#define DAVINCI_LPSC_EMAC_WRAPPER 6
-#define DAVINCI_LPSC_USB 9
-#define DAVINCI_LPSC_ATA 10
-#define DAVINCI_LPSC_VLYNQ 11
-#define DAVINCI_LPSC_UHPI 12
-#define DAVINCI_LPSC_DDR_EMIF 13
-#define DAVINCI_LPSC_AEMIF 14
-#define DAVINCI_LPSC_MMC_SD 15
-#define DAVINCI_LPSC_McBSP 17
-#define DAVINCI_LPSC_I2C 18
-#define DAVINCI_LPSC_UART0 19
-#define DAVINCI_LPSC_UART1 20
-#define DAVINCI_LPSC_UART2 21
-#define DAVINCI_LPSC_SPI 22
-#define DAVINCI_LPSC_PWM0 23
-#define DAVINCI_LPSC_PWM1 24
-#define DAVINCI_LPSC_PWM2 25
-#define DAVINCI_LPSC_GPIO 26
-#define DAVINCI_LPSC_TIMER0 27
-#define DAVINCI_LPSC_TIMER1 28
-#define DAVINCI_LPSC_TIMER2 29
-#define DAVINCI_LPSC_SYSTEM_SUBSYS 30
-#define DAVINCI_LPSC_ARM 31
-#define DAVINCI_LPSC_SCR2 32
-#define DAVINCI_LPSC_SCR3 33
-#define DAVINCI_LPSC_SCR4 34
-#define DAVINCI_LPSC_CROSSBAR 35
-#define DAVINCI_LPSC_CFG27 36
-#define DAVINCI_LPSC_CFG3 37
-#define DAVINCI_LPSC_CFG5 38
-#define DAVINCI_LPSC_GEM 39
-#define DAVINCI_LPSC_IMCOP 40
-
-#define DM355_LPSC_TIMER3 5
-#define DM355_LPSC_SPI1 6
-#define DM355_LPSC_MMC_SD1 7
-#define DM355_LPSC_McBSP1 8
-#define DM355_LPSC_PWM3 10
-#define DM355_LPSC_SPI2 11
-#define DM355_LPSC_RTO 12
-#define DM355_LPSC_VPSS_DAC 41
-
-/* DM365 */
-#define DM365_LPSC_TIMER3 5
-#define DM365_LPSC_SPI1 6
-#define DM365_LPSC_MMC_SD1 7
-#define DM365_LPSC_McBSP1 8
-#define DM365_LPSC_PWM3 10
-#define DM365_LPSC_SPI2 11
-#define DM365_LPSC_RTO 12
-#define DM365_LPSC_TIMER4 17
-#define DM365_LPSC_SPI0 22
-#define DM365_LPSC_SPI3 38
-#define DM365_LPSC_SPI4 39
-#define DM365_LPSC_EMAC 40
-#define DM365_LPSC_VOICE_CODEC 44
-#define DM365_LPSC_DAC_CLK 46
-#define DM365_LPSC_VPSSMSTR 47
-#define DM365_LPSC_MJCP 50
-
-/*
- * LPSC Assignments
- */
-#define DM646X_LPSC_ARM 0
-#define DM646X_LPSC_C64X_CPU 1
-#define DM646X_LPSC_HDVICP0 2
-#define DM646X_LPSC_HDVICP1 3
-#define DM646X_LPSC_TPCC 4
-#define DM646X_LPSC_TPTC0 5
-#define DM646X_LPSC_TPTC1 6
-#define DM646X_LPSC_TPTC2 7
-#define DM646X_LPSC_TPTC3 8
-#define DM646X_LPSC_PCI 13
-#define DM646X_LPSC_EMAC 14
-#define DM646X_LPSC_VDCE 15
-#define DM646X_LPSC_VPSSMSTR 16
-#define DM646X_LPSC_VPSSSLV 17
-#define DM646X_LPSC_TSIF0 18
-#define DM646X_LPSC_TSIF1 19
-#define DM646X_LPSC_DDR_EMIF 20
-#define DM646X_LPSC_AEMIF 21
-#define DM646X_LPSC_McASP0 22
-#define DM646X_LPSC_McASP1 23
-#define DM646X_LPSC_CRGEN0 24
-#define DM646X_LPSC_CRGEN1 25
-#define DM646X_LPSC_UART0 26
-#define DM646X_LPSC_UART1 27
-#define DM646X_LPSC_UART2 28
-#define DM646X_LPSC_PWM0 29
-#define DM646X_LPSC_PWM1 30
-#define DM646X_LPSC_I2C 31
-#define DM646X_LPSC_SPI 32
-#define DM646X_LPSC_GPIO 33
-#define DM646X_LPSC_TIMER0 34
-#define DM646X_LPSC_TIMER1 35
-#define DM646X_LPSC_ARM_INTC 45
-
-/* PSC0 defines */
-#define DA8XX_LPSC0_TPCC 0
-#define DA8XX_LPSC0_TPTC0 1
-#define DA8XX_LPSC0_TPTC1 2
-#define DA8XX_LPSC0_EMIF25 3
-#define DA8XX_LPSC0_SPI0 4
-#define DA8XX_LPSC0_MMC_SD 5
-#define DA8XX_LPSC0_AINTC 6
-#define DA8XX_LPSC0_ARM_RAM_ROM 7
-#define DA8XX_LPSC0_SECU_MGR 8
-#define DA8XX_LPSC0_UART0 9
-#define DA8XX_LPSC0_SCR0_SS 10
-#define DA8XX_LPSC0_SCR1_SS 11
-#define DA8XX_LPSC0_SCR2_SS 12
-#define DA8XX_LPSC0_PRUSS 13
-#define DA8XX_LPSC0_ARM 14
-#define DA8XX_LPSC0_GEM 15
-
-/* PSC1 defines */
-#define DA850_LPSC1_TPCC1 0
-#define DA8XX_LPSC1_USB20 1
-#define DA8XX_LPSC1_USB11 2
-#define DA8XX_LPSC1_GPIO 3
-#define DA8XX_LPSC1_UHPI 4
-#define DA8XX_LPSC1_CPGMAC 5
-#define DA8XX_LPSC1_EMIF3C 6
-#define DA8XX_LPSC1_McASP0 7
-#define DA830_LPSC1_McASP1 8
-#define DA850_LPSC1_SATA 8
-#define DA830_LPSC1_McASP2 9
-#define DA8XX_LPSC1_SPI1 10
-#define DA8XX_LPSC1_I2C 11
-#define DA8XX_LPSC1_UART1 12
-#define DA8XX_LPSC1_UART2 13
-#define DA8XX_LPSC1_LCDC 16
-#define DA8XX_LPSC1_PWM 17
-#define DA850_LPSC1_MMC_SD1 18
-#define DA8XX_LPSC1_ECAP 20
-#define DA830_LPSC1_EQEP 21
-#define DA850_LPSC1_TPTC2 21
-#define DA8XX_LPSC1_SCR_P0_SS 24
-#define DA8XX_LPSC1_SCR_P1_SS 25
-#define DA8XX_LPSC1_CR_P3_SS 26
-#define DA8XX_LPSC1_L3_CBA_RAM 31
-
-/* TNETV107X LPSC Assignments */
-#define TNETV107X_LPSC_ARM 0
-#define TNETV107X_LPSC_GEM 1
-#define TNETV107X_LPSC_DDR2_PHY 2
-#define TNETV107X_LPSC_TPCC 3
-#define TNETV107X_LPSC_TPTC0 4
-#define TNETV107X_LPSC_TPTC1 5
-#define TNETV107X_LPSC_RAM 6
-#define TNETV107X_LPSC_MBX_LITE 7
-#define TNETV107X_LPSC_LCD 8
-#define TNETV107X_LPSC_ETHSS 9
-#define TNETV107X_LPSC_AEMIF 10
-#define TNETV107X_LPSC_CHIP_CFG 11
-#define TNETV107X_LPSC_TSC 12
-#define TNETV107X_LPSC_ROM 13
-#define TNETV107X_LPSC_UART2 14
-#define TNETV107X_LPSC_PKTSEC 15
-#define TNETV107X_LPSC_SECCTL 16
-#define TNETV107X_LPSC_KEYMGR 17
-#define TNETV107X_LPSC_KEYPAD 18
-#define TNETV107X_LPSC_GPIO 19
-#define TNETV107X_LPSC_MDIO 20
-#define TNETV107X_LPSC_SDIO0 21
-#define TNETV107X_LPSC_UART0 22
-#define TNETV107X_LPSC_UART1 23
-#define TNETV107X_LPSC_TIMER0 24
-#define TNETV107X_LPSC_TIMER1 25
-#define TNETV107X_LPSC_WDT_ARM 26
-#define TNETV107X_LPSC_WDT_DSP 27
-#define TNETV107X_LPSC_SSP 28
-#define TNETV107X_LPSC_TDM0 29
-#define TNETV107X_LPSC_VLYNQ 30
-#define TNETV107X_LPSC_MCDMA 31
-#define TNETV107X_LPSC_USB0 32
-#define TNETV107X_LPSC_TDM1 33
-#define TNETV107X_LPSC_DEBUGSS 34
-#define TNETV107X_LPSC_ETHSS_RGMII 35
-#define TNETV107X_LPSC_SYSTEM 36
-#define TNETV107X_LPSC_IMCOP 37
-#define TNETV107X_LPSC_SPARE 38
-#define TNETV107X_LPSC_SDIO1 39
-#define TNETV107X_LPSC_USB1 40
-#define TNETV107X_LPSC_USBSS 41
-#define TNETV107X_LPSC_DDR2_EMIF1_VRST 42
-#define TNETV107X_LPSC_DDR2_EMIF2_VCTL_RST 43
-#define TNETV107X_LPSC_MAX 44
-#endif
-
/* PSC register offsets */
#define EPCPR 0x070
#define PTCMD 0x120
@@ -251,14 +48,4 @@
#define PDCTL_NEXT BIT(0)
#define PDCTL_EPCGOOD BIT(8)
-#ifndef __ASSEMBLER__
-
-#ifndef CONFIG_COMMON_CLK
-extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
-extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
- unsigned int id, bool enable, u32 flags);
-#endif
-
-#endif
-
#endif /* __ASM_ARCH_PSC_H */
diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h
index 7faa530..90b3633 100644
--- a/arch/arm/mach-davinci/include/mach/time.h
+++ b/arch/arm/mach-davinci/include/mach/time.h
@@ -31,7 +31,5 @@ enum {
#define ID_TO_TIMER(id) (IS_TIMER1(id) != 0)
extern struct davinci_timer_instance davinci_timer_instance[];
-#ifdef CONFIG_COMMON_CLK
extern void davinci_watchdog_reset(struct platform_device *);
-#endif
#endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */
diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c
index 8802fdc..7540f4e 100644
--- a/arch/arm/mach-davinci/pm.c
+++ b/arch/arm/mach-davinci/pm.c
@@ -22,12 +22,7 @@
#include <mach/da8xx.h>
#include <mach/sram.h>
#include <mach/pm.h>
-
-#ifndef CONFIG_COMMON_CLK
-#include "clock.h"
-#else
#include <mach/pll.h>
-#endif
#define DEEPSLEEP_SLEEPCOUNT_MASK 0xFFFF
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
deleted file mode 100644
index d7e210f..0000000
--- a/arch/arm/mach-davinci/psc.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * TI DaVinci Power and Sleep Controller (PSC)
- *
- * Copyright (C) 2006 Texas Instruments.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-
-#include <mach/cputype.h>
-#include <mach/psc.h>
-
-#include "clock.h"
-
-/* Return nonzero iff the domain's clock is active */
-int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
-{
- void __iomem *psc_base;
- u32 mdstat;
- struct davinci_soc_info *soc_info = &davinci_soc_info;
-
- if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
- pr_warning("PSC: Bad psc data: 0x%x[%d]\n",
- (int)soc_info->psc_bases, ctlr);
- return 0;
- }
-
- psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
- mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
- iounmap(psc_base);
-
- /* if clocked, state can be "Enable" or "SyncReset" */
- return mdstat & BIT(12);
-}
-
-/* Enable or disable a PSC domain */
-void davinci_psc_config(unsigned int domain, unsigned int ctlr,
- unsigned int id, bool enable, u32 flags)
-{
- u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl;
- void __iomem *psc_base;
- struct davinci_soc_info *soc_info = &davinci_soc_info;
- u32 next_state = PSC_STATE_ENABLE;
-
- if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
- pr_warning("PSC: Bad psc data: 0x%x[%d]\n",
- (int)soc_info->psc_bases, ctlr);
- return;
- }
-
- psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
-
- if (!enable) {
- if (flags & PSC_SWRSTDISABLE)
- next_state = PSC_STATE_SWRSTDISABLE;
- else
- next_state = PSC_STATE_DISABLE;
- }
-
- mdctl = __raw_readl(psc_base + MDCTL + 4 * id);
- mdctl &= ~MDSTAT_STATE_MASK;
- mdctl |= next_state;
- if (flags & PSC_FORCE)
- mdctl |= MDCTL_FORCE;
- __raw_writel(mdctl, psc_base + MDCTL + 4 * id);
-
- pdstat = __raw_readl(psc_base + PDSTAT + 4 * domain);
- if ((pdstat & PDSTAT_STATE_MASK) == 0) {
- pdctl = __raw_readl(psc_base + PDCTL + 4 * domain);
- pdctl |= PDCTL_NEXT;
- __raw_writel(pdctl, psc_base + PDCTL + 4 * domain);
-
- ptcmd = 1 << domain;
- __raw_writel(ptcmd, psc_base + PTCMD);
-
- do {
- epcpr = __raw_readl(psc_base + EPCPR);
- } while ((((epcpr >> domain) & 1) == 0));
-
- pdctl = __raw_readl(psc_base + PDCTL + 4 * domain);
- pdctl |= PDCTL_EPCGOOD;
- __raw_writel(pdctl, psc_base + PDCTL + 4 * domain);
- } else {
- ptcmd = 1 << domain;
- __raw_writel(ptcmd, psc_base + PTCMD);
- }
-
- do {
- ptstat = __raw_readl(psc_base + PTSTAT);
- } while (!(((ptstat >> domain) & 1) == 0));
-
- do {
- mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
- } while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
-
- iounmap(psc_base);
-}
diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S
index a3bd60d..20e41e3 100644
--- a/arch/arm/mach-davinci/sleep.S
+++ b/arch/arm/mach-davinci/sleep.S
@@ -23,12 +23,7 @@
#include <asm/assembler.h>
#include <mach/psc.h>
#include <mach/ddr2.h>
-
-#ifndef CONFIG_COMMON_CLK
-#include "clock.h"
-#else
#include <mach/pll.h>
-#endif
/* Arbitrary, hardware currently does not update PHYRDY correctly */
#define PHYRDY_CYCLES 0x1000
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 01467d8..8686879 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -27,10 +27,6 @@
#include <mach/hardware.h>
#include <mach/time.h>
-#ifndef CONFIG_COMMON_CLK
-#include "clock.h"
-#endif
-
static struct clock_event_device clockevent_davinci;
static unsigned int davinci_clock_tick_rate;
@@ -349,11 +345,10 @@ static void __init davinci_timer_init(void)
"%s: can't register clocksource!\n";
int i;
-#ifdef CONFIG_COMMON_CLK
/* invoke clk init function specific to a SoC */
if (davinci_soc_info.clk_init)
davinci_soc_info.clk_init();
-#endif
+
clockevent_id = soc_info->timer_info->clockevent_id;
clocksource_id = soc_info->timer_info->clocksource_id;
--
1.7.9.5
This patch adds dm644x clock initialization code that consists of
clocks data for various clocks and clock register callouts to
various clock drivers. It uses following clk drivers for this
1. clk-fixed-rate - for ref clock
2. clk-mux - for mux at the input and output of main pll
3. davinci specific clk-pll for main pll clock
4. davinci specific clk-div for pll divider clock
5. clk-fixed-factor for fixed factor clock such as auxclk
6. davinci specific clk-psc for psc clocks
This patch also moves all of the PLL and PSC register definitions
from clock.h and psc.h under davinci to the clk/davinci folder so
that various soc specific clock initialization code can share these
definitions.
Signed-off-by: Murali Karicheri <[email protected]>
---
drivers/clk/davinci/dm644x-clock.c | 304 ++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/pll.h | 83 ++++++++++
drivers/clk/davinci/psc.h | 215 +++++++++++++++++++++++++
3 files changed, 602 insertions(+)
create mode 100644 drivers/clk/davinci/dm644x-clock.c
create mode 100644 drivers/clk/davinci/pll.h
create mode 100644 drivers/clk/davinci/psc.h
diff --git a/drivers/clk/davinci/dm644x-clock.c b/drivers/clk/davinci/dm644x-clock.c
new file mode 100644
index 0000000..8f74f72
--- /dev/null
+++ b/drivers/clk/davinci/dm644x-clock.c
@@ -0,0 +1,304 @@
+/*
+ * DM644x clock initialization
+ *
+ * Copyright (C) 2012 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+
+#include "clk-pll.h"
+#include "clk-psc.h"
+#include "clk-div.h"
+#include "clock.h"
+#include "pll.h"
+#include "psc.h"
+
+#define DM644X_CLKIN_FREQ 27000000
+#define DM644X_OSCIN_FREQ 27000000
+
+/* all clocks available in DM644x SoCs */
+enum dm644x_clk {
+ clkin, oscin, ref_clk_mux, pll1, pll1_plldiv_clk_mux, auxclk,
+ clk_pll1_sysclk1, clk_pll1_sysclk2, clk_pll1_sysclk3, clk_pll1_sysclk4,
+ clk_pll1_sysclk5, clk_pll1_sysclkbp, pll2, pll2_plldiv_clk_mux,
+ clk_pll2_sysclk1, clk_pll2_sysclk2, clk_pll2_sysclkbp, dsp, arm, vicp,
+ vpss_master, vpss_slave, uart0, uart1, uart2, emac, i2c, ide, asp,
+ mmcsd, spi, gpio, usb, vlynq, aemif, pwm0, pwm1, pwm2, timer0, timer1,
+ timer2, clk_max
+};
+
+static struct clk *clks[clk_max];
+
+static u32 dm644x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
+
+static const char *ref_clk_mux_parents[] = {"clkin", "oscin"};
+
+static struct clk_mux_data ref_clk_mux_data = {
+ .shift = PLLCTL_CLKMODE_SHIFT,
+ .width = PLLCTL_CLKMODE_WIDTH,
+ .phys_reg = DAVINCI_PLL1_BASE + PLLCTL,
+};
+
+static const char *pll1_plldiv_clk_mux_parents[] = {
+ "ref_clk_mux", "pll1"};
+
+static struct clk_pll_data pll1_data = {
+ .pllm_mask = PLLM_PLLM_MASK,
+ .prediv_mask = PLLDIV_RATIO_MASK,
+ .postdiv_mask = PLLDIV_RATIO_MASK,
+ .num = 1,
+};
+
+static struct clk_mux_data pll1_plldiv_clk_mux_data = {
+ .shift = PLLCTL_PLLEN_SHIFT,
+ .width = PLLCTL_PLLEN_WIDTH,
+ .phys_reg = DAVINCI_PLL1_BASE + PLLCTL,
+};
+
+#define define_pll1_div_clk(__name, __parent_name, __div) \
+ static struct clk_plldiv_data pll1_div_data##__div = { \
+ .phys_div_reg = DAVINCI_PLL1_BASE + PLLDIV##__div, \
+ .width = 5, \
+ .en_id = 15, \
+ }; \
+ \
+ static struct davinci_clk __name = { \
+ .name = #__name, \
+ .parent = #__parent_name, \
+ .data = &pll1_div_data##__div, \
+ };
+
+define_pll1_div_clk(pll1_sysclk1, pll1_plldiv_clk_mux, 1);
+define_pll1_div_clk(pll1_sysclk2, pll1_plldiv_clk_mux, 2);
+define_pll1_div_clk(pll1_sysclk3, pll1_plldiv_clk_mux, 3);
+define_pll1_div_clk(pll1_sysclk4, pll1_plldiv_clk_mux, 4);
+define_pll1_div_clk(pll1_sysclk5, pll1_plldiv_clk_mux, 5);
+
+static struct clk_plldiv_data pll1_sysclkbp_data = {
+ .phys_div_reg = DAVINCI_PLL1_BASE + BPDIV,
+ .width = 5,
+ .en_id = 15,
+};
+
+static struct davinci_clk pll1_sysclkbp = {
+ .name = "pll1_sysclkbp",
+ .parent = "ref_clk_mux",
+ .data = &pll1_sysclkbp_data,
+};
+
+static struct davinci_clk *pll1_plldiv_clocks[] = {
+ &pll1_sysclk1, &pll1_sysclk2, &pll1_sysclk3, &pll1_sysclk4,
+ &pll1_sysclk5, &pll1_sysclkbp,
+};
+
+static struct clk_pll_data pll2_data = {
+ .pllm_mask = PLLM_PLLM_MASK,
+ .prediv_mask = PLLDIV_RATIO_MASK,
+ .postdiv_mask = PLLDIV_RATIO_MASK,
+ .num = 2,
+};
+
+#define define_pll2_div_clk(__name, __parent_name, __div) \
+ static struct clk_plldiv_data pll2_div_data##__div = { \
+ .phys_div_reg = DAVINCI_PLL2_BASE + PLLDIV##__div, \
+ .width = 5, \
+ .en_id = 15, \
+ }; \
+ \
+ static struct davinci_clk __name = { \
+ .name = #__name, \
+ .parent = #__parent_name, \
+ .data = &pll2_div_data##__div, \
+ };
+
+static const char *pll2_plldiv_clk_mux_parents[] = {
+ "ref_clk_mux", "pll2"};
+
+static struct clk_mux_data pll2_plldiv_clk_mux_data = {
+ .shift = PLLCTL_PLLEN_SHIFT,
+ .width = PLLCTL_PLLEN_WIDTH,
+ .phys_reg = DAVINCI_PLL2_BASE + PLLCTL,
+};
+
+define_pll2_div_clk(pll2_sysclk1, pll2_plldiv_clk_mux, 1);
+define_pll2_div_clk(pll2_sysclk2, pll2_plldiv_clk_mux, 2);
+
+static struct clk_plldiv_data pll2_sysclkbp_data = {
+ .phys_div_reg = DAVINCI_PLL2_BASE + BPDIV,
+ .width = 5,
+ .en_id = 15,
+};
+
+static struct davinci_clk pll2_sysclkbp = {
+ .name = "pll2_sysclkbp",
+ .parent = "ref_clk_mux",
+ .data = &pll2_sysclkbp_data,
+};
+
+static struct davinci_clk *pll2_plldiv_clocks[] = {
+ &pll2_sysclk1, &pll2_sysclk2, &pll2_sysclkbp,
+};
+
+#define __lpsc_clk(__name, __parent_name, mod, flgs, _flgs, dom, _dev_id) \
+ static struct clk_psc_data clk_psc_data_##__name = { \
+ .domain_id = DAVINCI_GPSC_##dom, \
+ .lpsc_id = DAVINCI_LPSC_##mod, \
+ .flags = flgs | CLK_PSC_HAS_EXT_POWER_CNTL, \
+ }; \
+ \
+ static struct davinci_clk clk_##__name = { \
+ .name = #__name, \
+ .parent = #__parent_name, \
+ .flags = _flgs, \
+ .dev_id = _dev_id, \
+ .data = &clk_psc_data_##__name \
+ };
+
+#define lpsc_clk_enabled(name, parent, mod, dev_id) \
+ __lpsc_clk(name, parent, mod, 0, ALWAYS_ENABLED, ARMDOMAIN, dev_id)
+
+#define lpsc_clk(name, flgs, parent, mod, dom, dev_id) \
+ __lpsc_clk(name, parent, mod, flgs, 0, dom, dev_id)
+
+lpsc_clk_enabled(arm, pll1_sysclk2, ARM, NULL);
+lpsc_clk(dsp, CLK_IGNORE_UNUSED, pll1_sysclk1, GEM, DSPDOMAIN, NULL);
+lpsc_clk(vicp, CLK_IGNORE_UNUSED, pll1_sysclk2, IMCOP, DSPDOMAIN, NULL);
+lpsc_clk(vpss_master, 0, pll1_sysclk3, VPSSMSTR, ARMDOMAIN, "dm644x_ccdc");
+lpsc_clk(vpss_slave, 0, pll1_sysclk3, VPSSSLV, ARMDOMAIN, "dm644x_ccdc");
+lpsc_clk(uart0, 0, auxclk, UART0, ARMDOMAIN, NULL);
+lpsc_clk(uart1, 0, auxclk, UART1, ARMDOMAIN, NULL);
+lpsc_clk(uart2, 0, auxclk, UART2, ARMDOMAIN, NULL);
+lpsc_clk(emac, 0, pll1_sysclk5, EMAC_WRAPPER, ARMDOMAIN, "davinci_emac.1");
+lpsc_clk(i2c, 0, auxclk, I2C, ARMDOMAIN, "i2c_davinci.1");
+lpsc_clk(ide, 0, pll1_sysclk5, ATA, ARMDOMAIN, "palm_bk3710");
+lpsc_clk(asp0, 0, pll1_sysclk5, McBSP, ARMDOMAIN, "davinci-mcbsp");
+lpsc_clk(mmcsd, 0, pll1_sysclk5, MMC_SD, ARMDOMAIN, "davinci_mmc.0");
+lpsc_clk(spi, 0, pll1_sysclk5, SPI, ARMDOMAIN, NULL);
+lpsc_clk(gpio, 0, pll1_sysclk5, GPIO, ARMDOMAIN, NULL);
+lpsc_clk(usb, 0, pll1_sysclk5, USB, ARMDOMAIN, NULL);
+lpsc_clk(vlynq, 0, pll1_sysclk5, VLYNQ, ARMDOMAIN, NULL);
+lpsc_clk(aemif, 0, pll1_sysclk5, AEMIF, ARMDOMAIN, NULL);
+lpsc_clk(pwm0, 0, auxclk, PWM0, ARMDOMAIN, NULL);
+lpsc_clk(pwm1, 0, auxclk, PWM1, ARMDOMAIN, NULL);
+lpsc_clk(pwm2, 0, auxclk, PWM2, ARMDOMAIN, NULL);
+lpsc_clk(timer0, 0, auxclk, TIMER0, ARMDOMAIN, NULL);
+lpsc_clk(timer1, 0, auxclk, TIMER1, ARMDOMAIN, NULL);
+lpsc_clk(timer2, CLK_IGNORE_UNUSED, auxclk, TIMER2, ARMDOMAIN, "watchdog");
+
+static struct davinci_clk *psc_clocks[] = {
+ &clk_dsp, &clk_arm, &clk_vicp, &clk_vpss_master, &clk_vpss_slave,
+ &clk_uart0, &clk_uart1, &clk_uart2, &clk_emac, &clk_i2c, &clk_ide,
+ &clk_asp0, &clk_mmcsd, &clk_spi, &clk_gpio, &clk_usb, &clk_vlynq,
+ &clk_aemif, &clk_pwm0, &clk_pwm1, &clk_pwm2, &clk_timer0, &clk_timer1,
+ &clk_timer2
+};
+
+void __init dm644x_clk_init(void)
+{
+ void __iomem *psc_base;
+ int i, ret;
+
+ psc_base = ioremap(dm644x_psc_bases[0], SZ_4K);
+ if (WARN_ON(!psc_base))
+ return;
+
+ /* Input clocks to the SoC */
+ clks[clkin] = davinci_fixed_ref_clk("clkin", DM644X_CLKIN_FREQ);
+ clks[oscin] = davinci_fixed_ref_clk("oscin", DM644X_OSCIN_FREQ);
+
+ /* The mux at the input selected by CLKMODE bit */
+ clks[ref_clk_mux] = davinci_mux_clk("ref_clk_mux",
+ ARRAY_SIZE(ref_clk_mux_parents),
+ ref_clk_mux_parents, &ref_clk_mux_data);
+
+ /* Main PLL1 clock */
+ clks[pll1] = davinci_pll_clk("pll1", "ref_clk_mux",
+ DAVINCI_PLL1_BASE + PLLM, 0, 0, &pll1_data);
+
+ /* The mux at the output of PLL1 and selected by PLLEN bit */
+ clks[pll1_plldiv_clk_mux] = davinci_mux_clk("pll1_plldiv_clk_mux",
+ ARRAY_SIZE(pll1_plldiv_clk_mux_parents),
+ pll1_plldiv_clk_mux_parents,
+ &pll1_plldiv_clk_mux_data);
+
+ /* Auxiliary clock that comes from the ref_clk_mux output */
+ clks[auxclk] = davinci_fixed_factor_clk("auxclk",
+ "ref_clk_mux", 0, 1, 1);
+
+ /*
+ * PLL1 divider clocks that has an EN bit to enable or bypass the
+ * PLL divider
+ */
+ for (i = 0; i < ARRAY_SIZE(pll1_plldiv_clocks); i++)
+ clks[clk_pll1_sysclk1 + i] =
+ davinci_plldiv_clk(pll1_plldiv_clocks[i]->name,
+ pll1_plldiv_clocks[i]->parent,
+ pll1_plldiv_clocks[i]->data);
+
+ /* Main PLL2 clock */
+ clks[pll2] = davinci_pll_clk("pll2", "ref_clk_mux",
+ DAVINCI_PLL2_BASE + PLLM, 0, 0, &pll2_data);
+
+ /* The mux at the output of PLL2 and selected by PLLEN bit */
+ clks[pll2_plldiv_clk_mux] = davinci_mux_clk("pll2_plldiv_clk_mux",
+ ARRAY_SIZE(pll2_plldiv_clk_mux_parents),
+ pll2_plldiv_clk_mux_parents,
+ &pll2_plldiv_clk_mux_data);
+
+ /*
+ * PLL2 divider clocks that has an EN bit to enable or bypass the
+ * PLL divider
+ */
+ for (i = 0; i < ARRAY_SIZE(pll2_plldiv_clocks); i++)
+ clks[clk_pll2_sysclk1 + i] =
+ davinci_plldiv_clk(pll2_plldiv_clocks[i]->name,
+ pll2_plldiv_clocks[i]->parent,
+ pll2_plldiv_clocks[i]->data);
+
+ /* PSC clocks */
+ for (i = 0; i < ARRAY_SIZE(psc_clocks); i++) {
+ struct clk_psc_data *data = psc_clocks[i]->data;
+
+ data->reg_base = psc_base;
+ clks[dsp + i] = davinci_psc_clk(psc_clocks[i]->name,
+ psc_clocks[i]->parent, data);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(clks); i++) {
+ if (IS_ERR(clks[i])) {
+ pr_err("DM644x clk %d: register failed with %ld\n",
+ i, PTR_ERR(clks[i]));
+ return;
+ }
+ }
+
+ /* register clkdev for leaf clocks */
+ for (i = 0; i < ARRAY_SIZE(psc_clocks); i++) {
+ if (psc_clocks[i]->dev_id)
+ ret = clk_register_clkdev(clks[dsp + i], NULL,
+ psc_clocks[i]->dev_id);
+ else
+ ret = clk_register_clkdev(clks[dsp + i],
+ psc_clocks[i]->name, NULL);
+ if (ret < 0) {
+ pr_err("clk_register_clkdev failed for %s\n",
+ psc_clocks[i]->name);
+ return;
+ }
+
+ /* Enable always on clocks */
+ if (psc_clocks[i]->flags & ALWAYS_ENABLED)
+ clk_prepare_enable(clks[dsp + i]);
+ }
+ pr_notice("DM644x clock initialization complete\n");
+}
+EXPORT_SYMBOL_GPL(dm644x_clk_init);
diff --git a/drivers/clk/davinci/pll.h b/drivers/clk/davinci/pll.h
new file mode 100644
index 0000000..5000e6f
--- /dev/null
+++ b/drivers/clk/davinci/pll.h
@@ -0,0 +1,83 @@
+/*
+ * TI DaVinci PLL definitions
+ *
+ * Copyright (C) 2006-2012 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef __DAVINCI_PLL_H
+#define __DAVINCI_PLL_H
+
+#define DAVINCI_PLL1_BASE 0x01c40800
+#define DAVINCI_PLL2_BASE 0x01c40c00
+#define MAX_PLL 2
+
+/* PLL/Reset register offsets */
+#define PLLCTL 0x100
+#define PLLCTL_PLLEN BIT(0)
+#define PLLCTL_PLLPWRDN BIT(1)
+#define PLLCTL_PLLRST BIT(3)
+#define PLLCTL_PLLDIS BIT(4)
+#define PLLCTL_PLLENSRC BIT(5)
+#define PLLCTL_CLKMODE BIT(8)
+
+#define PLLCTL_CLKMODE_SHIFT 8
+#define PLLCTL_CLKMODE_WIDTH 1
+#define PLLCTL_PLLEN_SHIFT 0
+#define PLLCTL_PLLEN_WIDTH 1
+
+#define PLLDIV1 0x118
+#define PLLDIV2 0x11c
+#define PLLDIV3 0x120
+#define OSCDIV1 0x124
+#define BPDIV 0x12c
+#define PLLCMD 0x138
+#define PLLSTAT 0x13c
+#define PLLALNCTL 0x140
+#define PLLDCHANGE 0x144
+#define PLLCKEN 0x148
+#define PLLCKSTAT 0x14c
+#define PLLSYSTAT 0x150
+#define PLLDIV4 0x160
+#define PLLDIV5 0x164
+#define PLLDIV6 0x168
+#define PLLDIV7 0x16c
+#define PLLDIV8 0x170
+#define PLLDIV9 0x174
+#define PLLDIV10 0x178
+#define PLLDIV11 0x17c
+#define PLLDIV12 0x180
+#define PLLDIV13 0x184
+#define PLLDIV14 0x188
+#define PLLDIV15 0x18c
+#define PLLDIV16 0x190
+#define PLLDIV_RATIO_MASK 0x1f
+#define PLLDIV_EN BIT(15)
+
+/*
+ * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN
+ * cycles to ensure that the PLLC has switched to bypass mode. Delay of 1us
+ * ensures we are good for all > 4MHz OSCIN/CLKIN inputs. Typically the input
+ * is ~25MHz. Units are micro seconds.
+ */
+#define PLL_BYPASS_TIME 1
+/* From OMAP-L138 datasheet table 6-4. Units are micro seconds */
+#define PLL_RESET_TIME 1
+/*
+ * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4
+ * Units are micro seconds.
+ */
+#define PLL_LOCK_TIME 20
+#define PLLSTAT_GOSTAT BIT(0)
+#define PLLCMD_GOSET BIT(0)
+
+#define PLLM 0x110
+#define PREDIV 0x114
+#define POSTDIV 0x128
+#define PLLM_PLLM_MASK 0xff
+
+#endif /* __ASM_ARCH_PLL_H */
diff --git a/drivers/clk/davinci/psc.h b/drivers/clk/davinci/psc.h
new file mode 100644
index 0000000..1f704d6
--- /dev/null
+++ b/drivers/clk/davinci/psc.h
@@ -0,0 +1,215 @@
+/*
+ * DaVinci Power & Sleep Controller (PSC) defines
+ *
+ * Copyright (C) 2006-2012 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+#ifndef __DAVINCI_PSC_H
+#define __DAVINCI_PSC_H
+
+#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000
+
+/* Power and Sleep Controller (PSC) Domains */
+#define DAVINCI_GPSC_ARMDOMAIN 0
+#define DAVINCI_GPSC_DSPDOMAIN 1
+
+#define DAVINCI_LPSC_VPSSMSTR 0
+#define DAVINCI_LPSC_VPSSSLV 1
+#define DAVINCI_LPSC_TPCC 2
+#define DAVINCI_LPSC_TPTC0 3
+#define DAVINCI_LPSC_TPTC1 4
+#define DAVINCI_LPSC_EMAC 5
+#define DAVINCI_LPSC_EMAC_WRAPPER 6
+#define DAVINCI_LPSC_USB 9
+#define DAVINCI_LPSC_ATA 10
+#define DAVINCI_LPSC_VLYNQ 11
+#define DAVINCI_LPSC_UHPI 12
+#define DAVINCI_LPSC_DDR_EMIF 13
+#define DAVINCI_LPSC_AEMIF 14
+#define DAVINCI_LPSC_MMC_SD 15
+#define DAVINCI_LPSC_McBSP 17
+#define DAVINCI_LPSC_I2C 18
+#define DAVINCI_LPSC_UART0 19
+#define DAVINCI_LPSC_UART1 20
+#define DAVINCI_LPSC_UART2 21
+#define DAVINCI_LPSC_SPI 22
+#define DAVINCI_LPSC_PWM0 23
+#define DAVINCI_LPSC_PWM1 24
+#define DAVINCI_LPSC_PWM2 25
+#define DAVINCI_LPSC_GPIO 26
+#define DAVINCI_LPSC_TIMER0 27
+#define DAVINCI_LPSC_TIMER1 28
+#define DAVINCI_LPSC_TIMER2 29
+#define DAVINCI_LPSC_SYSTEM_SUBSYS 30
+#define DAVINCI_LPSC_ARM 31
+#define DAVINCI_LPSC_SCR2 32
+#define DAVINCI_LPSC_SCR3 33
+#define DAVINCI_LPSC_SCR4 34
+#define DAVINCI_LPSC_CROSSBAR 35
+#define DAVINCI_LPSC_CFG27 36
+#define DAVINCI_LPSC_CFG3 37
+#define DAVINCI_LPSC_CFG5 38
+#define DAVINCI_LPSC_GEM 39
+#define DAVINCI_LPSC_IMCOP 40
+
+#define DM355_LPSC_TIMER3 5
+#define DM355_LPSC_SPI1 6
+#define DM355_LPSC_MMC_SD1 7
+#define DM355_LPSC_McBSP1 8
+#define DM355_LPSC_PWM3 10
+#define DM355_LPSC_SPI2 11
+#define DM355_LPSC_RTO 12
+#define DM355_LPSC_VPSS_DAC 41
+
+/* DM365 */
+#define DM365_LPSC_TIMER3 5
+#define DM365_LPSC_SPI1 6
+#define DM365_LPSC_MMC_SD1 7
+#define DM365_LPSC_McBSP1 8
+#define DM365_LPSC_PWM3 10
+#define DM365_LPSC_SPI2 11
+#define DM365_LPSC_RTO 12
+#define DM365_LPSC_TIMER4 17
+#define DM365_LPSC_SPI0 22
+#define DM365_LPSC_SPI3 38
+#define DM365_LPSC_SPI4 39
+#define DM365_LPSC_EMAC 40
+#define DM365_LPSC_VOICE_CODEC 44
+#define DM365_LPSC_DAC_CLK 46
+#define DM365_LPSC_VPSSMSTR 47
+#define DM365_LPSC_MJCP 50
+
+/*
+ * LPSC Assignments
+ */
+#define DM646X_LPSC_ARM 0
+#define DM646X_LPSC_C64X_CPU 1
+#define DM646X_LPSC_HDVICP0 2
+#define DM646X_LPSC_HDVICP1 3
+#define DM646X_LPSC_TPCC 4
+#define DM646X_LPSC_TPTC0 5
+#define DM646X_LPSC_TPTC1 6
+#define DM646X_LPSC_TPTC2 7
+#define DM646X_LPSC_TPTC3 8
+#define DM646X_LPSC_PCI 13
+#define DM646X_LPSC_EMAC 14
+#define DM646X_LPSC_VDCE 15
+#define DM646X_LPSC_VPSSMSTR 16
+#define DM646X_LPSC_VPSSSLV 17
+#define DM646X_LPSC_TSIF0 18
+#define DM646X_LPSC_TSIF1 19
+#define DM646X_LPSC_DDR_EMIF 20
+#define DM646X_LPSC_AEMIF 21
+#define DM646X_LPSC_McASP0 22
+#define DM646X_LPSC_McASP1 23
+#define DM646X_LPSC_CRGEN0 24
+#define DM646X_LPSC_CRGEN1 25
+#define DM646X_LPSC_UART0 26
+#define DM646X_LPSC_UART1 27
+#define DM646X_LPSC_UART2 28
+#define DM646X_LPSC_PWM0 29
+#define DM646X_LPSC_PWM1 30
+#define DM646X_LPSC_I2C 31
+#define DM646X_LPSC_SPI 32
+#define DM646X_LPSC_GPIO 33
+#define DM646X_LPSC_TIMER0 34
+#define DM646X_LPSC_TIMER1 35
+#define DM646X_LPSC_ARM_INTC 45
+
+/* PSC0 defines */
+#define DA8XX_LPSC0_TPCC 0
+#define DA8XX_LPSC0_TPTC0 1
+#define DA8XX_LPSC0_TPTC1 2
+#define DA8XX_LPSC0_EMIF25 3
+#define DA8XX_LPSC0_SPI0 4
+#define DA8XX_LPSC0_MMC_SD 5
+#define DA8XX_LPSC0_AINTC 6
+#define DA8XX_LPSC0_ARM_RAM_ROM 7
+#define DA8XX_LPSC0_SECU_MGR 8
+#define DA8XX_LPSC0_UART0 9
+#define DA8XX_LPSC0_SCR0_SS 10
+#define DA8XX_LPSC0_SCR1_SS 11
+#define DA8XX_LPSC0_SCR2_SS 12
+#define DA8XX_LPSC0_PRUSS 13
+#define DA8XX_LPSC0_ARM 14
+#define DA8XX_LPSC0_GEM 15
+
+/* PSC1 defines */
+#define DA850_LPSC1_TPCC1 0
+#define DA8XX_LPSC1_USB20 1
+#define DA8XX_LPSC1_USB11 2
+#define DA8XX_LPSC1_GPIO 3
+#define DA8XX_LPSC1_UHPI 4
+#define DA8XX_LPSC1_CPGMAC 5
+#define DA8XX_LPSC1_EMIF3C 6
+#define DA8XX_LPSC1_McASP0 7
+#define DA830_LPSC1_McASP1 8
+#define DA850_LPSC1_SATA 8
+#define DA830_LPSC1_McASP2 9
+#define DA8XX_LPSC1_SPI1 10
+#define DA8XX_LPSC1_I2C 11
+#define DA8XX_LPSC1_UART1 12
+#define DA8XX_LPSC1_UART2 13
+#define DA8XX_LPSC1_LCDC 16
+#define DA8XX_LPSC1_PWM 17
+#define DA850_LPSC1_MMC_SD1 18
+#define DA8XX_LPSC1_ECAP 20
+#define DA830_LPSC1_EQEP 21
+#define DA850_LPSC1_TPTC2 21
+#define DA8XX_LPSC1_SCR_P0_SS 24
+#define DA8XX_LPSC1_SCR_P1_SS 25
+#define DA8XX_LPSC1_CR_P3_SS 26
+#define DA8XX_LPSC1_L3_CBA_RAM 31
+
+/* TNETV107X LPSC Assignments */
+#define TNETV107X_LPSC_ARM 0
+#define TNETV107X_LPSC_GEM 1
+#define TNETV107X_LPSC_DDR2_PHY 2
+#define TNETV107X_LPSC_TPCC 3
+#define TNETV107X_LPSC_TPTC0 4
+#define TNETV107X_LPSC_TPTC1 5
+#define TNETV107X_LPSC_RAM 6
+#define TNETV107X_LPSC_MBX_LITE 7
+#define TNETV107X_LPSC_LCD 8
+#define TNETV107X_LPSC_ETHSS 9
+#define TNETV107X_LPSC_AEMIF 10
+#define TNETV107X_LPSC_CHIP_CFG 11
+#define TNETV107X_LPSC_TSC 12
+#define TNETV107X_LPSC_ROM 13
+#define TNETV107X_LPSC_UART2 14
+#define TNETV107X_LPSC_PKTSEC 15
+#define TNETV107X_LPSC_SECCTL 16
+#define TNETV107X_LPSC_KEYMGR 17
+#define TNETV107X_LPSC_KEYPAD 18
+#define TNETV107X_LPSC_GPIO 19
+#define TNETV107X_LPSC_MDIO 20
+#define TNETV107X_LPSC_SDIO0 21
+#define TNETV107X_LPSC_UART0 22
+#define TNETV107X_LPSC_UART1 23
+#define TNETV107X_LPSC_TIMER0 24
+#define TNETV107X_LPSC_TIMER1 25
+#define TNETV107X_LPSC_WDT_ARM 26
+#define TNETV107X_LPSC_WDT_DSP 27
+#define TNETV107X_LPSC_SSP 28
+#define TNETV107X_LPSC_TDM0 29
+#define TNETV107X_LPSC_VLYNQ 30
+#define TNETV107X_LPSC_MCDMA 31
+#define TNETV107X_LPSC_USB0 32
+#define TNETV107X_LPSC_TDM1 33
+#define TNETV107X_LPSC_DEBUGSS 34
+#define TNETV107X_LPSC_ETHSS_RGMII 35
+#define TNETV107X_LPSC_SYSTEM 36
+#define TNETV107X_LPSC_IMCOP 37
+#define TNETV107X_LPSC_SPARE 38
+#define TNETV107X_LPSC_SDIO1 39
+#define TNETV107X_LPSC_USB1 40
+#define TNETV107X_LPSC_USBSS 41
+#define TNETV107X_LPSC_DDR2_EMIF1_VRST 42
+#define TNETV107X_LPSC_DDR2_EMIF2_VCTL_RST 43
+#define TNETV107X_LPSC_MAX 44
+#endif /* __DAVINCI_PSC_H */
--
1.7.9.5
Currently migrate only DM644x as this is being reviewed. Once all
platforms are migrated, the Makefile will be cleaned up to remove
obsoleted files clock.o and psc.o
Signed-off-by: Murali Karicheri <[email protected]>
---
arch/arm/Kconfig | 1 +
arch/arm/mach-davinci/Kconfig | 2 ++
arch/arm/mach-davinci/Makefile | 11 ++++++++++-
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c5f9ae5..4611987 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -967,6 +967,7 @@ config ARCH_DAVINCI
select ARCH_REQUIRE_GPIOLIB
select ZONE_DMA
select HAVE_IDE
+ select COMMON_CLK
select CLKDEV_LOOKUP
select GENERIC_ALLOCATOR
select GENERIC_IRQ_CHIP
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index ab99c3c..ab414b4 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -19,6 +19,8 @@ config ARCH_DAVINCI_DM644x
bool "DaVinci 644x based system"
select AINTC
select ARCH_DAVINCI_DMx
+ select DAVINCI_CLKS
+ select CLK_DAVINCI_PLL
config ARCH_DAVINCI_DM355
bool "DaVinci 355 based system"
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index 2227eff..5a5b3dc 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -4,18 +4,25 @@
#
# Common objects
+ifndef CONFIG_COMMON_CLK
obj-y := time.o clock.o serial.o psc.o \
dma.o usb.o common.o sram.o aemif.o
+else
+obj-y := time.o serial.o \
+ dma.o usb.o common.o sram.o aemif.o
+endif
obj-$(CONFIG_DAVINCI_MUX) += mux.o
# Chip specific
obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o devices.o
+ifndef CONFIG_COMMON_CLK
obj-$(CONFIG_ARCH_DAVINCI_DM355) += dm355.o devices.o
-obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o
obj-$(CONFIG_ARCH_DAVINCI_DM365) += dm365.o devices.o
+obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += da830.o devices-da8xx.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += da850.o devices-da8xx.o
+endif
obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += tnetv107x.o devices-tnetv107x.o
obj-$(CONFIG_AINTC) += irq.o
@@ -23,6 +30,7 @@ obj-$(CONFIG_CP_INTC) += cp_intc.o
# Board specific
obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o
+ifndef CONFIG_COMMON_CLK
obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o
obj-$(CONFIG_MACH_NEUROS_OSD2) += board-neuros-osd2.o
obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-dm355-evm.o
@@ -31,6 +39,7 @@ obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o cdce949.o
obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o
obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o
obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o
+endif
obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o
obj-$(CONFIG_MACH_MITYOMAPL138) += board-mityomapl138.o
obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o
--
1.7.9.5
pll dividers are present in the pll controller of DaVinci and Other
SoCs that re-uses the same hardware IP. This has a enable bit for
bypass the divider or enable the driver. This is a sub class of the
clk-divider clock checks the enable bit to calculare the rate and
invoke the recalculate() function of the clk-divider if enabled.
Signed-off-by: Murali Karicheri <[email protected]>
---
drivers/clk/davinci/clk-div.c | 124 +++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/clk-div.h | 42 ++++++++++++++
2 files changed, 166 insertions(+)
create mode 100644 drivers/clk/davinci/clk-div.c
create mode 100644 drivers/clk/davinci/clk-div.h
diff --git a/drivers/clk/davinci/clk-div.c b/drivers/clk/davinci/clk-div.c
new file mode 100644
index 0000000..8147d99
--- /dev/null
+++ b/drivers/clk/davinci/clk-div.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Texas instuments
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include "clk-div.h"
+
+/**
+ * struct clk_div - DaVinci integer pll divider clock
+ *
+ * @divider: the parent class
+ * @ops: pointer to clk_ops of parent class
+ * @reg: register address
+ * @en_id: enable bit id
+ *
+ * The DaVinci pll divider clock is a subclass of basic clk_divider with
+ * an additional enable bit
+ */
+struct clk_div {
+ struct clk_divider divider;
+ const struct clk_ops *ops;
+ void __iomem *reg;
+ u8 en_id;
+};
+
+static inline struct clk_div *to_clk_div(struct clk_hw *hw)
+{
+ struct clk_divider *divider = container_of(hw, struct clk_divider, hw);
+
+ return container_of(divider, struct clk_div, divider);
+}
+
+static unsigned long clk_div_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_div *div = to_clk_div(hw);
+ u32 val;
+
+ val = readl(div->reg);
+ if (val & BIT(div->en_id))
+ return div->ops->recalc_rate(&div->divider.hw, parent_rate);
+
+ /* pll divider bypassed, return parent rate */
+ return parent_rate;
+}
+
+static long clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk_div *div = to_clk_div(hw);
+
+ return div->ops->round_rate(&div->divider.hw, rate, prate);
+}
+
+static int clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_div *div = to_clk_div(hw);
+
+ return div->ops->set_rate(&div->divider.hw, rate, parent_rate);
+}
+
+static struct clk_ops clk_div_ops = {
+ .recalc_rate = clk_div_recalc_rate,
+ .round_rate = clk_div_round_rate,
+ .set_rate = clk_div_set_rate,
+};
+
+/**
+ * clk_register_davinci_plldiv - register function for DaVinci PLL divider clk
+ *
+ * @dev: device ptr
+ * @name: name of the clock
+ * @parent_name: name of parent clock
+ * @plldiv_data: ptr to pll divider data
+ * @lock: ptr to spinlock passed to divider clock
+ */
+struct clk *clk_register_davinci_plldiv(struct device *dev,
+ const char *name, const char *parent_name,
+ struct clk_plldiv_data *plldiv_data,
+ spinlock_t *lock)
+{
+ struct clk_div *div;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ div = kzalloc(sizeof(*div), GFP_KERNEL);
+ if (!div)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &clk_div_ops;
+ init.flags = plldiv_data->flags;
+ init.parent_names = (parent_name ? &parent_name : NULL);
+ init.num_parents = (parent_name ? 1 : 0);
+
+ div->reg = plldiv_data->reg;
+ div->en_id = plldiv_data->en_id;
+
+ div->divider.reg = plldiv_data->reg;
+ div->divider.shift = plldiv_data->shift;
+ div->divider.width = plldiv_data->width;
+ div->divider.flags = plldiv_data->divider_flags;
+ div->divider.lock = lock;
+ div->divider.hw.init = &init;
+ div->ops = &clk_divider_ops;
+
+ clk = clk_register(NULL, &div->divider.hw);
+ if (IS_ERR(clk))
+ kfree(div);
+
+ return clk;
+}
diff --git a/drivers/clk/davinci/clk-div.h b/drivers/clk/davinci/clk-div.h
new file mode 100644
index 0000000..0e3708c
--- /dev/null
+++ b/drivers/clk/davinci/clk-div.h
@@ -0,0 +1,42 @@
+/*
+ * Header file for DaVinci pll divider clk driver
+ *
+ * Copyright (C) 2006-2012 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __CLK_DAVINCI_PLLDIV_H
+#define __CLK_DAVINCI_PLLDIV_H
+
+
+/**
+ * struct clk_plldiv_data - configuration for DaVinci PLL divider driver
+ *
+ * @flags - base clk driver flags
+ * @divider_flags - clk-divider flags
+ * @phys_div_reg - clk-divider register physical address
+ * @reg - clk-divider register io mapped address
+ * @shift - shift applied to the divider bits in the register
+ * @width - width of the divider bits in the register
+ * @en_id - bypass or enable bit mask id. mask = BIT(en_id)
+ */
+/* configuration data for PLL divider clock */
+struct clk_plldiv_data {
+ u32 flags;
+ u8 divider_flags;
+ u32 phys_div_reg;
+ void __iomem *reg;
+ u8 shift;
+ u8 width;
+ u8 en_id;
+};
+
+struct clk *clk_register_davinci_plldiv(struct device *dev,
+ const char *name, const char *parent_name,
+ struct clk_plldiv_data *plldiv_data,
+ spinlock_t *lock);
+#endif /* CLK_DAVINCI_PLLDIV_H */
--
1.7.9.5
As part of the migration, the clock data is now moved to the driver/clk/
davinci/dm644x-clock.c. Currently the clock data is placed under ifndef
CONFIG_COMMON_CLK directive and will be removed in a subsequent patch.
Signed-off-by: Murali Karicheri <[email protected]>
---
arch/arm/mach-davinci/davinci.h | 3 +++
arch/arm/mach-davinci/dm644x.c | 28 ++++++++++++++++++++++------
2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index 8661b20..ae9b1af 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -100,4 +100,7 @@ int __init dm646x_init_edma(struct edma_rsv_info *rsv);
void dm646x_video_init(void);
void dm646x_setup_vpif(struct vpif_display_config *,
struct vpif_capture_config *);
+
+extern void __init dm644x_clk_init(void);
+
#endif /*__DAVINCI_H */
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 0755d46..bf64b75 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -9,7 +9,9 @@
* or implied.
*/
#include <linux/init.h>
+#ifndef CONFIG_COMMON_CLK
#include <linux/clk.h>
+#endif
#include <linux/serial_8250.h>
#include <linux/platform_device.h>
@@ -18,7 +20,9 @@
#include <mach/cputype.h>
#include <mach/edma.h>
#include <mach/irqs.h>
+#ifndef CONFIG_COMMON_CLK
#include <mach/psc.h>
+#endif
#include <mach/mux.h>
#include <mach/time.h>
#include <mach/serial.h>
@@ -26,14 +30,11 @@
#include <mach/gpio-davinci.h>
#include "davinci.h"
-#include "clock.h"
#include "mux.h"
#include "asp.h"
-
-/*
- * Device specific clocks
- */
-#define DM644X_REF_FREQ 27000000
+#ifndef CONFIG_COMMON_CLK
+#include "clock.h"
+#endif
#define DM644X_EMAC_BASE 0x01c80000
#define DM644X_EMAC_MDIO_BASE (DM644X_EMAC_BASE + 0x4000)
@@ -42,6 +43,12 @@
#define DM644X_EMAC_CNTRL_RAM_OFFSET 0x2000
#define DM644X_EMAC_CNTRL_RAM_SIZE 0x2000
+#ifndef CONFIG_COMMON_CLK
+/*
+ * Device specific clocks
+ */
+#define DM644X_REF_FREQ 27000000
+
static struct pll_data pll1_data = {
.num = 1,
.phys_base = DAVINCI_PLL1_BASE,
@@ -324,6 +331,7 @@ static struct clk_lookup dm644x_clks[] = {
CLK("watchdog", NULL, &timer2_clk),
CLK(NULL, NULL, NULL),
};
+#endif
static struct emac_platform_data dm644x_emac_pdata = {
.ctrl_reg_offset = DM644X_EMAC_CNTRL_OFFSET,
@@ -821,7 +829,9 @@ static struct davinci_id dm644x_ids[] = {
},
};
+#ifndef CONFIG_COMMON_CLK
static u32 dm644x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
+#endif
/*
* T0_BOT: Timer 0, bottom: clockevent source for hrtimers
@@ -879,9 +889,13 @@ static struct davinci_soc_info davinci_soc_info_dm644x = {
.jtag_id_reg = 0x01c40028,
.ids = dm644x_ids,
.ids_num = ARRAY_SIZE(dm644x_ids),
+#ifdef CONFIG_COMMON_CLK
+ .clk_init = dm644x_clk_init,
+#else
.cpu_clks = dm644x_clks,
.psc_bases = dm644x_psc_bases,
.psc_bases_num = ARRAY_SIZE(dm644x_psc_bases),
+#endif
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
.pinmux_pins = dm644x_pins,
.pinmux_pins_num = ARRAY_SIZE(dm644x_pins),
@@ -923,11 +937,13 @@ int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
dm644x_vpfe_dev.dev.platform_data = vpfe_cfg;
platform_device_register(&dm644x_ccdc_dev);
platform_device_register(&dm644x_vpfe_dev);
+#ifndef CONFIG_COMMON_CLK
/* Add ccdc clock aliases */
clk_add_alias("master", dm644x_ccdc_dev.name,
"vpss_master", NULL);
clk_add_alias("slave", dm644x_ccdc_dev.name,
"vpss_slave", NULL);
+#endif
}
if (vpbe_cfg) {
--
1.7.9.5
A clk_init function pointer is added to davinci_soc_info to allow
SoC code to specify a clock init function for the SoC. Also
cpu_clks, psc_bases and psc_bases_num are being obsoleted as part
of the migration. clk_init() is now called from davinci_timer_init()
as the davinci_common_init() is too early to call this function.
Signed-off-by: Murali Karicheri <[email protected]>
---
arch/arm/mach-davinci/common.c | 6 ++++++
arch/arm/mach-davinci/include/mach/common.h | 4 ++++
arch/arm/mach-davinci/time.c | 7 +++++++
3 files changed, 17 insertions(+)
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
index 64b0f65..039494e 100644
--- a/arch/arm/mach-davinci/common.c
+++ b/arch/arm/mach-davinci/common.c
@@ -20,7 +20,9 @@
#include <mach/common.h>
#include <mach/cputype.h>
+#ifndef CONFIG_COMMON_CLK
#include "clock.h"
+#endif
struct davinci_soc_info davinci_soc_info;
EXPORT_SYMBOL(davinci_soc_info);
@@ -105,12 +107,14 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info)
if (ret < 0)
goto err;
+#ifndef CONFIG_COMMON_CLK
if (davinci_soc_info.cpu_clks) {
ret = davinci_clk_init(davinci_soc_info.cpu_clks);
if (ret != 0)
goto err;
}
+#endif
return;
@@ -122,5 +126,7 @@ void __init davinci_init_late(void)
{
davinci_cpufreq_init();
davinci_pm_init();
+#ifndef CONFIG_COMMON_CLK
davinci_clk_disable_unused();
+#endif
}
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index bdc4aa8..040db17 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -54,9 +54,13 @@ struct davinci_soc_info {
u32 jtag_id_reg;
struct davinci_id *ids;
unsigned long ids_num;
+#ifdef CONFIG_COMMON_CLK
+ void (*clk_init)(void);
+#else
struct clk_lookup *cpu_clks;
u32 *psc_bases;
unsigned long psc_bases_num;
+#endif
u32 pinmux_base;
const struct mux_config *pinmux_pins;
unsigned long pinmux_pins_num;
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 9847938..01467d8 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -27,7 +27,9 @@
#include <mach/hardware.h>
#include <mach/time.h>
+#ifndef CONFIG_COMMON_CLK
#include "clock.h"
+#endif
static struct clock_event_device clockevent_davinci;
static unsigned int davinci_clock_tick_rate;
@@ -347,6 +349,11 @@ static void __init davinci_timer_init(void)
"%s: can't register clocksource!\n";
int i;
+#ifdef CONFIG_COMMON_CLK
+ /* invoke clk init function specific to a SoC */
+ if (davinci_soc_info.clk_init)
+ davinci_soc_info.clk_init();
+#endif
clockevent_id = soc_info->timer_info->clockevent_id;
clocksource_id = soc_info->timer_info->clocksource_id;
--
1.7.9.5
On Thu, Oct 25, 2012 at 6:11 PM, Murali Karicheri <[email protected]> wrote:
> This is the driver for the main PLL clock hardware found on DM SoCs.
> This driver borrowed code from arch/arm/mach-davinci/clock.c and
> implemented the driver as per common clock provider API. The main PLL
> hardware typically has a multiplier, a pre-divider and a post-divider.
> Some of the SoCs has the divider fixed meaning they can not be
> configured through a register. HAS_PREDIV and HAS_POSTDIV flags are used
> to tell the driver if a hardware has these dividers present or not.
> Driver is configured through the struct clk_pll_data that has the
> SoC specific clock data.
>
> Signed-off-by: Murali Karicheri <[email protected]>
This looks good to me.
Acked-by: Linus Walleij <[email protected]>
Yours,
Linus Walleij
On Thu, Oct 25, 2012 at 6:11 PM, Murali Karicheri <[email protected]> wrote:
> This is the driver for the Power Sleep Controller (PSC) hardware
> found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed
> code from arch/arm/mach-davinci/psc.c and implemented the driver
> as per common clock provider API. The PSC module is responsible for
> enabling/disabling the Power Domain and Clock domain for different IPs
> present in the SoC. The driver is configured through the clock data
> passed to the driver through struct clk_psc_data.
>
> Signed-off-by: Murali Karicheri <[email protected]>
Acked-by: Linus Walleij <[email protected]>
Here is some pedantic stuff if you're really bored:
> diff --git a/drivers/clk/davinci/clk-psc.c b/drivers/clk/davinci/clk-psc.c
(...)
> + ptcmd = 1 << domain;
ptcmd = BIT(domain);
> + pdctl = readl(psc_base + PDCTL + 4 * domain);
> + pdctl |= 0x100;
pdctl |= BIT(8); /* and here a comment explaing what on earth that means */
> + } else {
> + ptcmd = 1 << domain;
ptcmd = BIT(domain);
Yours,
Linus Walleij
On Thu, Oct 25, 2012 at 6:11 PM, Murali Karicheri <[email protected]> wrote:
> This is the common clk driver initialization functions for DaVinci
> SoCs and other SoCs that uses similar hardware architecture.
> clock.h also defines struct types for clock definitions in a SoC
> and clock data type for configuring clk-mux. The initialization
> functions are used by clock initialization code in a specific
> platform/SoC.
>
> Signed-off-by: Murali Karicheri <[email protected]>
This is looking good.
Acked-by: Linus Walleij <[email protected]>
Yours,
Linus Walleij
On Thu, Oct 25, 2012 at 6:11 PM, Murali Karicheri <[email protected]> wrote:
> pll dividers are present in the pll controller of DaVinci and Other
> SoCs that re-uses the same hardware IP. This has a enable bit for
> bypass the divider or enable the driver. This is a sub class of the
> clk-divider clock checks the enable bit to calculare the rate and
> invoke the recalculate() function of the clk-divider if enabled.
>
> Signed-off-by: Murali Karicheri <[email protected]>
Looking good,
Acked-by: Linus Walleij <[email protected]>
Yours,
Linus Walleij
Mike, Sekhar,
Could you please take some time to review this patch set? Last one was reviewed by Sekhar and I have re-worked the patch to address his comments.
Murali
>> -----Original Message-----
>> From: Karicheri, Muralidharan
>> Sent: Thursday, October 25, 2012 12:12 PM
>> To: [email protected]; [email protected]; [email protected];
>> [email protected]; [email protected]; [email protected];
>> [email protected]; [email protected]; Nori, Sekhar; Hilman, Kevin;
>> [email protected]; [email protected]; davinci-linux-open-
>> [email protected]; [email protected]
>> Cc: [email protected] - Linux developers for Keystone family of devices (May
>> contain non-TIers); Karicheri, Muralidharan
>> Subject: [PATCH v3 00/11] common clk drivers migration for DaVinci SoCs
>>
>> This is v3 of the patch series for implementing clock tree for DaVinci SoCs using common
>> clk framework.
>>
>> supported platforms: DM644x
>>
>> This code base can be accessed at
>>
>> https://gitorious.org/~m-karicheri/linux-davinci/linux-davinci-clk/commits/common-clk-
>> v3
>>
>> The patch series is split in two parts:-
>> patches prefixed with "clk" are for clk drivers
>> patches prefixed with "ARM" are for davinci machine specific code.
>>
>> revision history:
>> -----------------
>> updates in v3:
>> - Major changes done based on review of v2 to move the clock data and
>> initialization code to drivers/clk/davinci. There is a soc specific
>> code (for example dm644x-clock.c) for doing clock initialization.
>> - Files renamed based on the review comments.
>> - Only DM644x is supported. Other devices will be added as the code
>> matures so that unnecessary rework can be avoided.
>> - Incorporated comments from Nori Sekhar and Linus (comments coding
>> style)
>> - Added clk-div clock to represent DaVinci pll divider clocks
>> - Removed clk-keystone-pll.c (will be added later)
>>
>> updates in v2:
>> - updates to davinci_clk to use union for clk driver platform data
>> - Fixed Linus Walleij' comment on code comment
>> - added code clean up that takes out the ifdef used in previous patches
>>
>> updates in v1:
>> - Added DM365 and DM355
>> - updates to davinci_clk struct to accomodate clk-fixed-factor data
>>
>> initial version:-
>>
>> Currently arch/arm/mach-davinci/clock.c and arch/arm/mach-davinci/psc.c implements
>> clock drivers for DaVinci. This patch makes these code obsolete and migrate the SoC code
>> to use the common clk based drivers. This adds two clk drivers specific to DaVinci and
>> Keystone (found in c6x arch such as C6678) devices. Some of the existing clk drivers such
>> as clk-fixed-rate, clk-divider, and clk-mux are re-used in addition to the DaVinci specific
>> drivers to initialize the clock tree for the SoCs. Please refer chapter 6 of
>> http://www.ti.com/lit/ug/sprue14c/sprue14c.pdf for details of the PLL hardware in
>> DM6446 and chapter 7 for defails of the PSC hardware.
>>
>> There are two Main PLLs in DM644x. PLL1 and PLL2. Each of these generate different
>> clocks in the DM device through PLL dividers. Figure above shows this for PLL1. Similar
>> hardware exists for PLL2 and the related output clocks. The hardware is similar in most of
>> the DM SoCs. Some of the recent Keystone devices
>> (c6678 under c6x architecture) include a slight variant of the PLL that implemented
>> different registers for the multipliers and dividers. All of these devices include PLL dividers
>> (PLLDIVx) and Power Sleep controllers (PSC). The SoCs defines various Power Domains
>> and Clock domains and there are PSC modules that controls power and clocks to various
>> hardware IPs of the SoC.
>>
>> Following drivers are used for various clock hardware blocks:-
>>
>> CLKIN and OSCIN - clk-fixed-rate (existing driver) MUX - clk-mux (existing driver)
>> PLLDIVx - davinci/clk-div (new driver) PLL mult/div - clk-pll (new driver) PSC - clk-psc.c
>> (new driver)
>>
>> Please note that initially only platforms listed above are supported. The idea is to review
>> the initial patch set and get a feedback on the overall structure of the code organization.
>> The other SoCs will be added in subsequent patch revisions.
>>
>> The driver code implements the features needed to support the platforms listed above. It
>> is expected that these drivers get updated in subsequent patch revisions to support
>> additional SoCs. I have boot tested this on DM6446 EVM. Also verified reboot command
>> works and the clock rates are set as before.
>> The patches depends on the following patches that I had sent for review earlier:
>>
>> davinci spi driver preparation @
>> https://patchwork.kernel.org/patch/1389321/
>> davinci watchdog driver preparation @
>> https://lkml.org/lkml/2012/9/7/634
>> davinci nand driver preparation @
>> https://lkml.org/lkml/2012/9/7/635
>> davinci i2c driver preparation @
>> https://patchwork.kernel.org/patch/1388841/
>> davinci gpio driver preparation @
>> https://lkml.org/lkml/2012/8/31/341
>>
>> [RFC - PATCH] base:pm: prepare driver for common clock framework
>>
>> ISSUES to discuss
>> -----------------
>> Following are to be discussed as part of this patch review.
>>
>> 1. arch/arm/pm.c. This is configuring PLL controller registers for suspend and
>> resume. It appears that we need to move this code to clk-pll.c?? But
>> I can't find APIs for suspend and resume in the common clk framework. How
>> is this expected to work? Currently i have kept the code ASIS.
>>
>> 2. There are usecount=1 in the old clock implementation for dsp, vicp and timer2
>> clocks. CLK_IGNORE_UNUSED flag is used currently to implement the same as
>> disabling these unused clocks causes issues in boot up,
>>
>> HELP NEEDED!!:
>> --------------
>> I am doing this work as a background activity and hence the progress will be slow. Please
>> volunteer to help me in this effort by offering to test or migrating other devices to this
>> framework.
>>
>> Murali Karicheri (11):
>> clk: davinci - add main PLL clock driver
>> clk: davinci - add PSC clock driver
>> clk: davinci - common clk utilities to init clk driver
>> clk: davinci - add pll divider clock driver
>> clk: davinci - add dm644x clock initialization
>> clk: davinci - add build infrastructure for DaVinci clock drivers
>> ARM: davinci - restructure header files for common clock migration
>> ARM: davinci - migrating to use common clock init code
>> ARM: davinci - dm644x: update SoC code to remove the clock data
>> ARM: davinci - migrate to common clock
>> ARM: davinci - common clock migration: clean up the old code
>>
>> arch/arm/Kconfig | 1 +
>> arch/arm/mach-davinci/Kconfig | 2 +
>> arch/arm/mach-davinci/Makefile | 15 +-
>> arch/arm/mach-davinci/clock.c | 669 ---------------------------
>> arch/arm/mach-davinci/clock.h | 135 ------
>> arch/arm/mach-davinci/common.c | 10 -
>> arch/arm/mach-davinci/cpufreq.c | 2 -
>> arch/arm/mach-davinci/davinci.h | 3 +
>> arch/arm/mach-davinci/devices.c | 1 -
>> arch/arm/mach-davinci/dm644x.c | 302 +-----------
>> arch/arm/mach-davinci/include/mach/clock.h | 21 -
>> arch/arm/mach-davinci/include/mach/common.h | 10 +-
>> arch/arm/mach-davinci/include/mach/pll.h | 46 ++
>> arch/arm/mach-davinci/include/mach/psc.h | 209 ---------
>> arch/arm/mach-davinci/include/mach/time.h | 2 +-
>> arch/arm/mach-davinci/pm.c | 3 +-
>> arch/arm/mach-davinci/psc.c | 112 -----
>> arch/arm/mach-davinci/sleep.S | 3 +-
>> arch/arm/mach-davinci/time.c | 6 +-
>> drivers/clk/Kconfig | 2 +
>> drivers/clk/Makefile | 1 +
>> drivers/clk/davinci/Kconfig | 44 ++
>> drivers/clk/davinci/Makefile | 5 +
>> drivers/clk/davinci/clk-div.c | 124 +++++
>> drivers/clk/davinci/clk-div.h | 42 ++
>> drivers/clk/davinci/clk-pll.c | 146 ++++++
>> drivers/clk/davinci/clk-pll.h | 57 +++
>> drivers/clk/davinci/clk-psc.c | 207 +++++++++
>> drivers/clk/davinci/clk-psc.h | 46 ++
>> drivers/clk/davinci/clock.c | 112 +++++
>> drivers/clk/davinci/clock.h | 80 ++++
>> drivers/clk/davinci/dm644x-clock.c | 304 ++++++++++++
>> drivers/clk/davinci/pll.h | 83 ++++
>> drivers/clk/davinci/psc.h | 215 +++++++++
>> 34 files changed, 1530 insertions(+), 1490 deletions(-) delete mode 100644
>> arch/arm/mach-davinci/clock.c delete mode 100644 arch/arm/mach-davinci/clock.h
>> delete mode 100644 arch/arm/mach-davinci/include/mach/clock.h
>> create mode 100644 arch/arm/mach-davinci/include/mach/pll.h
>> delete mode 100644 arch/arm/mach-davinci/psc.c create mode 100644
>> drivers/clk/davinci/Kconfig create mode 100644 drivers/clk/davinci/Makefile create
>> mode 100644 drivers/clk/davinci/clk-div.c create mode 100644 drivers/clk/davinci/clk-
>> div.h create mode 100644 drivers/clk/davinci/clk-pll.c create mode 100644
>> drivers/clk/davinci/clk-pll.h create mode 100644 drivers/clk/davinci/clk-psc.c create
>> mode 100644 drivers/clk/davinci/clk-psc.h create mode 100644
>> drivers/clk/davinci/clock.c create mode 100644 drivers/clk/davinci/clock.h create mode
>> 100644 drivers/clk/davinci/dm644x-clock.c
>> create mode 100644 drivers/clk/davinci/pll.h create mode 100644
>> drivers/clk/davinci/psc.h
>>
>> --
>> 1.7.9.5
Hi Murali,
On 10/25/2012 9:41 PM, Murali Karicheri wrote:
> This is the driver for the main PLL clock hardware found on DM SoCs.
> This driver borrowed code from arch/arm/mach-davinci/clock.c and
> implemented the driver as per common clock provider API. The main PLL
> hardware typically has a multiplier, a pre-divider and a post-divider.
> Some of the SoCs has the divider fixed meaning they can not be
> configured through a register. HAS_PREDIV and HAS_POSTDIV flags are used
> to tell the driver if a hardware has these dividers present or not.
> Driver is configured through the struct clk_pll_data that has the
> SoC specific clock data.
>
> Signed-off-by: Murali Karicheri <[email protected]>
> ---
> diff --git a/drivers/clk/davinci/clk-pll.c b/drivers/clk/davinci/clk-pll.c
> +static unsigned long clk_pllclk_recalc(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct clk_pll *pll = to_clk_pll(hw);
> + struct clk_pll_data *pll_data = pll->pll_data;
> + u32 mult = 1, prediv = 1, postdiv = 1;
No need to initialize mult here. I gave this comment last time around as
well.
> + unsigned long rate = parent_rate;
> +
> + mult = readl(pll_data->reg_pllm);
> +
> + /*
> + * if fixed_multiplier is non zero, multiply pllm value by this
> + * value.
> + */
> + if (pll_data->fixed_multiplier)
> + mult = pll_data->fixed_multiplier *
> + (mult & pll_data->pllm_mask);
> + else
> + mult = (mult & pll_data->pllm_mask) + 1;
Hmm, this is interpreting the 'mult' register field differently in both
cases. In one case it is 'actual multiplier - 1' and in other case it is
the 'actual multiplier' itself. Can we be sure that the mult register
definition will change whenever there is a fixed multiplier in the PLL
block? I don't think any of the existing DaVinci devices have a fixed
multiplier. Is this on keystone?
> +struct clk *clk_register_davinci_pll(struct device *dev, const char *name,
> + const char *parent_name,
> + struct clk_pll_data *pll_data)
> +{
> + struct clk_init_data init;
> + struct clk_pll *pll;
> + struct clk *clk;
> +
> + if (!pll_data)
> + return ERR_PTR(-ENODEV);
-EINVAL? Clearly you are treating NULL value as an invalid argument here.
Thanks,
Sekhar
On 10/28/2012 03:26 PM, Linus Walleij wrote:
> On Thu, Oct 25, 2012 at 6:11 PM, Murali Karicheri <[email protected]> wrote:
>
>> pll dividers are present in the pll controller of DaVinci and Other
>> SoCs that re-uses the same hardware IP. This has a enable bit for
>> bypass the divider or enable the driver. This is a sub class of the
>> clk-divider clock checks the enable bit to calculare the rate and
>> invoke the recalculate() function of the clk-divider if enabled.
>>
>> Signed-off-by: Murali Karicheri <[email protected]>
> Looking good,
> Acked-by: Linus Walleij <[email protected]>
>
> Yours,
> Linus Walleij
>
Linus,
Thanks. I will add your Acked-by in the next version.
Murali
On 10/28/2012 03:25 PM, Linus Walleij wrote:
> On Thu, Oct 25, 2012 at 6:11 PM, Murali Karicheri <[email protected]> wrote:
>
>> This is the common clk driver initialization functions for DaVinci
>> SoCs and other SoCs that uses similar hardware architecture.
>> clock.h also defines struct types for clock definitions in a SoC
>> and clock data type for configuring clk-mux. The initialization
>> functions are used by clock initialization code in a specific
>> platform/SoC.
>>
>> Signed-off-by: Murali Karicheri <[email protected]>
> This is looking good.
> Acked-by: Linus Walleij <[email protected]>
>
> Yours,
> Linus Walleij
>
Linus,
Thanks. I will add your Acked-by in the next revision of the patch.
Murali
On 10/28/2012 03:24 PM, Linus Walleij wrote:
> On Thu, Oct 25, 2012 at 6:11 PM, Murali Karicheri <[email protected]> wrote:
>
>> This is the driver for the Power Sleep Controller (PSC) hardware
>> found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed
>> code from arch/arm/mach-davinci/psc.c and implemented the driver
>> as per common clock provider API. The PSC module is responsible for
>> enabling/disabling the Power Domain and Clock domain for different IPs
>> present in the SoC. The driver is configured through the clock data
>> passed to the driver through struct clk_psc_data.
>>
>> Signed-off-by: Murali Karicheri <[email protected]>
> Acked-by: Linus Walleij <[email protected]>
>
> Here is some pedantic stuff if you're really bored:
>
>> diff --git a/drivers/clk/davinci/clk-psc.c b/drivers/clk/davinci/clk-psc.c
> (...)
>> + ptcmd = 1 << domain;
> ptcmd = BIT(domain);
>
>> + pdctl = readl(psc_base + PDCTL + 4 * domain);
>> + pdctl |= 0x100;
> pdctl |= BIT(8); /* and here a comment explaing what on earth that means */
>
>> + } else {
>> + ptcmd = 1 << domain;
> ptcmd = BIT(domain);
>
> Yours,
> Linus Walleij
>
>
Linus,
Thanks. I will fix the above and add your Acked-by in the next revision
of the patch.
Murali
On 10/28/2012 03:18 PM, Linus Walleij wrote:
> On Thu, Oct 25, 2012 at 6:11 PM, Murali Karicheri <[email protected]> wrote:
>
>> This is the driver for the main PLL clock hardware found on DM SoCs.
>> This driver borrowed code from arch/arm/mach-davinci/clock.c and
>> implemented the driver as per common clock provider API. The main PLL
>> hardware typically has a multiplier, a pre-divider and a post-divider.
>> Some of the SoCs has the divider fixed meaning they can not be
>> configured through a register. HAS_PREDIV and HAS_POSTDIV flags are used
>> to tell the driver if a hardware has these dividers present or not.
>> Driver is configured through the struct clk_pll_data that has the
>> SoC specific clock data.
>>
>> Signed-off-by: Murali Karicheri <[email protected]>
> This looks good to me.
> Acked-by: Linus Walleij <[email protected]>
>
> Yours,
> Linus Walleij
>
>
Linus,
Thanks. I will add your Acked-by in the next revision of the patch.
Murali
On 10/31/2012 08:29 AM, Sekhar Nori wrote:
> Hi Murali,
>
> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>> This is the driver for the main PLL clock hardware found on DM SoCs.
>> This driver borrowed code from arch/arm/mach-davinci/clock.c and
>> implemented the driver as per common clock provider API. The main PLL
>> hardware typically has a multiplier, a pre-divider and a post-divider.
>> Some of the SoCs has the divider fixed meaning they can not be
>> configured through a register. HAS_PREDIV and HAS_POSTDIV flags are used
>> to tell the driver if a hardware has these dividers present or not.
>> Driver is configured through the struct clk_pll_data that has the
>> SoC specific clock data.
>>
>> Signed-off-by: Murali Karicheri <[email protected]>
>> ---
>> diff --git a/drivers/clk/davinci/clk-pll.c b/drivers/clk/davinci/clk-pll.c
>> +static unsigned long clk_pllclk_recalc(struct clk_hw *hw,
>> + unsigned long parent_rate)
>> +{
>> + struct clk_pll *pll = to_clk_pll(hw);
>> + struct clk_pll_data *pll_data = pll->pll_data;
>> + u32 mult = 1, prediv = 1, postdiv = 1;
> No need to initialize mult here. I gave this comment last time around as
> well.
Yes. I missed it. I will fix it in the next revision.
>> + unsigned long rate = parent_rate;
>> +
>> + mult = readl(pll_data->reg_pllm);
>> +
>> + /*
>> + * if fixed_multiplier is non zero, multiply pllm value by this
>> + * value.
>> + */
>> + if (pll_data->fixed_multiplier)
>> + mult = pll_data->fixed_multiplier *
>> + (mult & pll_data->pllm_mask);
>> + else
>> + mult = (mult & pll_data->pllm_mask) + 1;
> Hmm, this is interpreting the 'mult' register field differently in both
> cases. In one case it is 'actual multiplier - 1' and in other case it is
> the 'actual multiplier' itself. Can we be sure that the mult register
> definition will change whenever there is a fixed multiplier in the PLL
> block? I don't think any of the existing DaVinci devices have a fixed
> multiplier. Is this on keystone?
Read section 6.4.3 (PLL Mode) in DM365 documentation (SPRUFG5a.pdf) that
states PLL multiplies the clock by 2x the value in the PLLM. In the old
code this is handled by a if cpu_is_* macro that we can't use in the
driver. So this is represented by a fixed_multiplier that can be set to
2 for DM365 and zero on other SoCs.
>> +struct clk *clk_register_davinci_pll(struct device *dev, const char *name,
>> + const char *parent_name,
>> + struct clk_pll_data *pll_data)
>> +{
>> + struct clk_init_data init;
>> + struct clk_pll *pll;
>> + struct clk *clk;
>> +
>> + if (!pll_data)
>> + return ERR_PTR(-ENODEV);
> -EINVAL? Clearly you are treating NULL value as an invalid argument here.
Ok. Will fix to ERR_PTR(-EINVAL).
>
> Thanks,
> Sekhar
>
On 10/31/2012 7:16 PM, Murali Karicheri wrote:
> On 10/31/2012 08:29 AM, Sekhar Nori wrote:
>>> + /*
>>> + * if fixed_multiplier is non zero, multiply pllm value by this
>>> + * value.
>>> + */
>>> + if (pll_data->fixed_multiplier)
>>> + mult = pll_data->fixed_multiplier *
>>> + (mult & pll_data->pllm_mask);
>>> + else
>>> + mult = (mult & pll_data->pllm_mask) + 1;
>> Hmm, this is interpreting the 'mult' register field differently in both
>> cases. In one case it is 'actual multiplier - 1' and in other case it is
>> the 'actual multiplier' itself. Can we be sure that the mult register
>> definition will change whenever there is a fixed multiplier in the PLL
>> block? I don't think any of the existing DaVinci devices have a fixed
>> multiplier. Is this on keystone?
> Read section 6.4.3 (PLL Mode) in DM365 documentation (SPRUFG5a.pdf) that
> states PLL multiplies the clock by 2x the value in the PLLM. In the old
> code this is handled by a if cpu_is_* macro that we can't use in the
> driver. So this is represented by a fixed_multiplier that can be set to
> 2 for DM365 and zero on other SoCs.
Thanks for the clarification.
Regards,
Sekhar
On 10/25/2012 9:41 PM, Murali Karicheri wrote:
> This is the common clk driver initialization functions for DaVinci
> SoCs and other SoCs that uses similar hardware architecture.
> clock.h also defines struct types for clock definitions in a SoC
> and clock data type for configuring clk-mux. The initialization
> functions are used by clock initialization code in a specific
> platform/SoC.
>
> Signed-off-by: Murali Karicheri <[email protected]>
> +struct clk *davinci_plldiv_clk(const char *name, const char *parent,
> + struct clk_plldiv_data *data)
> +{
> + /*
> + * This is a PLL divider clock with divider specified by
> + * div_reg in pll_div_data.
> + */
> + data->reg = ioremap(data->phys_div_reg, 4);
> + if (WARN_ON(!data->reg))
> + return NULL;
> +
> + return clk_register_davinci_plldiv(NULL, name, parent, data, &_lock);
This function does not exist at this point. Looks like you need to swap
3/11 with 4/11. Also, you should also add build infrastructure
(makefile, Kconfig) changes in the same patch that creates the file.
There is no point in adding those separately.
Thanks,
Sekhar
On 11/01/2012 08:41 AM, Sekhar Nori wrote:
> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>> This is the common clk driver initialization functions for DaVinci
>> SoCs and other SoCs that uses similar hardware architecture.
>> clock.h also defines struct types for clock definitions in a SoC
>> and clock data type for configuring clk-mux. The initialization
>> functions are used by clock initialization code in a specific
>> platform/SoC.
>>
>> Signed-off-by: Murali Karicheri <[email protected]>
>> +struct clk *davinci_plldiv_clk(const char *name, const char *parent,
>> + struct clk_plldiv_data *data)
>> +{
>> + /*
>> + * This is a PLL divider clock with divider specified by
>> + * div_reg in pll_div_data.
>> + */
>> + data->reg = ioremap(data->phys_div_reg, 4);
>> + if (WARN_ON(!data->reg))
>> + return NULL;
>> +
>> + return clk_register_davinci_plldiv(NULL, name, parent, data, &_lock);
> This function does not exist at this point. Looks like you need to swap
> 3/11 with 4/11. Also, you should also add build infrastructure
> (makefile, Kconfig) changes in the same patch that creates the file.
> There is no point in adding those separately.
>
> Thanks,
> Sekhar
>
Sekhar,
So the Makefile, Kconfig and new files should be in the same patch.
Also will re-order the 3/11 and 4/11 in the next revision.
Murali
On 10/25/2012 9:41 PM, Murali Karicheri wrote:
> pll dividers are present in the pll controller of DaVinci and Other
> SoCs that re-uses the same hardware IP. This has a enable bit for
> bypass the divider or enable the driver. This is a sub class of the
> clk-divider clock checks the enable bit to calculare the rate and
> invoke the recalculate() function of the clk-divider if enabled.
>
> Signed-off-by: Murali Karicheri <[email protected]>
> ---
> drivers/clk/davinci/clk-div.c | 124 +++++++++++++++++++++++++++++++++++++++++
> drivers/clk/davinci/clk-div.h | 42 ++++++++++++++
> 2 files changed, 166 insertions(+)
> create mode 100644 drivers/clk/davinci/clk-div.c
> create mode 100644 drivers/clk/davinci/clk-div.h
>
> diff --git a/drivers/clk/davinci/clk-div.c b/drivers/clk/davinci/clk-div.c
> new file mode 100644
> index 0000000..8147d99
> --- /dev/null
> +++ b/drivers/clk/davinci/clk-div.c
> @@ -0,0 +1,124 @@
> +/*
> + * Copyright 2012 Freescale Semiconductor, Inc.
> + * Copyright 2012 Texas instuments
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
incomplete sentence.
> +/**
> + * clk_register_davinci_plldiv - register function for DaVinci PLL divider clk
> + *
> + * @dev: device ptr
> + * @name: name of the clock
> + * @parent_name: name of parent clock
> + * @plldiv_data: ptr to pll divider data
> + * @lock: ptr to spinlock passed to divider clock
> + */
> +struct clk *clk_register_davinci_plldiv(struct device *dev,
Why do you need a dev pointer here and which device does it point to? In
the only usage of this API in the series, you pass a NULL here. I should
have probably asked this question on one of the earlier patches itself.
> + const char *name, const char *parent_name,
> + struct clk_plldiv_data *plldiv_data,
> + spinlock_t *lock)
> +{
> + struct clk_div *div;
> + struct clk *clk;
> + struct clk_init_data init;
> +
> + div = kzalloc(sizeof(*div), GFP_KERNEL);
> + if (!div)
> + return ERR_PTR(-ENOMEM);
> +
> + init.name = name;
> + init.ops = &clk_div_ops;
> + init.flags = plldiv_data->flags;
> + init.parent_names = (parent_name ? &parent_name : NULL);
> + init.num_parents = (parent_name ? 1 : 0);
> +
> + div->reg = plldiv_data->reg;
> + div->en_id = plldiv_data->en_id;
> +
> + div->divider.reg = plldiv_data->reg;
> + div->divider.shift = plldiv_data->shift;
> + div->divider.width = plldiv_data->width;
> + div->divider.flags = plldiv_data->divider_flags;
> + div->divider.lock = lock;
> + div->divider.hw.init = &init;
> + div->ops = &clk_divider_ops;
> +
> + clk = clk_register(NULL, &div->divider.hw);
Shouldn't you be calling clk_register_divider() here which in turn will
do clk_register()?
Thanks,
Sekhar
On 11/02/2012 07:33 AM, Sekhar Nori wrote:
> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>
>> pll dividers are present in the pll controller of DaVinci and Other
>> SoCs that re-uses the same hardware IP. This has a enable bit for
>> bypass the divider or enable the driver. This is a sub class of the
>> clk-divider clock checks the enable bit to calculare the rate and
>> invoke the recalculate() function of the clk-divider if enabled.
>>
>> Signed-off-by: Murali Karicheri <[email protected]>
>> ---
>> drivers/clk/davinci/clk-div.c | 124 +++++++++++++++++++++++++++++++++++++++++
>> drivers/clk/davinci/clk-div.h | 42 ++++++++++++++
>> 2 files changed, 166 insertions(+)
>> create mode 100644 drivers/clk/davinci/clk-div.c
>> create mode 100644 drivers/clk/davinci/clk-div.h
>>
>> diff --git a/drivers/clk/davinci/clk-div.c b/drivers/clk/davinci/clk-div.c
>> new file mode 100644
>> index 0000000..8147d99
>> --- /dev/null
>> +++ b/drivers/clk/davinci/clk-div.c
>> @@ -0,0 +1,124 @@
>> +/*
>> + * Copyright 2012 Freescale Semiconductor, Inc.
>> + * Copyright 2012 Texas instuments
>> + *
>> + * The code contained herein is licensed under the GNU General Public
>> + * License. You may obtain a copy of the GNU General Public License
>> + * Version 2 or later at the following locations:
> incomplete sentence.
Will fix
>
>> +/**
>> + * clk_register_davinci_plldiv - register function for DaVinci PLL divider clk
>> + *
>> + * @dev: device ptr
>> + * @name: name of the clock
>> + * @parent_name: name of parent clock
>> + * @plldiv_data: ptr to pll divider data
>> + * @lock: ptr to spinlock passed to divider clock
>> + */
>> +struct clk *clk_register_davinci_plldiv(struct device *dev,
> Why do you need a dev pointer here and which device does it point to? In
> the only usage of this API in the series, you pass a NULL here. I should
> have probably asked this question on one of the earlier patches itself.
>
I did a grep in the drivers/clk directory. All of the platform drivers
are having the device ptr and all of them are called with NULL. I am not
sure what is the intent of this arg in the API. As per documentation of
the clk_register() API, the device ptr points to the device that is
registering this clk. So if a specific device driver ever has to
register a PLL div clk, this will be non NULL. In the normal use case,
clk is registered in a platform specific code and is always passed NULL.
The platform/SoC specific clock initialization code will be using
davinci_plldiv_clk() that doesn't have a device ptr arg.
So this can be changed in future in sync with other drivers (assuming
this will get removed if unused), and changes
doesn't impact the platform code that initialize the clock. So IMO, we
should keep this arg so that it is in sync with other driver APIs.
+ const char *name, const char *parent_name,
+ struct clk_plldiv_data *plldiv_data,
+ spinlock_t *lock)
+{
+ struct clk_div *div;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ div = kzalloc(sizeof(*div), GFP_KERNEL);
+ if (!div)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &clk_div_ops;
+ init.flags = plldiv_data->flags;
+ init.parent_names = (parent_name ? &parent_name : NULL);
+ init.num_parents = (parent_name ? 1 : 0);
+
+ div->reg = plldiv_data->reg;
+ div->en_id = plldiv_data->en_id;
+
+ div->divider.reg = plldiv_data->reg;
+ div->divider.shift = plldiv_data->shift;
+ div->divider.width = plldiv_data->width;
+ div->divider.flags = plldiv_data->divider_flags;
+ div->divider.lock = lock;
+ div->divider.hw.init = &init;
+ div->ops = &clk_divider_ops;
+
+ clk = clk_register(NULL, &div->divider.hw);
> Shouldn't you be calling clk_register_divider() here which in turn will
> do clk_register()?
As stated in the top of the file, this is a subclass driver of clk-div
similar in line with mxs/clk-div.c. The
driver registers the clock instead of calling clk_register_divider() so
that it's ops function has a chance to do whatever it wants to do and
call the divider ops function after that.
Murali
> Thanks,
> Sekhar
>
>
On 11/2/2012 7:23 PM, Murali Karicheri wrote:
> On 11/02/2012 07:33 AM, Sekhar Nori wrote:
>> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>>
>>> pll dividers are present in the pll controller of DaVinci and Other
>>> SoCs that re-uses the same hardware IP. This has a enable bit for
>>> bypass the divider or enable the driver. This is a sub class of the
>>> clk-divider clock checks the enable bit to calculare the rate and
>>> invoke the recalculate() function of the clk-divider if enabled.
>>>
>>> Signed-off-by: Murali Karicheri <[email protected]>
>>> ---
>>> +/**
>>> + * clk_register_davinci_plldiv - register function for DaVinci PLL
>>> divider clk
>>> + *
>>> + * @dev: device ptr
>>> + * @name: name of the clock
>>> + * @parent_name: name of parent clock
>>> + * @plldiv_data: ptr to pll divider data
>>> + * @lock: ptr to spinlock passed to divider clock
>>> + */
>>> +struct clk *clk_register_davinci_plldiv(struct device *dev,
>> Why do you need a dev pointer here and which device does it point to? In
>> the only usage of this API in the series, you pass a NULL here. I should
>> have probably asked this question on one of the earlier patches itself.
>>
> I did a grep in the drivers/clk directory. All of the platform drivers
> are having the device ptr and all of them are called with NULL. I am not
> sure what is the intent of this arg in the API. As per documentation of
I just took a look at the mxs example you referenced below and it does
not take a dev pointer.
struct clk *mxs_clk_div(const char *name, const char *parent_name,
void __iomem *reg, u8 shift, u8 width, u8 busy)
{
> the clk_register() API, the device ptr points to the device that is
> registering this clk. So if a specific device driver ever has to
> register a PLL div clk, this will be non NULL. In the normal use case,
> clk is registered in a platform specific code and is always passed NULL.
>
> The platform/SoC specific clock initialization code will be using
> davinci_plldiv_clk() that doesn't have a device ptr arg.
> So this can be changed in future in sync with other drivers (assuming
> this will get removed if unused), and changes
> doesn't impact the platform code that initialize the clock. So IMO, we
> should keep this arg so that it is in sync with other driver APIs.
I think you should get rid of this unused arg and introduce it when you
actually need it. That way we are clear about why we need it.
>
> + const char *name, const char *parent_name,
> + struct clk_plldiv_data *plldiv_data,
> + spinlock_t *lock)
> +{
> + struct clk_div *div;
> + struct clk *clk;
> + struct clk_init_data init;
> +
> + div = kzalloc(sizeof(*div), GFP_KERNEL);
> + if (!div)
> + return ERR_PTR(-ENOMEM);
> +
> + init.name = name;
> + init.ops = &clk_div_ops;
> + init.flags = plldiv_data->flags;
> + init.parent_names = (parent_name ? &parent_name : NULL);
> + init.num_parents = (parent_name ? 1 : 0);
> +
> + div->reg = plldiv_data->reg;
> + div->en_id = plldiv_data->en_id;
> +
> + div->divider.reg = plldiv_data->reg;
> + div->divider.shift = plldiv_data->shift;
> + div->divider.width = plldiv_data->width;
> + div->divider.flags = plldiv_data->divider_flags;
> + div->divider.lock = lock;
> + div->divider.hw.init = &init;
> + div->ops = &clk_divider_ops;
> +
> + clk = clk_register(NULL, &div->divider.hw);
>
>> Shouldn't you be calling clk_register_divider() here which in turn will
>> do clk_register()?
> As stated in the top of the file, this is a subclass driver of clk-div
> similar in line with mxs/clk-div.c. The
> driver registers the clock instead of calling clk_register_divider() so
> that it's ops function has a chance to do whatever it wants to do and
> call the divider ops function after that.
I see that now. I should have paid more attention.
Regards,
Sekhar
On 10/25/2012 9:41 PM, Murali Karicheri wrote:
> This is the driver for the Power Sleep Controller (PSC) hardware
> found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed
> code from arch/arm/mach-davinci/psc.c and implemented the driver
> as per common clock provider API. The PSC module is responsible for
> enabling/disabling the Power Domain and Clock domain for different IPs
> present in the SoC. The driver is configured through the clock data
> passed to the driver through struct clk_psc_data.
>
> Signed-off-by: Murali Karicheri <[email protected]>
> ---
> +/**
> + * struct clk_psc - DaVinci PSC clock driver data
> + *
> + * @hw: clk_hw for the psc
> + * @psc_data: Driver specific data
> + */
> +struct clk_psc {
> + struct clk_hw hw;
> + struct clk_psc_data *psc_data;
> + spinlock_t *lock;
Unused member? I don't see this being used.
Thanks,
Sekhar
On 10/25/2012 9:41 PM, Murali Karicheri wrote:
> This is the common clk driver initialization functions for DaVinci
> SoCs and other SoCs that uses similar hardware architecture.
> clock.h also defines struct types for clock definitions in a SoC
> and clock data type for configuring clk-mux. The initialization
> functions are used by clock initialization code in a specific
> platform/SoC.
>
> Signed-off-by: Murali Karicheri <[email protected]>
> ---
> drivers/clk/davinci/clock.c | 112 +++++++++++++++++++++++++++++++++++++++++++
> drivers/clk/davinci/clock.h | 80 +++++++++++++++++++++++++++++++
> 2 files changed, 192 insertions(+)
> create mode 100644 drivers/clk/davinci/clock.c
> create mode 100644 drivers/clk/davinci/clock.h
>
> diff --git a/drivers/clk/davinci/clock.c b/drivers/clk/davinci/clock.c
> new file mode 100644
> index 0000000..ad02149
> --- /dev/null
> +++ b/drivers/clk/davinci/clock.c
> @@ -0,0 +1,112 @@
> +/*
> + * clock.c - davinci clock initialization functions for various clocks
> + *
> + * Copyright (C) 2006-2012 Texas Instruments.
> + * Copyright (C) 2008-2009 Deep Root Systems, LLC
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +#include <linux/init.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clkdev.h>
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +
> +#include "clk-pll.h"
> +#include "clk-psc.h"
> +#include "clk-div.h"
> +#include "clock.h"
> +
> +static DEFINE_SPINLOCK(_lock);
> +
> +#ifdef CONFIG_CLK_DAVINCI_PLL
> +struct clk *davinci_pll_clk(const char *name, const char *parent,
> + u32 phys_pllm, u32 phys_prediv, u32 phys_postdiv,
> + struct clk_pll_data *pll_data)
> +{
> + struct clk *clkp = NULL;
> +
> + pll_data->reg_pllm = ioremap(phys_pllm, 4);
> + if (WARN_ON(!pll_data->reg_pllm))
> + return clkp;
I would prefer ERR_PTR(-ENOMEM) here. Same comment applies to other
instances elsewhere in the patch.
> diff --git a/drivers/clk/davinci/clock.h b/drivers/clk/davinci/clock.h
> new file mode 100644
> index 0000000..73204b8
> --- /dev/null
> +++ b/drivers/clk/davinci/clock.h
> @@ -0,0 +1,80 @@
> +/*
> + * TI DaVinci Clock definitions - Contains Macros and Types used for
> + * defining various clocks on a DaVinci SoC
> + *
> + * Copyright (C) 2012 Texas Instruments
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +#ifndef __DAVINCI_CLOCK_H
> +#define __DAVINCI_CLOCK_H
> +
> +#include <linux/types.h>
> +
> +/* general flags: */
> +#define ALWAYS_ENABLED BIT(0)
This is not used in this patch. Can you add the define along with its
usage so it is immediately clear why you need it?
> +/**
> + * struct davinci_clk - struct for defining DaVinci clocks for a SoC.
> + *
> + * @name: name of the clock
> + * @parent: name of parent clock
> + * @flags: General flags for all drivers used by platform clock init code
> + * @data: data specific to a clock used by the driver
> + * @dev_id: dev_id used to look up this clock. If this is NULL
> + * clock name is used for lookup.
> + */
> +struct davinci_clk {
> + const char *name;
> + const char *parent;
> + u32 flags;
> + void *data;
> + char *dev_id;
Similarly dont see this being used as well.
Thanks,
Sekhar
On 10/25/2012 9:41 PM, Murali Karicheri wrote:
> This patch adds dm644x clock initialization code that consists of
> clocks data for various clocks and clock register callouts to
> various clock drivers. It uses following clk drivers for this
>
> 1. clk-fixed-rate - for ref clock
> 2. clk-mux - for mux at the input and output of main pll
> 3. davinci specific clk-pll for main pll clock
> 4. davinci specific clk-div for pll divider clock
> 5. clk-fixed-factor for fixed factor clock such as auxclk
> 6. davinci specific clk-psc for psc clocks
>
> This patch also moves all of the PLL and PSC register definitions
> from clock.h and psc.h under davinci to the clk/davinci folder so
> that various soc specific clock initialization code can share these
> definitions.
Except this patch does not move the defines, it creates a copy of them
(which is bad since you quickly lose track of which is the correct
copy). Is this done to avoid including mach/ header files here? It will
actually be better to include the mach/ files here as a temporary
solution and then remove the include mach/ files once all the SoCs have
been converted over.
> Signed-off-by: Murali Karicheri <[email protected]>
> ---
> drivers/clk/davinci/dm644x-clock.c | 304 ++++++++++++++++++++++++++++++++++++
> drivers/clk/davinci/pll.h | 83 ++++++++++
> drivers/clk/davinci/psc.h | 215 +++++++++++++++++++++++++
> 3 files changed, 602 insertions(+)
> create mode 100644 drivers/clk/davinci/dm644x-clock.c
> create mode 100644 drivers/clk/davinci/pll.h
> create mode 100644 drivers/clk/davinci/psc.h
>
> +/* all clocks available in DM644x SoCs */
> +enum dm644x_clk {
> + clkin, oscin, ref_clk_mux, pll1, pll1_plldiv_clk_mux, auxclk,
> + clk_pll1_sysclk1, clk_pll1_sysclk2, clk_pll1_sysclk3, clk_pll1_sysclk4,
> + clk_pll1_sysclk5, clk_pll1_sysclkbp, pll2, pll2_plldiv_clk_mux,
> + clk_pll2_sysclk1, clk_pll2_sysclk2, clk_pll2_sysclkbp, dsp, arm, vicp,
> + vpss_master, vpss_slave, uart0, uart1, uart2, emac, i2c, ide, asp,
> + mmcsd, spi, gpio, usb, vlynq, aemif, pwm0, pwm1, pwm2, timer0, timer1,
> + timer2, clk_max
> +};
> +
> +static struct davinci_clk *psc_clocks[] = {
> + &clk_dsp, &clk_arm, &clk_vicp, &clk_vpss_master, &clk_vpss_slave,
> + &clk_uart0, &clk_uart1, &clk_uart2, &clk_emac, &clk_i2c, &clk_ide,
> + &clk_asp0, &clk_mmcsd, &clk_spi, &clk_gpio, &clk_usb, &clk_vlynq,
> + &clk_aemif, &clk_pwm0, &clk_pwm1, &clk_pwm2, &clk_timer0, &clk_timer1,
> + &clk_timer2
> +};
You rely on perfect order between this array and dm644x_clk enum above.
Can you initialize this array using the enum as the index so that it is
clear. Current method is too error prone.
Thanks,
Sekhar
On 10/25/2012 9:41 PM, Murali Karicheri wrote:
> Currently migrate only DM644x as this is being reviewed. Once all
> platforms are migrated, the Makefile will be cleaned up to remove
> obsoleted files clock.o and psc.o
>
> Signed-off-by: Murali Karicheri <[email protected]>
> ---
> arch/arm/Kconfig | 1 +
> arch/arm/mach-davinci/Kconfig | 2 ++
> arch/arm/mach-davinci/Makefile | 11 ++++++++++-
> 3 files changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index c5f9ae5..4611987 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -967,6 +967,7 @@ config ARCH_DAVINCI
> select ARCH_REQUIRE_GPIOLIB
> select ZONE_DMA
> select HAVE_IDE
> + select COMMON_CLK
> select CLKDEV_LOOKUP
> select GENERIC_ALLOCATOR
> select GENERIC_IRQ_CHIP
This list has to be sorted. Russell has a patch which fixed this all
across arch/arm/* which got merged for v3.7. This patch does not apply
to v3.7-rc3 anymore due to the same reason.
Thanks,
Sekhar
On 10/25/2012 9:41 PM, Murali Karicheri wrote:
> This updates clk Makefile and Kconfig to integrate the DaVinci specific
> clock drivers. Also add new Kconfig and Makefile for these drivers.
>
> Signed-off-by: Murali Karicheri <[email protected]>
As mentioned before, this should be folded into previous patches which
actually add the particular functionality.
> ---
> drivers/clk/Kconfig | 2 ++
> drivers/clk/Makefile | 1 +
> drivers/clk/davinci/Kconfig | 44 ++++++++++++++++++++++++++++++++++++++++++
> drivers/clk/davinci/Makefile | 5 +++++
> 4 files changed, 52 insertions(+)
> create mode 100644 drivers/clk/davinci/Kconfig
> create mode 100644 drivers/clk/davinci/Makefile
>
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index 7f0b5ca..1ad2ab0 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -33,6 +33,8 @@ config COMMON_CLK_DEBUG
> clk_flags, clk_prepare_count, clk_enable_count &
> clk_notifier_count.
>
> +source "drivers/clk/davinci/Kconfig"
> +
> config COMMON_CLK_WM831X
> tristate "Clock driver for WM831x/2x PMICs"
> depends on MFD_WM831X
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 5869ea3..b127b6f 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -10,6 +10,7 @@ obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
> obj-$(CONFIG_PLAT_SPEAR) += spear/
> obj-$(CONFIG_ARCH_U300) += clk-u300.o
> obj-$(CONFIG_ARCH_INTEGRATOR) += versatile/
> +obj-$(CONFIG_DAVINCI_CLKS) += davinci/
>
> # Chip specific
> obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
> diff --git a/drivers/clk/davinci/Kconfig b/drivers/clk/davinci/Kconfig
> new file mode 100644
> index 0000000..e53bbc3
> --- /dev/null
> +++ b/drivers/clk/davinci/Kconfig
> @@ -0,0 +1,44 @@
> +menu "TI DaVinci Clock drivers"
> + depends on COMMON_CLK
> +
> +config CLK_DAVINCI_PSC
> + bool "TI DaVici PSC clock driver"
> + default n
> + ---help---
> + Selects clock driver for DaVinci PSC clocks. This clock
> + hardware is found on TI DaVinci SoCs and other SoCs that
> + uses this hardware IP. This hardware has a local power
> + sleep control module that gate the clock to the IP.
> +
> +config CLK_DAVINCI_PLL
> + bool "DaVici main PLL clock"
> + ---help---
> + Selects clock driver for DaVinci main PLL. This clock
> + hardware is found on TI DaVinci SoCs. This typically has
> + a multiplier, a pre divider and post driver. Some of the
> + SoCs has the the dividers fixed, and others have it
> + programmable
> +
> +config CLK_DAVINCI_PLLDIV
> + bool "DaVici PLL divider clock"
> + ---help---
> + Selects clock driver for DaVinci PLL divider. This clock
> + hardware is found on TI DaVinci SoCs. This typically has
> + a divider and an enable bit to bypass or enable the
> + divider.
> +
> +config DAVINCI_CLKS
> + bool "TI DaVinci common clocks"
> + default n
> + select CLK_DAVINCI_PSC
> + select CLK_DAVINCI_PLLDIV
> + ---help---
> + Selects common clock drivers for DaVinci. These clocks
> + are re-used across many TI SoCs that are based on DaVinci and
> + Keystone (c6x) families. This config option is used to select
> + the common clock driver for DaVinci based SoCs. SoCs specific
> + Kconfig option needs to select the driver for clocks specific
> + to the SoC.
> +
> +endmenu
I wonder if all these configurations are really required. For complete
clock functionality you anyway require all this functionality so I
wonder why anyone would not select any of these. And to differentiate
between architecture changes, conditional build based on architecture
can be used:
obj-$(CONFIG_ARCH_DAVINCI) += clk-pll.o
obj-$(CONFIG_ARCH_KEYSTONE) += clk-pll-keystone.o
Thanks,
Sekhar
On 10/25/2012 9:41 PM, Murali Karicheri wrote:
> pll.h is added to migrate some of the PLL controller defines for sleep.S.
> psc.h is modified to keep only PSC modules definitions needed by sleep.S
> after migrating to common clock. The definitions under
> ifdef CONFIG_COMMON_CLK will be removed in a subsequent patch.
> davinci_watchdog_reset prototype is moved to time.h as clock.h is
> being obsoleted. sleep.S and pm.c is modified to include the new header
> file replacements.
>
> Signed-off-by: Murali Karicheri <[email protected]>
> ---
> arch/arm/mach-davinci/devices.c | 2 ++
> arch/arm/mach-davinci/include/mach/pll.h | 46 +++++++++++++++++++++++++++++
> arch/arm/mach-davinci/include/mach/psc.h | 4 +++
> arch/arm/mach-davinci/include/mach/time.h | 4 ++-
> arch/arm/mach-davinci/pm.c | 4 +++
> arch/arm/mach-davinci/sleep.S | 4 +++
> 6 files changed, 63 insertions(+), 1 deletion(-)
> create mode 100644 arch/arm/mach-davinci/include/mach/pll.h
With this patch a _third_ copy of PLL definitions is created in kernel
sources. The existing PLL definitions in clock.h inside mach-davinci
should be moved to mach/pll.h and the pll.h you introduced inside
drivers/clk in 5/11 should be removed (this patch should appear before
5/11).
The biggest disadvantage of this approach is inclusion of mach/ includes
in drivers/clk. But duplicating code is definitely not the fix for this.
Anyway, mach/ includes are not uncommon in drivers/clk (they are all
probably suffering from the same issue).
$ grep -rl "include <mach/" drivers/clk/*
drivers/clk/clk-u300.c
drivers/clk/mmp/clk-pxa168.c
drivers/clk/mmp/clk-mmp2.c
drivers/clk/mmp/clk-pxa910.c
drivers/clk/mxs/clk-imx23.c
drivers/clk/mxs/clk-imx28.c
drivers/clk/spear/spear6xx_clock.c
drivers/clk/spear/spear3xx_clock.c
drivers/clk/spear/spear1340_clock.c
drivers/clk/spear/spear1310_clock.c
drivers/clk/ux500/clk-prcc.c
drivers/clk/versatile/clk-integrator.c
drivers/clk/versatile/clk-realview.c
pll.h can probably be moved to include/linux/clk/ to avoid this. Would
like to hear from Mike on this before going ahead.
Anyway, instead of just commenting, I though I will be more useful and
went ahead and made some of the changes I have been talking about. I
fixed the multiple PLL definitions issue, the build infrastructure issue
and the commit ordering too.
I pushed the patches I fixed to devel-common-clk branch of my git tree.
It is build tested using davinci_all_defconfig but its not runtime tested.
Can you start from here and provide me incremental changes on top of
this? That way we can collaborate to finish this faster.
Thanks,
Sekhar
On 11/03/2012 08:03 AM, Sekhar Nori wrote:
> On 11/2/2012 7:23 PM, Murali Karicheri wrote:
>> On 11/02/2012 07:33 AM, Sekhar Nori wrote:
>>> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>>>
>>>> pll dividers are present in the pll controller of DaVinci and Other
>>>> SoCs that re-uses the same hardware IP. This has a enable bit for
>>>> bypass the divider or enable the driver. This is a sub class of the
>>>> clk-divider clock checks the enable bit to calculare the rate and
>>>> invoke the recalculate() function of the clk-divider if enabled.
>>>>
>>>> Signed-off-by: Murali Karicheri <[email protected]>
>>>> ---
>>>> +/**
>>>> + * clk_register_davinci_plldiv - register function for DaVinci PLL
>>>> divider clk
>>>> + *
>>>> + * @dev: device ptr
>>>> + * @name: name of the clock
>>>> + * @parent_name: name of parent clock
>>>> + * @plldiv_data: ptr to pll divider data
>>>> + * @lock: ptr to spinlock passed to divider clock
>>>> + */
>>>> +struct clk *clk_register_davinci_plldiv(struct device *dev,
>>> Why do you need a dev pointer here and which device does it point to? In
>>> the only usage of this API in the series, you pass a NULL here. I should
>>> have probably asked this question on one of the earlier patches itself.
>>>
>> I did a grep in the drivers/clk directory. All of the platform drivers
>> are having the device ptr and all of them are called with NULL. I am not
>> sure what is the intent of this arg in the API. As per documentation of
> I just took a look at the mxs example you referenced below and it does
> not take a dev pointer.
>
> struct clk *mxs_clk_div(const char *name, const char *parent_name,
> void __iomem *reg, u8 shift, u8 width, u8 busy)
> {
>
>> the clk_register() API, the device ptr points to the device that is
>> registering this clk. So if a specific device driver ever has to
>> register a PLL div clk, this will be non NULL. In the normal use case,
>> clk is registered in a platform specific code and is always passed NULL.
>>
>> The platform/SoC specific clock initialization code will be using
>> davinci_plldiv_clk() that doesn't have a device ptr arg.
>> So this can be changed in future in sync with other drivers (assuming
>> this will get removed if unused), and changes
>> doesn't impact the platform code that initialize the clock. So IMO, we
>> should keep this arg so that it is in sync with other driver APIs.
> I think you should get rid of this unused arg and introduce it when you
> actually need it. That way we are clear about why we need it.
>
You are right. I will remove it and for other drivers.
>> + const char *name, const char *parent_name,
>> + struct clk_plldiv_data *plldiv_data,
>> + spinlock_t *lock)
>> +{
>> + struct clk_div *div;
>> + struct clk *clk;
>> + struct clk_init_data init;
>> +
>> + div = kzalloc(sizeof(*div), GFP_KERNEL);
>> + if (!div)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + init.name = name;
>> + init.ops = &clk_div_ops;
>> + init.flags = plldiv_data->flags;
>> + init.parent_names = (parent_name ? &parent_name : NULL);
>> + init.num_parents = (parent_name ? 1 : 0);
>> +
>> + div->reg = plldiv_data->reg;
>> + div->en_id = plldiv_data->en_id;
>> +
>> + div->divider.reg = plldiv_data->reg;
>> + div->divider.shift = plldiv_data->shift;
>> + div->divider.width = plldiv_data->width;
>> + div->divider.flags = plldiv_data->divider_flags;
>> + div->divider.lock = lock;
>> + div->divider.hw.init = &init;
>> + div->ops = &clk_divider_ops;
>> +
>> + clk = clk_register(NULL, &div->divider.hw);
>>
>>> Shouldn't you be calling clk_register_divider() here which in turn will
>>> do clk_register()?
>> As stated in the top of the file, this is a subclass driver of clk-div
>> similar in line with mxs/clk-div.c. The
>> driver registers the clock instead of calling clk_register_divider() so
>> that it's ops function has a chance to do whatever it wants to do and
>> call the divider ops function after that.
> I see that now. I should have paid more attention.
>
> Regards,
> Sekhar
>
On 11/03/2012 08:07 AM, Sekhar Nori wrote:
> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>> This is the driver for the Power Sleep Controller (PSC) hardware
>> found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed
>> code from arch/arm/mach-davinci/psc.c and implemented the driver
>> as per common clock provider API. The PSC module is responsible for
>> enabling/disabling the Power Domain and Clock domain for different IPs
>> present in the SoC. The driver is configured through the clock data
>> passed to the driver through struct clk_psc_data.
>>
>> Signed-off-by: Murali Karicheri <[email protected]>
>> ---
>> +/**
>> + * struct clk_psc - DaVinci PSC clock driver data
>> + *
>> + * @hw: clk_hw for the psc
>> + * @psc_data: Driver specific data
>> + */
>> +struct clk_psc {
>> + struct clk_hw hw;
>> + struct clk_psc_data *psc_data;
>> + spinlock_t *lock;
> Unused member? I don't see this being used.
OK. Will remove.
>
> Thanks,
> Sekhar
>
On 11/03/2012 08:35 AM, Sekhar Nori wrote:
> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>> This is the common clk driver initialization functions for DaVinci
>> SoCs and other SoCs that uses similar hardware architecture.
>> clock.h also defines struct types for clock definitions in a SoC
>> and clock data type for configuring clk-mux. The initialization
>> functions are used by clock initialization code in a specific
>> platform/SoC.
>>
>> Signed-off-by: Murali Karicheri <[email protected]>
>> ---
>> drivers/clk/davinci/clock.c | 112 +++++++++++++++++++++++++++++++++++++++++++
>> drivers/clk/davinci/clock.h | 80 +++++++++++++++++++++++++++++++
>> 2 files changed, 192 insertions(+)
>> create mode 100644 drivers/clk/davinci/clock.c
>> create mode 100644 drivers/clk/davinci/clock.h
>>
>> diff --git a/drivers/clk/davinci/clock.c b/drivers/clk/davinci/clock.c
>> new file mode 100644
>> index 0000000..ad02149
>> --- /dev/null
>> +++ b/drivers/clk/davinci/clock.c
>> @@ -0,0 +1,112 @@
>> +/*
>> + * clock.c - davinci clock initialization functions for various clocks
>> + *
>> + * Copyright (C) 2006-2012 Texas Instruments.
>> + * Copyright (C) 2008-2009 Deep Root Systems, LLC
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + */
>> +#include <linux/init.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/clkdev.h>
>> +#include <linux/io.h>
>> +#include <linux/slab.h>
>> +
>> +#include "clk-pll.h"
>> +#include "clk-psc.h"
>> +#include "clk-div.h"
>> +#include "clock.h"
>> +
>> +static DEFINE_SPINLOCK(_lock);
>> +
>> +#ifdef CONFIG_CLK_DAVINCI_PLL
>> +struct clk *davinci_pll_clk(const char *name, const char *parent,
>> + u32 phys_pllm, u32 phys_prediv, u32 phys_postdiv,
>> + struct clk_pll_data *pll_data)
>> +{
>> + struct clk *clkp = NULL;
>> +
>> + pll_data->reg_pllm = ioremap(phys_pllm, 4);
>> + if (WARN_ON(!pll_data->reg_pllm))
>> + return clkp;
> I would prefer ERR_PTR(-ENOMEM) here. Same comment applies to other
> instances elsewhere in the patch.
>
>> diff --git a/drivers/clk/davinci/clock.h b/drivers/clk/davinci/clock.h
>> new file mode 100644
>> index 0000000..73204b8
>> --- /dev/null
>> +++ b/drivers/clk/davinci/clock.h
>> @@ -0,0 +1,80 @@
>> +/*
>> + * TI DaVinci Clock definitions - Contains Macros and Types used for
>> + * defining various clocks on a DaVinci SoC
>> + *
>> + * Copyright (C) 2012 Texas Instruments
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation version 2.
>> + *
>> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
>> + * kind, whether express or implied; without even the implied warranty
>> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + */
>> +#ifndef __DAVINCI_CLOCK_H
>> +#define __DAVINCI_CLOCK_H
>> +
>> +#include <linux/types.h>
>> +
>> +/* general flags: */
>> +#define ALWAYS_ENABLED BIT(0)
> This is not used in this patch. Can you add the define along with its
> usage so it is immediately clear why you need it?
This is used on the next patch as this adds a bunch of utilities or
types for the platform specific clock code. Do you want to combine this
patch with 05/11? It will become a bigger patch then? Is that fine.
IMO, this is a logical group that can be a standalone patch than
combining with 05/11.
>> +/**
>> + * struct davinci_clk - struct for defining DaVinci clocks for a SoC.
>> + *
>> + * @name: name of the clock
>> + * @parent: name of parent clock
>> + * @flags: General flags for all drivers used by platform clock init code
>> + * @data: data specific to a clock used by the driver
>> + * @dev_id: dev_id used to look up this clock. If this is NULL
>> + * clock name is used for lookup.
>> + */
>> +struct davinci_clk {
>> + const char *name;
>> + const char *parent;
>> + u32 flags;
>> + void *data;
>> + char *dev_id;
> Similarly dont see this being used as well.
For this and previous one, check lpsc_clk() macro usage. dev_id is used
where a specific device id is used to look up
the clk as is done for davinci_emac.1, davinci_mmc.0 etc.
>
> Thanks,
> Sekhar
>
On 11/03/2012 09:30 AM, Sekhar Nori wrote:
> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>> This patch adds dm644x clock initialization code that consists of
>> clocks data for various clocks and clock register callouts to
>> various clock drivers. It uses following clk drivers for this
>>
>> 1. clk-fixed-rate - for ref clock
>> 2. clk-mux - for mux at the input and output of main pll
>> 3. davinci specific clk-pll for main pll clock
>> 4. davinci specific clk-div for pll divider clock
>> 5. clk-fixed-factor for fixed factor clock such as auxclk
>> 6. davinci specific clk-psc for psc clocks
>>
>> This patch also moves all of the PLL and PSC register definitions
>> from clock.h and psc.h under davinci to the clk/davinci folder so
>> that various soc specific clock initialization code can share these
>> definitions.
> Except this patch does not move the defines, it creates a copy of them
> (which is bad since you quickly lose track of which is the correct
> copy). Is this done to avoid including mach/ header files here?
Yes.
> It will
> actually be better to include the mach/ files here as a temporary
> solution and then remove the include mach/ files once all the SoCs have
> been converted over.
I was thinking we are not allowed to include mach/* header files in
driver files. But most of the clk drivers
such clk-imx28, spear6xx_clock.c. versatile/clk-integrator.c etc are
including mach/ headers. One issue is that the definitions in pll.h are
re-usable across other machines falling under c6x and Keystone (new
device we are working on) as well. Where do we keep includes that can be
re-used across different architectures? include/linux/platform_data/ ? I
see clk-integrator.h, clk-nomadik.h and clk-u300 sitting there. So I
suggest moving any header files that defines utility functions, register
definitions across different architectures to
include/linux/platform_data. Candidate files would be clock.h, pll.h,
clk-psc.h, clk-pll.h and clk-div.h. This way these can be used across
the above machines that use the above architectures. Can we do this in
my next version? This way we don't have to make another move later. All
these CLK IPs are re-used across multiple architectures and make perfect
sense to me to move to the above folder.
>
>> Signed-off-by: Murali Karicheri <[email protected]>
>> ---
>> drivers/clk/davinci/dm644x-clock.c | 304 ++++++++++++++++++++++++++++++++++++
>> drivers/clk/davinci/pll.h | 83 ++++++++++
>> drivers/clk/davinci/psc.h | 215 +++++++++++++++++++++++++
>> 3 files changed, 602 insertions(+)
>> create mode 100644 drivers/clk/davinci/dm644x-clock.c
>> create mode 100644 drivers/clk/davinci/pll.h
>> create mode 100644 drivers/clk/davinci/psc.h
>>
>> +/* all clocks available in DM644x SoCs */
>> +enum dm644x_clk {
>> + clkin, oscin, ref_clk_mux, pll1, pll1_plldiv_clk_mux, auxclk,
>> + clk_pll1_sysclk1, clk_pll1_sysclk2, clk_pll1_sysclk3, clk_pll1_sysclk4,
>> + clk_pll1_sysclk5, clk_pll1_sysclkbp, pll2, pll2_plldiv_clk_mux,
>> + clk_pll2_sysclk1, clk_pll2_sysclk2, clk_pll2_sysclkbp, dsp, arm, vicp,
>> + vpss_master, vpss_slave, uart0, uart1, uart2, emac, i2c, ide, asp,
>> + mmcsd, spi, gpio, usb, vlynq, aemif, pwm0, pwm1, pwm2, timer0, timer1,
>> + timer2, clk_max
>> +};
>> +
>> +static struct davinci_clk *psc_clocks[] = {
>> + &clk_dsp, &clk_arm, &clk_vicp, &clk_vpss_master, &clk_vpss_slave,
>> + &clk_uart0, &clk_uart1, &clk_uart2, &clk_emac, &clk_i2c, &clk_ide,
>> + &clk_asp0, &clk_mmcsd, &clk_spi, &clk_gpio, &clk_usb, &clk_vlynq,
>> + &clk_aemif, &clk_pwm0, &clk_pwm1, &clk_pwm2, &clk_timer0, &clk_timer1,
>> + &clk_timer2
>> +};
> You rely on perfect order between this array and dm644x_clk enum above.
> Can you initialize this array using the enum as the index so that it is
> clear. Current method is too error prone.
Ok. Will do.
>
> Thanks,
> Sekhar
>
On 11/04/2012 08:06 AM, Sekhar Nori wrote:
> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>> Currently migrate only DM644x as this is being reviewed. Once all
>> platforms are migrated, the Makefile will be cleaned up to remove
>> obsoleted files clock.o and psc.o
>>
>> Signed-off-by: Murali Karicheri <[email protected]>
>> ---
>> arch/arm/Kconfig | 1 +
>> arch/arm/mach-davinci/Kconfig | 2 ++
>> arch/arm/mach-davinci/Makefile | 11 ++++++++++-
>> 3 files changed, 13 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index c5f9ae5..4611987 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -967,6 +967,7 @@ config ARCH_DAVINCI
>> select ARCH_REQUIRE_GPIOLIB
>> select ZONE_DMA
>> select HAVE_IDE
>> + select COMMON_CLK
>> select CLKDEV_LOOKUP
>> select GENERIC_ALLOCATOR
>> select GENERIC_IRQ_CHIP
> This list has to be sorted. Russell has a patch which fixed this all
> across arch/arm/* which got merged for v3.7. This patch does not apply
> to v3.7-rc3 anymore due to the same reason.
>
> Thanks,
> Sekhar
>
Ok. Will do.
On 11/04/2012 08:34 AM, Sekhar Nori wrote:
> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>> This updates clk Makefile and Kconfig to integrate the DaVinci specific
>> clock drivers. Also add new Kconfig and Makefile for these drivers.
>>
>> Signed-off-by: Murali Karicheri <[email protected]>
> As mentioned before, this should be folded into previous patches which
> actually add the particular functionality.
Yes. Agreed.,
>> ---
>> drivers/clk/Kconfig | 2 ++
>> drivers/clk/Makefile | 1 +
>> drivers/clk/davinci/Kconfig | 44 ++++++++++++++++++++++++++++++++++++++++++
>> drivers/clk/davinci/Makefile | 5 +++++
>> 4 files changed, 52 insertions(+)
>> create mode 100644 drivers/clk/davinci/Kconfig
>> create mode 100644 drivers/clk/davinci/Makefile
>>
>> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
>> index 7f0b5ca..1ad2ab0 100644
>> --- a/drivers/clk/Kconfig
>> +++ b/drivers/clk/Kconfig
>> @@ -33,6 +33,8 @@ config COMMON_CLK_DEBUG
>> clk_flags, clk_prepare_count, clk_enable_count &
>> clk_notifier_count.
>>
>> +source "drivers/clk/davinci/Kconfig"
>> +
>> config COMMON_CLK_WM831X
>> tristate "Clock driver for WM831x/2x PMICs"
>> depends on MFD_WM831X
>> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
>> index 5869ea3..b127b6f 100644
>> --- a/drivers/clk/Makefile
>> +++ b/drivers/clk/Makefile
>> @@ -10,6 +10,7 @@ obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
>> obj-$(CONFIG_PLAT_SPEAR) += spear/
>> obj-$(CONFIG_ARCH_U300) += clk-u300.o
>> obj-$(CONFIG_ARCH_INTEGRATOR) += versatile/
>> +obj-$(CONFIG_DAVINCI_CLKS) += davinci/
>>
>> # Chip specific
>> obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
>> diff --git a/drivers/clk/davinci/Kconfig b/drivers/clk/davinci/Kconfig
>> new file mode 100644
>> index 0000000..e53bbc3
>> --- /dev/null
>> +++ b/drivers/clk/davinci/Kconfig
>> @@ -0,0 +1,44 @@
>> +menu "TI DaVinci Clock drivers"
>> + depends on COMMON_CLK
>> +
>> +config CLK_DAVINCI_PSC
>> + bool "TI DaVici PSC clock driver"
>> + default n
>> + ---help---
>> + Selects clock driver for DaVinci PSC clocks. This clock
>> + hardware is found on TI DaVinci SoCs and other SoCs that
>> + uses this hardware IP. This hardware has a local power
>> + sleep control module that gate the clock to the IP.
>> +
>> +config CLK_DAVINCI_PLL
>> + bool "DaVici main PLL clock"
>> + ---help---
>> + Selects clock driver for DaVinci main PLL. This clock
>> + hardware is found on TI DaVinci SoCs. This typically has
>> + a multiplier, a pre divider and post driver. Some of the
>> + SoCs has the the dividers fixed, and others have it
>> + programmable
>> +
>> +config CLK_DAVINCI_PLLDIV
>> + bool "DaVici PLL divider clock"
>> + ---help---
>> + Selects clock driver for DaVinci PLL divider. This clock
>> + hardware is found on TI DaVinci SoCs. This typically has
>> + a divider and an enable bit to bypass or enable the
>> + divider.
>> +
>> +config DAVINCI_CLKS
>> + bool "TI DaVinci common clocks"
>> + default n
>> + select CLK_DAVINCI_PSC
>> + select CLK_DAVINCI_PLLDIV
>> + ---help---
>> + Selects common clock drivers for DaVinci. These clocks
>> + are re-used across many TI SoCs that are based on DaVinci and
>> + Keystone (c6x) families. This config option is used to select
>> + the common clock driver for DaVinci based SoCs. SoCs specific
>> + Kconfig option needs to select the driver for clocks specific
>> + to the SoC.
>> +
>> +endmenu
> I wonder if all these configurations are really required. For complete
> clock functionality you anyway require all this functionality so I
> wonder why anyone would not select any of these. And to differentiate
> between architecture changes, conditional build based on architecture
> can be used:
I know this is a grey area I need to improve and had a discussion with
Mike sometime back. Are you also suggesting including davinci folder
unconditionally under drivers/clk/Makefile? I think it will work. And
then in clk/davinci/Makefile we can include on a per architecture basis.
But I am not sure if calling the folder as davinci make sense and these
drivers are used on non DaVinci architectures as well. I had initially
named it as "ti" to include all ti drivers. But Mike had commented that
current directory structure use platform/arch name instead of vendor
name. Also OMAP is going to move the clk drivers to this folder soon. So
for now, davinci may be used to house all of the non OMAP drivers. Later
we can re-visit this as needed (wouldn't be that hard to do this within
the clk driver folder later). We can keep the davinci folder name and
unconditionally include it in clk/Makefile.
clk/Makefile
add
obj-y += davinci/
clk/davinci/Makefile
obj-$(CONFIG_ARCH_DAVINCI) += clk-pll.o clk-div.o clk-psc.o clock.o
obj-$(CONFIG_ARCH_KEYSTONE) += clk-pll-keystone.o clk-div.o clk-psc.o clock.o
obj-$(CONFIG_ARCH_DAVINCI_DM644x) += clk-dm644x.o
obj-$(CONFIG_ARCH_DAVINCI_DM355) += clk-dm355.o
This way I can remove these config options. Are you okay with this?
>
> obj-$(CONFIG_ARCH_DAVINCI) += clk-pll.o
> obj-$(CONFIG_ARCH_KEYSTONE) += clk-pll-keystone.o
>
> Thanks,
> Sekhar
>
On 11/04/2012 09:05 AM, Sekhar Nori wrote:
>
> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>> pll.h is added to migrate some of the PLL controller defines for sleep.S.
>> psc.h is modified to keep only PSC modules definitions needed by sleep.S
>> after migrating to common clock. The definitions under
>> ifdef CONFIG_COMMON_CLK will be removed in a subsequent patch.
>> davinci_watchdog_reset prototype is moved to time.h as clock.h is
>> being obsoleted. sleep.S and pm.c is modified to include the new header
>> file replacements.
>>
>> Signed-off-by: Murali Karicheri <[email protected]>
>> ---
>> arch/arm/mach-davinci/devices.c | 2 ++
>> arch/arm/mach-davinci/include/mach/pll.h | 46 +++++++++++++++++++++++++++++
>> arch/arm/mach-davinci/include/mach/psc.h | 4 +++
>> arch/arm/mach-davinci/include/mach/time.h | 4 ++-
>> arch/arm/mach-davinci/pm.c | 4 +++
>> arch/arm/mach-davinci/sleep.S | 4 +++
>> 6 files changed, 63 insertions(+), 1 deletion(-)
>> create mode 100644 arch/arm/mach-davinci/include/mach/pll.h
> With this patch a _third_ copy of PLL definitions is created in kernel
> sources. The existing PLL definitions in clock.h inside mach-davinci
> should be moved to mach/pll.h and the pll.h you introduced inside
> drivers/clk in 5/11 should be removed (this patch should appear before
> 5/11).
>
> The biggest disadvantage of this approach is inclusion of mach/ includes
> in drivers/clk. But duplicating code is definitely not the fix for this.
> Anyway, mach/ includes are not uncommon in drivers/clk (they are all
> probably suffering from the same issue).
Sekhar,
I have replied to patch 5/11 that also refers to this. The main reason
we are not able to do this cleanly is the code in sleep.c and pm.c. That
is something related to Power management. Could you take a look and see
if you can do some clean up on this code? I believe It is more than just
moving the header files.
Murali
>
> $ grep -rl "include <mach/" drivers/clk/*
> drivers/clk/clk-u300.c
> drivers/clk/mmp/clk-pxa168.c
> drivers/clk/mmp/clk-mmp2.c
> drivers/clk/mmp/clk-pxa910.c
> drivers/clk/mxs/clk-imx23.c
> drivers/clk/mxs/clk-imx28.c
> drivers/clk/spear/spear6xx_clock.c
> drivers/clk/spear/spear3xx_clock.c
> drivers/clk/spear/spear1340_clock.c
> drivers/clk/spear/spear1310_clock.c
> drivers/clk/ux500/clk-prcc.c
> drivers/clk/versatile/clk-integrator.c
> drivers/clk/versatile/clk-realview.c
>
> pll.h can probably be moved to include/linux/clk/ to avoid this. Would
> like to hear from Mike on this before going ahead.
>
> Anyway, instead of just commenting, I though I will be more useful and
> went ahead and made some of the changes I have been talking about. I
> fixed the multiple PLL definitions issue, the build infrastructure issue
> and the commit ordering too.
>
> I pushed the patches I fixed to devel-common-clk branch of my git tree.
> It is build tested using davinci_all_defconfig but its not runtime tested.
>
> Can you start from here and provide me incremental changes on top of
> this? That way we can collaborate to finish this faster.
Thanks for offering some help. Yes I can provide you incremental patch.
But then could you also help me to squash/rebase and send patches to the
list for review?
> Thanks,
> Sekhar
>
On 11/04/2012 09:05 AM, Sekhar Nori wrote:
>
> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>> pll.h is added to migrate some of the PLL controller defines for sleep.S.
>> psc.h is modified to keep only PSC modules definitions needed by sleep.S
>> after migrating to common clock. The definitions under
>> ifdef CONFIG_COMMON_CLK will be removed in a subsequent patch.
>> davinci_watchdog_reset prototype is moved to time.h as clock.h is
>> being obsoleted. sleep.S and pm.c is modified to include the new header
>> file replacements.
>>
>> Signed-off-by: Murali Karicheri <[email protected]>
>> ---
>> arch/arm/mach-davinci/devices.c | 2 ++
>> arch/arm/mach-davinci/include/mach/pll.h | 46 +++++++++++++++++++++++++++++
>> arch/arm/mach-davinci/include/mach/psc.h | 4 +++
>> arch/arm/mach-davinci/include/mach/time.h | 4 ++-
>> arch/arm/mach-davinci/pm.c | 4 +++
>> arch/arm/mach-davinci/sleep.S | 4 +++
>> 6 files changed, 63 insertions(+), 1 deletion(-)
>> create mode 100644 arch/arm/mach-davinci/include/mach/pll.h
> With this patch a _third_ copy of PLL definitions is created in kernel
> sources. The existing PLL definitions in clock.h inside mach-davinci
> should be moved to mach/pll.h and the pll.h you introduced inside
> drivers/clk in 5/11 should be removed (this patch should appear before
> 5/11).
>
> The biggest disadvantage of this approach is inclusion of mach/ includes
> in drivers/clk. But duplicating code is definitely not the fix for this.
> Anyway, mach/ includes are not uncommon in drivers/clk (they are all
> probably suffering from the same issue).
>
> $ grep -rl "include <mach/" drivers/clk/*
> drivers/clk/clk-u300.c
> drivers/clk/mmp/clk-pxa168.c
> drivers/clk/mmp/clk-mmp2.c
> drivers/clk/mmp/clk-pxa910.c
> drivers/clk/mxs/clk-imx23.c
> drivers/clk/mxs/clk-imx28.c
> drivers/clk/spear/spear6xx_clock.c
> drivers/clk/spear/spear3xx_clock.c
> drivers/clk/spear/spear1340_clock.c
> drivers/clk/spear/spear1310_clock.c
> drivers/clk/ux500/clk-prcc.c
> drivers/clk/versatile/clk-integrator.c
> drivers/clk/versatile/clk-realview.c
>
> pll.h can probably be moved to include/linux/clk/ to avoid this. Would
> like to hear from Mike on this before going ahead.
>
> Anyway, instead of just commenting, I though I will be more useful and
> went ahead and made some of the changes I have been talking about. I
> fixed the multiple PLL definitions issue, the build infrastructure issue
> and the commit ordering too.
>
> I pushed the patches I fixed to devel-common-clk branch of my git tree.
> It is build tested using davinci_all_defconfig but its not runtime tested.
>
> Can you start from here and provide me incremental changes on top of
> this? That way we can collaborate to finish this faster.
>
> Thanks,
> Sekhar
>
I made a build from your branch and it doesn't boot up DM6446. I will
debug this tomorrow. But what should I focus on? I thought it is a
header file re-arrangement?
Murali
On 11/03/2012 09:30 AM, Sekhar Nori wrote:
> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>> This patch adds dm644x clock initialization code that consists of
>> clocks data for various clocks and clock register callouts to
>> various clock drivers. It uses following clk drivers for this
>>
>> 1. clk-fixed-rate - for ref clock
>> 2. clk-mux - for mux at the input and output of main pll
>> 3. davinci specific clk-pll for main pll clock
>> 4. davinci specific clk-div for pll divider clock
>> 5. clk-fixed-factor for fixed factor clock such as auxclk
>> 6. davinci specific clk-psc for psc clocks
>>
>> This patch also moves all of the PLL and PSC register definitions
>> from clock.h and psc.h under davinci to the clk/davinci folder so
>> that various soc specific clock initialization code can share these
>> definitions.
> Except this patch does not move the defines, it creates a copy of them
> (which is bad since you quickly lose track of which is the correct
> copy). Is this done to avoid including mach/ header files here? It will
> actually be better to include the mach/ files here as a temporary
> solution and then remove the include mach/ files once all the SoCs have
> been converted over.
>
>> Signed-off-by: Murali Karicheri <[email protected]>
>> ---
>> drivers/clk/davinci/dm644x-clock.c | 304 ++++++++++++++++++++++++++++++++++++
>> drivers/clk/davinci/pll.h | 83 ++++++++++
>> drivers/clk/davinci/psc.h | 215 +++++++++++++++++++++++++
>> 3 files changed, 602 insertions(+)
>> create mode 100644 drivers/clk/davinci/dm644x-clock.c
>> create mode 100644 drivers/clk/davinci/pll.h
>> create mode 100644 drivers/clk/davinci/psc.h
>>
>> +/* all clocks available in DM644x SoCs */
>> +enum dm644x_clk {
>> + clkin, oscin, ref_clk_mux, pll1, pll1_plldiv_clk_mux, auxclk,
>> + clk_pll1_sysclk1, clk_pll1_sysclk2, clk_pll1_sysclk3, clk_pll1_sysclk4,
>> + clk_pll1_sysclk5, clk_pll1_sysclkbp, pll2, pll2_plldiv_clk_mux,
>> + clk_pll2_sysclk1, clk_pll2_sysclk2, clk_pll2_sysclkbp, dsp, arm, vicp,
>> + vpss_master, vpss_slave, uart0, uart1, uart2, emac, i2c, ide, asp,
>> + mmcsd, spi, gpio, usb, vlynq, aemif, pwm0, pwm1, pwm2, timer0, timer1,
>> + timer2, clk_max
>> +};
>> +
>> +static struct davinci_clk *psc_clocks[] = {
>> + &clk_dsp, &clk_arm, &clk_vicp, &clk_vpss_master, &clk_vpss_slave,
>> + &clk_uart0, &clk_uart1, &clk_uart2, &clk_emac, &clk_i2c, &clk_ide,
>> + &clk_asp0, &clk_mmcsd, &clk_spi, &clk_gpio, &clk_usb, &clk_vlynq,
>> + &clk_aemif, &clk_pwm0, &clk_pwm1, &clk_pwm2, &clk_timer0, &clk_timer1,
>> + &clk_timer2
>> +};
> You rely on perfect order between this array and dm644x_clk enum above.
> Can you initialize this array using the enum as the index so that it is
> clear. Current method is too error prone.
Are you expecting something like this?
static struct davinci_clk *psc_clocks[] = {
[dsp - dsp] = &clk_dsp,
[arm - dsp] = &clk_arm,
[vicp - dsp] = &clk_vicp,
[vpss_maste - dsp] = &clk_vpss_master,
[vpss_slave - dsp] = &clk_vpss_slave,
[uart0 - dsp] = &clk_uart0,
[uart1 - dsp] = &clk_uart1,
Murali
>
> Thanks,
> Sekhar
>
On 11/5/2012 8:50 PM, Murali Karicheri wrote:
> On 11/03/2012 08:35 AM, Sekhar Nori wrote:
>> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>>> This is the common clk driver initialization functions for DaVinci
>>> SoCs and other SoCs that uses similar hardware architecture.
>>> clock.h also defines struct types for clock definitions in a SoC
>>> and clock data type for configuring clk-mux. The initialization
>>> functions are used by clock initialization code in a specific
>>> platform/SoC.
>>>
>>> Signed-off-by: Murali Karicheri <[email protected]>
>>> ---
>>> drivers/clk/davinci/clock.c | 112
>>> +++++++++++++++++++++++++++++++++++++++++++
>>> drivers/clk/davinci/clock.h | 80 +++++++++++++++++++++++++++++++
>>> 2 files changed, 192 insertions(+)
>>> create mode 100644 drivers/clk/davinci/clock.c
>>> create mode 100644 drivers/clk/davinci/clock.h
>>>
>>> diff --git a/drivers/clk/davinci/clock.c b/drivers/clk/davinci/clock.c
>>> new file mode 100644
>>> index 0000000..ad02149
>>> --- /dev/null
>>> +++ b/drivers/clk/davinci/clock.c
>>> @@ -0,0 +1,112 @@
>>> +/*
>>> + * clock.c - davinci clock initialization functions for various clocks
>>> + *
>>> + * Copyright (C) 2006-2012 Texas Instruments.
>>> + * Copyright (C) 2008-2009 Deep Root Systems, LLC
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License as published by
>>> + * the Free Software Foundation; either version 2 of the License, or
>>> + * (at your option) any later version.
>>> + */
>>> +#include <linux/init.h>
>>> +#include <linux/clk-provider.h>
>>> +#include <linux/clkdev.h>
>>> +#include <linux/io.h>
>>> +#include <linux/slab.h>
>>> +
>>> +#include "clk-pll.h"
>>> +#include "clk-psc.h"
>>> +#include "clk-div.h"
>>> +#include "clock.h"
>>> +
>>> +static DEFINE_SPINLOCK(_lock);
>>> +
>>> +#ifdef CONFIG_CLK_DAVINCI_PLL
>>> +struct clk *davinci_pll_clk(const char *name, const char *parent,
>>> + u32 phys_pllm, u32 phys_prediv, u32 phys_postdiv,
>>> + struct clk_pll_data *pll_data)
>>> +{
>>> + struct clk *clkp = NULL;
>>> +
>>> + pll_data->reg_pllm = ioremap(phys_pllm, 4);
>>> + if (WARN_ON(!pll_data->reg_pllm))
>>> + return clkp;
>> I would prefer ERR_PTR(-ENOMEM) here. Same comment applies to other
>> instances elsewhere in the patch.
>>
>>> diff --git a/drivers/clk/davinci/clock.h b/drivers/clk/davinci/clock.h
>>> new file mode 100644
>>> index 0000000..73204b8
>>> --- /dev/null
>>> +++ b/drivers/clk/davinci/clock.h
>>> @@ -0,0 +1,80 @@
>>> +/*
>>> + * TI DaVinci Clock definitions - Contains Macros and Types used for
>>> + * defining various clocks on a DaVinci SoC
>>> + *
>>> + * Copyright (C) 2012 Texas Instruments
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU General Public License as
>>> + * published by the Free Software Foundation version 2.
>>> + *
>>> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
>>> + * kind, whether express or implied; without even the implied warranty
>>> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>>> + * GNU General Public License for more details.
>>> + */
>>> +#ifndef __DAVINCI_CLOCK_H
>>> +#define __DAVINCI_CLOCK_H
>>> +
>>> +#include <linux/types.h>
>>> +
>>> +/* general flags: */
>>> +#define ALWAYS_ENABLED BIT(0)
>> This is not used in this patch. Can you add the define along with its
>> usage so it is immediately clear why you need it?
> This is used on the next patch as this adds a bunch of utilities or
> types for the platform specific clock code. Do you want to combine this
> patch with 05/11? It will become a bigger patch then? Is that fine.
> IMO, this is a logical group that can be a standalone patch than
> combining with 05/11.
It is more important to divide patches in logical functional blocks
rather than split it based on files. Reading this patch, I have no idea
what that define is for.
Thanks,
Sekhar
On 11/6/2012 4:53 AM, Murali Karicheri wrote:
> On 11/03/2012 09:30 AM, Sekhar Nori wrote:
>> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>>> This patch adds dm644x clock initialization code that consists of
>>> clocks data for various clocks and clock register callouts to
>>> various clock drivers. It uses following clk drivers for this
>>>
>>> 1. clk-fixed-rate - for ref clock
>>> 2. clk-mux - for mux at the input and output of main pll
>>> 3. davinci specific clk-pll for main pll clock
>>> 4. davinci specific clk-div for pll divider clock
>>> 5. clk-fixed-factor for fixed factor clock such as auxclk
>>> 6. davinci specific clk-psc for psc clocks
>>>
>>> This patch also moves all of the PLL and PSC register definitions
>>> from clock.h and psc.h under davinci to the clk/davinci folder so
>>> that various soc specific clock initialization code can share these
>>> definitions.
>> Except this patch does not move the defines, it creates a copy of them
>> (which is bad since you quickly lose track of which is the correct
>> copy). Is this done to avoid including mach/ header files here? It will
>> actually be better to include the mach/ files here as a temporary
>> solution and then remove the include mach/ files once all the SoCs have
>> been converted over.
>>
>>> Signed-off-by: Murali Karicheri <[email protected]>
>>> ---
>>> drivers/clk/davinci/dm644x-clock.c | 304
>>> ++++++++++++++++++++++++++++++++++++
>>> drivers/clk/davinci/pll.h | 83 ++++++++++
>>> drivers/clk/davinci/psc.h | 215 +++++++++++++++++++++++++
>>> 3 files changed, 602 insertions(+)
>>> create mode 100644 drivers/clk/davinci/dm644x-clock.c
>>> create mode 100644 drivers/clk/davinci/pll.h
>>> create mode 100644 drivers/clk/davinci/psc.h
>>>
>>> +/* all clocks available in DM644x SoCs */
>>> +enum dm644x_clk {
>>> + clkin, oscin, ref_clk_mux, pll1, pll1_plldiv_clk_mux, auxclk,
>>> + clk_pll1_sysclk1, clk_pll1_sysclk2, clk_pll1_sysclk3,
>>> clk_pll1_sysclk4,
>>> + clk_pll1_sysclk5, clk_pll1_sysclkbp, pll2, pll2_plldiv_clk_mux,
>>> + clk_pll2_sysclk1, clk_pll2_sysclk2, clk_pll2_sysclkbp, dsp, arm,
>>> vicp,
>>> + vpss_master, vpss_slave, uart0, uart1, uart2, emac, i2c, ide, asp,
>>> + mmcsd, spi, gpio, usb, vlynq, aemif, pwm0, pwm1, pwm2, timer0,
>>> timer1,
>>> + timer2, clk_max
>>> +};
>>> +
>>> +static struct davinci_clk *psc_clocks[] = {
>>> + &clk_dsp, &clk_arm, &clk_vicp, &clk_vpss_master, &clk_vpss_slave,
>>> + &clk_uart0, &clk_uart1, &clk_uart2, &clk_emac, &clk_i2c, &clk_ide,
>>> + &clk_asp0, &clk_mmcsd, &clk_spi, &clk_gpio, &clk_usb, &clk_vlynq,
>>> + &clk_aemif, &clk_pwm0, &clk_pwm1, &clk_pwm2, &clk_timer0,
>>> &clk_timer1,
>>> + &clk_timer2
>>> +};
>> You rely on perfect order between this array and dm644x_clk enum above.
>> Can you initialize this array using the enum as the index so that it is
>> clear. Current method is too error prone.
> Are you expecting something like this?
>
> static struct davinci_clk *psc_clocks[] = {
> [dsp - dsp] = &clk_dsp,
> [arm - dsp] = &clk_arm,
> [vicp - dsp] = &clk_vicp,
> [vpss_maste - dsp] = &clk_vpss_master,
> [vpss_slave - dsp] = &clk_vpss_slave,
> [uart0 - dsp] = &clk_uart0,
> [uart1 - dsp] = &clk_uart1,
Well, sort of! But the '- dsp' is really ugly. You can either define the
array for the full list of clocks (like 'clks') or move the psc clocks
to the beginning of the enum (less preferable to me).
Thanks,
Sekhar
On 11/5/2012 9:47 PM, Murali Karicheri wrote:
> On 11/04/2012 08:34 AM, Sekhar Nori wrote:
>> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>>> This updates clk Makefile and Kconfig to integrate the DaVinci specific
>>> clock drivers. Also add new Kconfig and Makefile for these drivers.
>>>
>>> Signed-off-by: Murali Karicheri <[email protected]>
>> As mentioned before, this should be folded into previous patches which
>> actually add the particular functionality.
> Yes. Agreed.,
>>> ---
>>> drivers/clk/Kconfig | 2 ++
>>> drivers/clk/Makefile | 1 +
>>> drivers/clk/davinci/Kconfig | 44
>>> ++++++++++++++++++++++++++++++++++++++++++
>>> drivers/clk/davinci/Makefile | 5 +++++
>>> 4 files changed, 52 insertions(+)
>>> create mode 100644 drivers/clk/davinci/Kconfig
>>> create mode 100644 drivers/clk/davinci/Makefile
>>>
>>> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
>>> index 7f0b5ca..1ad2ab0 100644
>>> --- a/drivers/clk/Kconfig
>>> +++ b/drivers/clk/Kconfig
>>> @@ -33,6 +33,8 @@ config COMMON_CLK_DEBUG
>>> clk_flags, clk_prepare_count, clk_enable_count &
>>> clk_notifier_count.
>>> +source "drivers/clk/davinci/Kconfig"
>>> +
>>> config COMMON_CLK_WM831X
>>> tristate "Clock driver for WM831x/2x PMICs"
>>> depends on MFD_WM831X
>>> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
>>> index 5869ea3..b127b6f 100644
>>> --- a/drivers/clk/Makefile
>>> +++ b/drivers/clk/Makefile
>>> @@ -10,6 +10,7 @@ obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
>>> obj-$(CONFIG_PLAT_SPEAR) += spear/
>>> obj-$(CONFIG_ARCH_U300) += clk-u300.o
>>> obj-$(CONFIG_ARCH_INTEGRATOR) += versatile/
>>> +obj-$(CONFIG_DAVINCI_CLKS) += davinci/
>>> # Chip specific
>>> obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
>>> diff --git a/drivers/clk/davinci/Kconfig b/drivers/clk/davinci/Kconfig
>>> new file mode 100644
>>> index 0000000..e53bbc3
>>> --- /dev/null
>>> +++ b/drivers/clk/davinci/Kconfig
>>> @@ -0,0 +1,44 @@
>>> +menu "TI DaVinci Clock drivers"
>>> + depends on COMMON_CLK
>>> +
>>> +config CLK_DAVINCI_PSC
>>> + bool "TI DaVici PSC clock driver"
>>> + default n
>>> + ---help---
>>> + Selects clock driver for DaVinci PSC clocks. This clock
>>> + hardware is found on TI DaVinci SoCs and other SoCs that
>>> + uses this hardware IP. This hardware has a local power
>>> + sleep control module that gate the clock to the IP.
>>> +
>>> +config CLK_DAVINCI_PLL
>>> + bool "DaVici main PLL clock"
>>> + ---help---
>>> + Selects clock driver for DaVinci main PLL. This clock
>>> + hardware is found on TI DaVinci SoCs. This typically has
>>> + a multiplier, a pre divider and post driver. Some of the
>>> + SoCs has the the dividers fixed, and others have it
>>> + programmable
>>> +
>>> +config CLK_DAVINCI_PLLDIV
>>> + bool "DaVici PLL divider clock"
>>> + ---help---
>>> + Selects clock driver for DaVinci PLL divider. This clock
>>> + hardware is found on TI DaVinci SoCs. This typically has
>>> + a divider and an enable bit to bypass or enable the
>>> + divider.
>>> +
>>> +config DAVINCI_CLKS
>>> + bool "TI DaVinci common clocks"
>>> + default n
>>> + select CLK_DAVINCI_PSC
>>> + select CLK_DAVINCI_PLLDIV
>>> + ---help---
>>> + Selects common clock drivers for DaVinci. These clocks
>>> + are re-used across many TI SoCs that are based on DaVinci and
>>> + Keystone (c6x) families. This config option is used to select
>>> + the common clock driver for DaVinci based SoCs. SoCs specific
>>> + Kconfig option needs to select the driver for clocks specific
>>> + to the SoC.
>>> +
>>> +endmenu
>> I wonder if all these configurations are really required. For complete
>> clock functionality you anyway require all this functionality so I
>> wonder why anyone would not select any of these. And to differentiate
>> between architecture changes, conditional build based on architecture
>> can be used:
> I know this is a grey area I need to improve and had a discussion with
> Mike sometime back. Are you also suggesting including davinci folder
> unconditionally under drivers/clk/Makefile? I think it will work. And
> then in clk/davinci/Makefile we can include on a per architecture basis.
> But I am not sure if calling the folder as davinci make sense and these
> drivers are used on non DaVinci architectures as well. I had initially
> named it as "ti" to include all ti drivers. But Mike had commented that
> current directory structure use platform/arch name instead of vendor
> name. Also OMAP is going to move the clk drivers to this folder soon. So
> for now, davinci may be used to house all of the non OMAP drivers. Later
> we can re-visit this as needed (wouldn't be that hard to do this within
> the clk driver folder later). We can keep the davinci folder name and
> unconditionally include it in clk/Makefile.
>
> clk/Makefile
>
> add
> obj-y += davinci/
I am not sure about this unconditional inclusion. Are you sure the
following will create problems when DaVinci and keystone are enabled
together?
obj-$(CONFIG_ARCH_DAVINCI) += davinci/
obj-$(CONFIG_ARCH_KEYSTONE) += davinci/
>
> clk/davinci/Makefile
>
> obj-$(CONFIG_ARCH_DAVINCI) += clk-pll.o clk-div.o clk-psc.o clock.o
> obj-$(CONFIG_ARCH_KEYSTONE) += clk-pll-keystone.o clk-div.o clk-psc.o
> clock.o
Rather
obj-y := clk-div.o clk-psc.o clock.o
obj-$(CONFIG_ARCH_DAVINCI) += clk-pll.o
obj-$(CONFIG_ARCH_KEYSTONE) += clk-pll-keystone.o
Thanks,
Sekhar
On 11/6/2012 12:41 AM, Murali Karicheri wrote:
> On 11/04/2012 09:05 AM, Sekhar Nori wrote:
>>
>> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>>> pll.h is added to migrate some of the PLL controller defines for
>>> sleep.S.
>>> psc.h is modified to keep only PSC modules definitions needed by sleep.S
>>> after migrating to common clock. The definitions under
>>> ifdef CONFIG_COMMON_CLK will be removed in a subsequent patch.
>>> davinci_watchdog_reset prototype is moved to time.h as clock.h is
>>> being obsoleted. sleep.S and pm.c is modified to include the new header
>>> file replacements.
>>>
>>> Signed-off-by: Murali Karicheri <[email protected]>
>>> ---
>>> arch/arm/mach-davinci/devices.c | 2 ++
>>> arch/arm/mach-davinci/include/mach/pll.h | 46
>>> +++++++++++++++++++++++++++++
>>> arch/arm/mach-davinci/include/mach/psc.h | 4 +++
>>> arch/arm/mach-davinci/include/mach/time.h | 4 ++-
>>> arch/arm/mach-davinci/pm.c | 4 +++
>>> arch/arm/mach-davinci/sleep.S | 4 +++
>>> 6 files changed, 63 insertions(+), 1 deletion(-)
>>> create mode 100644 arch/arm/mach-davinci/include/mach/pll.h
>> With this patch a _third_ copy of PLL definitions is created in kernel
>> sources. The existing PLL definitions in clock.h inside mach-davinci
>> should be moved to mach/pll.h and the pll.h you introduced inside
>> drivers/clk in 5/11 should be removed (this patch should appear before
>> 5/11).
>>
>> The biggest disadvantage of this approach is inclusion of mach/ includes
>> in drivers/clk. But duplicating code is definitely not the fix for this.
>> Anyway, mach/ includes are not uncommon in drivers/clk (they are all
>> probably suffering from the same issue).
> Sekhar,
>
> I have replied to patch 5/11 that also refers to this. The main reason
> we are not able to do this cleanly is the code in sleep.c and pm.c. That
> is something related to Power management. Could you take a look and see
> if you can do some clean up on this code? I believe It is more than just
> moving the header files.
I am not sure what more is required than moving header files? Can you
elaborate?
>
> Murali
>>
>> $ grep -rl "include <mach/" drivers/clk/*
>> drivers/clk/clk-u300.c
>> drivers/clk/mmp/clk-pxa168.c
>> drivers/clk/mmp/clk-mmp2.c
>> drivers/clk/mmp/clk-pxa910.c
>> drivers/clk/mxs/clk-imx23.c
>> drivers/clk/mxs/clk-imx28.c
>> drivers/clk/spear/spear6xx_clock.c
>> drivers/clk/spear/spear3xx_clock.c
>> drivers/clk/spear/spear1340_clock.c
>> drivers/clk/spear/spear1310_clock.c
>> drivers/clk/ux500/clk-prcc.c
>> drivers/clk/versatile/clk-integrator.c
>> drivers/clk/versatile/clk-realview.c
>>
>> pll.h can probably be moved to include/linux/clk/ to avoid this. Would
>> like to hear from Mike on this before going ahead.
>>
>> Anyway, instead of just commenting, I though I will be more useful and
>> went ahead and made some of the changes I have been talking about. I
>> fixed the multiple PLL definitions issue, the build infrastructure issue
>> and the commit ordering too.
>>
>> I pushed the patches I fixed to devel-common-clk branch of my git tree.
>> It is build tested using davinci_all_defconfig but its not runtime
>> tested.
>>
>> Can you start from here and provide me incremental changes on top of
>> this? That way we can collaborate to finish this faster.
> Thanks for offering some help. Yes I can provide you incremental patch.
> But then could you also help me to squash/rebase and send patches to the
> list for review?
No, no. I want you to own the submissions. Towards this, if it is easier
for you to build upon my work in your own tree, by all means, go ahead
and do it. Just share the branch/tree details so I can take a look and
contribute as well.
Thanks,
Sekhar
On 11/5/2012 9:12 PM, Murali Karicheri wrote:
> On 11/03/2012 09:30 AM, Sekhar Nori wrote:
>> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>>> This patch adds dm644x clock initialization code that consists of
>>> clocks data for various clocks and clock register callouts to
>>> various clock drivers. It uses following clk drivers for this
>>>
>>> 1. clk-fixed-rate - for ref clock
>>> 2. clk-mux - for mux at the input and output of main pll
>>> 3. davinci specific clk-pll for main pll clock
>>> 4. davinci specific clk-div for pll divider clock
>>> 5. clk-fixed-factor for fixed factor clock such as auxclk
>>> 6. davinci specific clk-psc for psc clocks
>>>
>>> This patch also moves all of the PLL and PSC register definitions
>>> from clock.h and psc.h under davinci to the clk/davinci folder so
>>> that various soc specific clock initialization code can share these
>>> definitions.
>> Except this patch does not move the defines, it creates a copy of them
>> (which is bad since you quickly lose track of which is the correct
>> copy). Is this done to avoid including mach/ header files here?
> Yes.
>> It will
>> actually be better to include the mach/ files here as a temporary
>> solution and then remove the include mach/ files once all the SoCs have
>> been converted over.
>
> I was thinking we are not allowed to include mach/* header files in
> driver files. But most of the clk drivers
> such clk-imx28, spear6xx_clock.c. versatile/clk-integrator.c etc are
> including mach/ headers. One issue is that the definitions in pll.h are
> re-usable across other machines falling under c6x and Keystone (new
> device we are working on) as well. Where do we keep includes that can be
> re-used across different architectures? include/linux/platform_data/ ?
In this case, it is not really platform data or even an interface for
drivers to use, so I prefer include/linux/clk/davinci-pll.h
> I
> see clk-integrator.h, clk-nomadik.h and clk-u300 sitting there. So I
> suggest moving any header files that defines utility functions, register
> definitions across different architectures to
> include/linux/platform_data. Candidate files would be clock.h, pll.h,
> clk-psc.h, clk-pll.h and clk-div.h. This way these can be used across
It is not clear to me why you would move these files outside of
drivers/clk/davinci. They are not used by any other code outside of this
directory.
> the above machines that use the above architectures. Can we do this in
> my next version? This way we don't have to make another move later. All
> these CLK IPs are re-used across multiple architectures and make perfect
> sense to me to move to the above folder.
Thanks,
Sekhar
On 11/06/2012 04:31 AM, Sekhar Nori wrote:
>
> On 11/5/2012 8:50 PM, Murali Karicheri wrote:
>> On 11/03/2012 08:35 AM, Sekhar Nori wrote:
>>> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>>>> This is the common clk driver initialization functions for DaVinci
>>>> SoCs and other SoCs that uses similar hardware architecture.
>>>> clock.h also defines struct types for clock definitions in a SoC
>>>> and clock data type for configuring clk-mux. The initialization
>>>> functions are used by clock initialization code in a specific
>>>> platform/SoC.
>>>>
>>>> Signed-off-by: Murali Karicheri <[email protected]>
>>>> ---
>>>> drivers/clk/davinci/clock.c | 112
>>>> +++++++++++++++++++++++++++++++++++++++++++
>>>> drivers/clk/davinci/clock.h | 80 +++++++++++++++++++++++++++++++
>>>> 2 files changed, 192 insertions(+)
>>>> create mode 100644 drivers/clk/davinci/clock.c
>>>> create mode 100644 drivers/clk/davinci/clock.h
>>>>
>>>> diff --git a/drivers/clk/davinci/clock.c b/drivers/clk/davinci/clock.c
>>>> new file mode 100644
>>>> index 0000000..ad02149
>>>> --- /dev/null
>>>> +++ b/drivers/clk/davinci/clock.c
>>>> @@ -0,0 +1,112 @@
>>>> +/*
>>>> + * clock.c - davinci clock initialization functions for various clocks
>>>> + *
>>>> + * Copyright (C) 2006-2012 Texas Instruments.
>>>> + * Copyright (C) 2008-2009 Deep Root Systems, LLC
>>>> + *
>>>> + * This program is free software; you can redistribute it and/or modify
>>>> + * it under the terms of the GNU General Public License as published by
>>>> + * the Free Software Foundation; either version 2 of the License, or
>>>> + * (at your option) any later version.
>>>> + */
>>>> +#include <linux/init.h>
>>>> +#include <linux/clk-provider.h>
>>>> +#include <linux/clkdev.h>
>>>> +#include <linux/io.h>
>>>> +#include <linux/slab.h>
>>>> +
>>>> +#include "clk-pll.h"
>>>> +#include "clk-psc.h"
>>>> +#include "clk-div.h"
>>>> +#include "clock.h"
>>>> +
>>>> +static DEFINE_SPINLOCK(_lock);
>>>> +
>>>> +#ifdef CONFIG_CLK_DAVINCI_PLL
>>>> +struct clk *davinci_pll_clk(const char *name, const char *parent,
>>>> + u32 phys_pllm, u32 phys_prediv, u32 phys_postdiv,
>>>> + struct clk_pll_data *pll_data)
>>>> +{
>>>> + struct clk *clkp = NULL;
>>>> +
>>>> + pll_data->reg_pllm = ioremap(phys_pllm, 4);
>>>> + if (WARN_ON(!pll_data->reg_pllm))
>>>> + return clkp;
>>> I would prefer ERR_PTR(-ENOMEM) here. Same comment applies to other
>>> instances elsewhere in the patch.
>>>
>>>> diff --git a/drivers/clk/davinci/clock.h b/drivers/clk/davinci/clock.h
>>>> new file mode 100644
>>>> index 0000000..73204b8
>>>> --- /dev/null
>>>> +++ b/drivers/clk/davinci/clock.h
>>>> @@ -0,0 +1,80 @@
>>>> +/*
>>>> + * TI DaVinci Clock definitions - Contains Macros and Types used for
>>>> + * defining various clocks on a DaVinci SoC
>>>> + *
>>>> + * Copyright (C) 2012 Texas Instruments
>>>> + *
>>>> + * This program is free software; you can redistribute it and/or
>>>> + * modify it under the terms of the GNU General Public License as
>>>> + * published by the Free Software Foundation version 2.
>>>> + *
>>>> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
>>>> + * kind, whether express or implied; without even the implied warranty
>>>> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>>>> + * GNU General Public License for more details.
>>>> + */
>>>> +#ifndef __DAVINCI_CLOCK_H
>>>> +#define __DAVINCI_CLOCK_H
>>>> +
>>>> +#include <linux/types.h>
>>>> +
>>>> +/* general flags: */
>>>> +#define ALWAYS_ENABLED BIT(0)
>>> This is not used in this patch. Can you add the define along with its
>>> usage so it is immediately clear why you need it?
>> This is used on the next patch as this adds a bunch of utilities or
>> types for the platform specific clock code. Do you want to combine this
>> patch with 05/11? It will become a bigger patch then? Is that fine.
>> IMO, this is a logical group that can be a standalone patch than
>> combining with 05/11.
> It is more important to divide patches in logical functional blocks
> rather than split it based on files. Reading this patch, I have no idea
> what that define is for.
>
> Thanks,
> Sekhar
>
>
Will combine with 05/11 since utilities are used by the clock init code
in dm644x.
Murali
Quoting Murali Karicheri (2012-11-05 07:10:52)
> On 11/03/2012 08:07 AM, Sekhar Nori wrote:
> > On 10/25/2012 9:41 PM, Murali Karicheri wrote:
> >> This is the driver for the Power Sleep Controller (PSC) hardware
> >> found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed
> >> code from arch/arm/mach-davinci/psc.c and implemented the driver
> >> as per common clock provider API. The PSC module is responsible for
> >> enabling/disabling the Power Domain and Clock domain for different IPs
> >> present in the SoC. The driver is configured through the clock data
> >> passed to the driver through struct clk_psc_data.
> >>
> >> Signed-off-by: Murali Karicheri <[email protected]>
> >> ---
> >> +/**
> >> + * struct clk_psc - DaVinci PSC clock driver data
> >> + *
> >> + * @hw: clk_hw for the psc
> >> + * @psc_data: Driver specific data
> >> + */
> >> +struct clk_psc {
> >> + struct clk_hw hw;
> >> + struct clk_psc_data *psc_data;
> >> + spinlock_t *lock;
> > Unused member? I don't see this being used.
>
> OK. Will remove.
Those locks are only used for the case where a register might contain
bits for several clocks. Thus RMW operations are protected. On OMAP
this isn't necessary due to a very generous register layout (typically
one 32-bit reg per module) controlling clocks. Seems tha tmaybe this is
not needed for PSC module either?
Regards,
Mike
> >
> > Thanks,
> > Sekhar
> >
Hi Mike,
On 11/10/2012 7:52 AM, Mike Turquette wrote:
> Quoting Murali Karicheri (2012-11-05 07:10:52)
>> On 11/03/2012 08:07 AM, Sekhar Nori wrote:
>>> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>>>> This is the driver for the Power Sleep Controller (PSC) hardware
>>>> found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed
>>>> code from arch/arm/mach-davinci/psc.c and implemented the driver
>>>> as per common clock provider API. The PSC module is responsible for
>>>> enabling/disabling the Power Domain and Clock domain for different IPs
>>>> present in the SoC. The driver is configured through the clock data
>>>> passed to the driver through struct clk_psc_data.
>>>>
>>>> Signed-off-by: Murali Karicheri <[email protected]>
>>>> ---
>>>> +/**
>>>> + * struct clk_psc - DaVinci PSC clock driver data
>>>> + *
>>>> + * @hw: clk_hw for the psc
>>>> + * @psc_data: Driver specific data
>>>> + */
>>>> +struct clk_psc {
>>>> + struct clk_hw hw;
>>>> + struct clk_psc_data *psc_data;
>>>> + spinlock_t *lock;
>>> Unused member? I don't see this being used.
>>
>> OK. Will remove.
>
> Those locks are only used for the case where a register might contain
> bits for several clocks. Thus RMW operations are protected. On OMAP
> this isn't necessary due to a very generous register layout (typically
> one 32-bit reg per module) controlling clocks. Seems tha tmaybe this is
> not needed for PSC module either?
Sorry about the late reply. The above is not totally true for PSC. There
are some registers (like PTCMD) which are common for all clocks.
There is an enable_lock used in drivers/clk/clk.c which serializes all
enable/disable calls across the clock tree. Since that is done, further
locking at clk-psc level is not really needed, no?
Thanks,
Sekhar
On 11/27/2012 12:29 PM, Mike Turquette wrote:
> Quoting Sekhar Nori (2012-11-27 07:05:21)
>> Hi Mike,
>>
>> On 11/10/2012 7:52 AM, Mike Turquette wrote:
>>> Quoting Murali Karicheri (2012-11-05 07:10:52)
>>>> On 11/03/2012 08:07 AM, Sekhar Nori wrote:
>>>>> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>>>>>> This is the driver for the Power Sleep Controller (PSC) hardware
>>>>>> found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed
>>>>>> code from arch/arm/mach-davinci/psc.c and implemented the driver
>>>>>> as per common clock provider API. The PSC module is responsible for
>>>>>> enabling/disabling the Power Domain and Clock domain for different IPs
>>>>>> present in the SoC. The driver is configured through the clock data
>>>>>> passed to the driver through struct clk_psc_data.
>>>>>>
>>>>>> Signed-off-by: Murali Karicheri <[email protected]>
>>>>>> ---
>>>>>> +/**
>>>>>> + * struct clk_psc - DaVinci PSC clock driver data
>>>>>> + *
>>>>>> + * @hw: clk_hw for the psc
>>>>>> + * @psc_data: Driver specific data
>>>>>> + */
>>>>>> +struct clk_psc {
>>>>>> + struct clk_hw hw;
>>>>>> + struct clk_psc_data *psc_data;
>>>>>> + spinlock_t *lock;
>>>>> Unused member? I don't see this being used.
>>>> OK. Will remove.
>>> Those locks are only used for the case where a register might contain
>>> bits for several clocks. Thus RMW operations are protected. On OMAP
>>> this isn't necessary due to a very generous register layout (typically
>>> one 32-bit reg per module) controlling clocks. Seems tha tmaybe this is
>>> not needed for PSC module either?
>> Sorry about the late reply. The above is not totally true for PSC. There
>> are some registers (like PTCMD) which are common for all clocks.
>>
>> There is an enable_lock used in drivers/clk/clk.c which serializes all
>> enable/disable calls across the clock tree. Since that is done, further
>> locking at clk-psc level is not really needed, no?
>>
> I haven't finished looking through the PSC design document yet, but my
> answer to your question is this:
>
> If a register is only used for clk_enable/disable calls (not touched by
> anything held under the prepare_lock mutex) and if that register isn't
> used anywhere else in the code (outside of the clk framework) then yes,
> the enable_lock spinlock is enough for you.
The psc clocks share registers such as PTCMD in addition to the clock
specific register. So if there are multiple concurrent paths to
clk_enable()/clk_disable() possible, then PTCMD write is not protected
through the main enable()/disable() lock. Now I am not sure if there are
multiple concurrent paths possible such as invoking the API in the
context of a user process, kernel thread etc. If this is a possibility
then IMO, a lock is needed.
Murali
> Also have you looked into regmap? Since you are defining your own clock
> type that might be something nice for you.
>
> Regards,
> Mike
>
>> Thanks,
>> Sekhar
>
On 11/27/2012 10:59 PM, Mike Turquette wrote:
> Quoting Sekhar Nori (2012-11-27 07:05:21)
>> Hi Mike,
>>
>> On 11/10/2012 7:52 AM, Mike Turquette wrote:
>>> Quoting Murali Karicheri (2012-11-05 07:10:52)
>>>> On 11/03/2012 08:07 AM, Sekhar Nori wrote:
>>>>> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>>>>>> This is the driver for the Power Sleep Controller (PSC) hardware
>>>>>> found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed
>>>>>> code from arch/arm/mach-davinci/psc.c and implemented the driver
>>>>>> as per common clock provider API. The PSC module is responsible for
>>>>>> enabling/disabling the Power Domain and Clock domain for different IPs
>>>>>> present in the SoC. The driver is configured through the clock data
>>>>>> passed to the driver through struct clk_psc_data.
>>>>>>
>>>>>> Signed-off-by: Murali Karicheri <[email protected]>
>>>>>> ---
>>>>>> +/**
>>>>>> + * struct clk_psc - DaVinci PSC clock driver data
>>>>>> + *
>>>>>> + * @hw: clk_hw for the psc
>>>>>> + * @psc_data: Driver specific data
>>>>>> + */
>>>>>> +struct clk_psc {
>>>>>> + struct clk_hw hw;
>>>>>> + struct clk_psc_data *psc_data;
>>>>>> + spinlock_t *lock;
>>>>> Unused member? I don't see this being used.
>>>>
>>>> OK. Will remove.
>>>
>>> Those locks are only used for the case where a register might contain
>>> bits for several clocks. Thus RMW operations are protected. On OMAP
>>> this isn't necessary due to a very generous register layout (typically
>>> one 32-bit reg per module) controlling clocks. Seems tha tmaybe this is
>>> not needed for PSC module either?
>>
>> Sorry about the late reply. The above is not totally true for PSC. There
>> are some registers (like PTCMD) which are common for all clocks.
>>
>> There is an enable_lock used in drivers/clk/clk.c which serializes all
>> enable/disable calls across the clock tree. Since that is done, further
>> locking at clk-psc level is not really needed, no?
>>
>
> I haven't finished looking through the PSC design document yet, but my
> answer to your question is this:
>
> If a register is only used for clk_enable/disable calls (not touched by
This is right, all PSC registers are only touched in clk_enable/disable
calls. clk-psc.c also populates .is_enabled, but that's only a regsiter
read anyway. Plus looks like even that is always accessed under enable_lock.
> anything held under the prepare_lock mutex) and if that register isn't
The requirement that these registers should not be touched when held
under prepare_lock mutex is not met because functions like
clk_disabled_unused_subtree() which are called under prepare_lock mutex
will end up calling clk_disable() anyway.
Perhaps you meant: not touched by anything under 'prepare_lock' mutex
while being outside of the 'enable_lock' spinlock?
> used anywhere else in the code (outside of the clk framework) then yes,
> the enable_lock spinlock is enough for you.
No, they are not accessed out side of clk framework. At least currently.
PSC can also be used to provide a "reset" to some IPs, but there is no
"reset framework" which uses this feature.
> Also have you looked into regmap? Since you are defining your own clock
> type that might be something nice for you.
No, haven't looked at regmap yet. Will look at that.
Thanks,
Sekhar
On 10/29/2012 12:54 AM, Linus Walleij wrote:
> On Thu, Oct 25, 2012 at 6:11 PM, Murali Karicheri <[email protected]> wrote:
>
>> This is the driver for the Power Sleep Controller (PSC) hardware
>> found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed
>> code from arch/arm/mach-davinci/psc.c and implemented the driver
>> as per common clock provider API. The PSC module is responsible for
>> enabling/disabling the Power Domain and Clock domain for different IPs
>> present in the SoC. The driver is configured through the clock data
>> passed to the driver through struct clk_psc_data.
>>
>> Signed-off-by: Murali Karicheri <[email protected]>
>
> Acked-by: Linus Walleij <[email protected]>
>
> Here is some pedantic stuff if you're really bored:
>
>> diff --git a/drivers/clk/davinci/clk-psc.c b/drivers/clk/davinci/clk-psc.c
> (...)
>> + ptcmd = 1 << domain;
>
> ptcmd = BIT(domain);
>
>> + pdctl = readl(psc_base + PDCTL + 4 * domain);
>> + pdctl |= 0x100;
>
> pdctl |= BIT(8); /* and here a comment explaing what on earth that means */
It turns out this piece of code is superfluous and the exact same thing
is being done again just down below.
Thanks,
Sekhar
Mike,
On 11/28/2012 6:52 PM, Sekhar Nori wrote:
> On 11/27/2012 10:59 PM, Mike Turquette wrote:
>> Also have you looked into regmap? Since you are defining your own clock
>> type that might be something nice for you.
>
> No, haven't looked at regmap yet. Will look at that.
I could get to this only now. regmap needs a valid struct device. We
aren't modelling psc clocks as device so regmap cannot be used here.
Thanks,
Sekhar
Quoting Sekhar Nori (2013-03-22 04:20:28)
> Mike,
>
> On 11/28/2012 6:52 PM, Sekhar Nori wrote:
> > On 11/27/2012 10:59 PM, Mike Turquette wrote:
>
> >> Also have you looked into regmap? Since you are defining your own clock
> >> type that might be something nice for you.
> >
> > No, haven't looked at regmap yet. Will look at that.
>
> I could get to this only now. regmap needs a valid struct device. We
> aren't modelling psc clocks as device so regmap cannot be used here.
>
According to Murali's reply back in November it was still not known if
the PTCMD register was going to be concurrently accessed by sources
outside the clock framework. If this is so then neither the existing
framework-level lock (e.g. enable_lock) nor the shared clock driver lock
(e.g. spinlock in struct clk_psc) are adequate. You may need a device
driver which represents the PSC and use accessor functions to write to
those register which provide coordination.
Regards,
Mike
> Thanks,
> Sekhar
Hi Mike,
On 3/23/2013 2:07 AM, Mike Turquette wrote:
> Quoting Sekhar Nori (2013-03-22 04:20:28)
>> Mike,
>>
>> On 11/28/2012 6:52 PM, Sekhar Nori wrote:
>>> On 11/27/2012 10:59 PM, Mike Turquette wrote:
>>
>>>> Also have you looked into regmap? Since you are defining your own clock
>>>> type that might be something nice for you.
>>>
>>> No, haven't looked at regmap yet. Will look at that.
>>
>> I could get to this only now. regmap needs a valid struct device. We
>> aren't modelling psc clocks as device so regmap cannot be used here.
>>
>
> According to Murali's reply back in November it was still not known if
> the PTCMD register was going to be concurrently accessed by sources
> outside the clock framework. If this is so then neither the existing
I can confirm that PTCMD is a PSC specific register and it is not
accessed outside of clock framework.
> framework-level lock (e.g. enable_lock) nor the shared clock driver lock
> (e.g. spinlock in struct clk_psc) are adequate. You may need a device
> driver which represents the PSC and use accessor functions to write to
> those register which provide coordination.
Well the only reason to access *any* PSC register outside of clock
framework would be to handle the corner case where DSP needs to be reset
using its PSC.
In this case, there needs to be an access to MDCTL register specific to
that module (ie the DSP). Right now this functionality is implemented
using the function davinci_psc_reset().
When moving to common clock framework, I think this can be moved to
drivers/clk/davinci/clk-psc.c (it will be similar to the way
tegra_periph_reset() is handled in drivers/clk/tegra/clk-periph-gate.c).
And in this case I do agree we need a spinlock local to clk-psc.c (like
the periph_ref_lock spinlock used in tegra implementation). That said,
the current series only enables DM644x and does not really implement the
reset stuff needed for DA850. So we can either add the spinlock now, or
defer it to later when DA850 get supported (so there is a clear history
trace of why it was added).
Thanks,
Sekhar