This series converts mach-davinci to use the common clock framework.
The series works like this, the first 19 patches create new clock drivers
using the common clock framework. There are basically 3 groups of clocks -
PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each have
unique init data, which is the reason for so many patches.
Then, starting with "ARM: davinci: pass clock as parameter to
davinci_timer_init()", we get the mach code ready for the switch by adding the
code needed for the new clock drivers and adding #ifndef CONFIG_COMMON_CLK
around the legacy clocks so that we can switch easily between the old and the
new.
"ARM: davinci: switch to common clock framework" actually flips the switch
to start using the new clock drivers. Then the next 8 patches remove all
of the old clock code.
The final three patches add device tree clock support to the one SoC that
supports it.
This series has been tested on LEGO MINDSTORMS EV3 (device tree) and TI
OMAP-L138 LCDK (both device tree and legacy board file).
Changes:
v8 changes (also see individual patches for details):
- Rebased on linux-davinci/master
- Dropped use of __init and __initconst attributes in clk drivers
- Add clkdev lookups for PLL SYSCLKs
- Fix genpd clock reference counting issue
- Fix PSC clock driver loading order issue
- Fix typo in device tree and add more power-domains properties
v7 changes (also see individual patches for details):
- Rebased on linux-davinci/master (v4.16-rc)
- Convert clock drivers to platform devices
- New patch "ARM: davinci: pass clock as parameter to davinci_timer_init()"
- Fix issues with lcdk and aemif clock lookups and power domains
- Fixed other minor issues brought up in v6 review
v6 changes (also see individual patches for details):
- All of the device tree bindings are changed
- All of the clock drivers are changed significantly
- Fixed issues brought up during review of v5
- "ARM: davinci: move davinci_clk_init() to init_time" is removed from this
series and submitted separately
v5 changes:
- Basically, this is an entirely new series
- Patches are broken up into bite-sized pieces
- Converted PSC clock driver to use regmap
- Restored "force" flag for certain DA850 clocks
- Added device tree bindings
- Moved more of the clock init to drivers/clk
- Fixed frequency scaling (maybe*)
* I have frequency scaling using cpufreq-dt, so I know the clocks are doing
what they need to do to make this work, but I haven't figured out how to
test davinci-cpufreq driver yet. (Patches to make cpufreq-dt work will be
sent separately after this series has landed.)
Dependencies:
- "ARM: davinci: fix the GPIO lookup for omapl138-hawk"[1] (in linux-davinci/fixes)
- "drm/tilcdc: Fix setting clock divider for omap-l138"[2] (new)
- "ARM: davinci: DA8XX: fix oops in USB PHY driver due to stack allocated
platform platform_data"[3] (new)
- "ARM: davinci: DA8XX: simplify CFGCHIP regmap_config"[4] (new)
- "clk: divider: export clk_div_mask() helper"[5] (in clk/fixes)
- "clk: divider: read-only divider can propagate rate change"[6] (in clk/fixes)
- "gpio: Handle deferred probing in of_find_gpio() properly"[7] (in v4.16-rc4)
- "gpiolib: Keep returning EPROBE_DEFER when we should"[8] (in v4.16-rc4)
[1]: https://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci.git/commit/?h=fixes&id=c4dc56be7e26040bfc60ce73425353516a356955
[2]: https://patchwork.freedesktop.org/patch/210696/
[3]: https://patchwork.kernel.org/patch/10285679/
[4]: https://patchwork.kernel.org/patch/10285605/
[5]: https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/commit/?h=clk-next&id=e6d3cc7b1fac3d7f1313faf8ac9b23830113e3ec
[6]: https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/commit/?h=clk-next&id=b15ee490e16324c35b51f04bad54ae45a2cefd29
[7]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ce27fb2c56db6ccfe8099343bb4afdab15e77e7b
[8]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6662ae6af82df10259a70c7569b4c12ea7f3ba93
You can find a working branch with everything included (plus a few extras, like
cpufreq-dt) in the "common-clk-v8" branch of https://github.com/dlech/ev3dev-kernel.git.
Testing/debugging for the uninitiated:
I only have one device to test with, which is based on da850, so I will
have to rely on others to do some testing here. Since we are dealing with
clocks, if something isn't working, you most likely won't see output on
the serial port. To figure out what is going on, you need to enable...
CONFIG_DEBUG_LL=y
CONFIG_EARLY_PRINTK=y
and add "earlyprintk clk_ignore_unused" to the kernel command line options.
You may need to select a different UART for this depending on your board. I
think UART1 is the default in the kernel configuration.
On da850 devices comment out the lines:
else
clk_set_parent(clk, parent->clk);
in da850.c or, if using device tree, comment out the lines:
assigned-clocks = <&async3_clk>;
assigned-clock-parents = <&pll1_sysclk 2>;
in da850.dtsi when doing earlyprintk, otherwise the UART1 and UART2 clock
source will change during boot and cause garbled output after a point.
David Lechner (42):
dt-bindings: clock: Add new bindings for TI Davinci PLL clocks
clk: davinci: New driver for davinci PLL clocks
clk: davinci: Add platform information for TI DA830 PLL
clk: davinci: Add platform information for TI DA850 PLL
clk: davinci: Add platform information for TI DM355 PLL
clk: davinci: Add platform information for TI DM365 PLL
clk: davinci: Add platform information for TI DM644x PLL
clk: davinci: Add platform information for TI DM646x PLL
dt-bindings: clock: New bindings for TI Davinci PSC
clk: davinci: New driver for davinci PSC clocks
clk: davinci: Add platform information for TI DA830 PSC
clk: davinci: Add platform information for TI DA850 PSC
clk: davinci: Add platform information for TI DM355 PSC
clk: davinci: Add platform information for TI DM365 PSC
clk: davinci: Add platform information for TI DM644x PSC
clk: davinci: Add platform information for TI DM646x PSC
dt-bindings: clock: Add bindings for DA8XX CFGCHIP clocks
clk: davinci: New driver for TI DA8XX CFGCHIP clocks
clk: davinci: cfgchip: Add TI DA8XX USB PHY clocks
ARM: davinci: pass clock as parameter to davinci_timer_init()
ARM: davinci: da830: add new clock init using common clock framework
ARM: davinci: da850: add new clock init using common clock framework
ARM: davinci: dm355: add new clock init using common clock framework
ARM: davinci: dm365: add new clock init using common clock framework
ARM: davinci: dm644x: add new clock init using common clock framework
ARM: davinci: dm646x: add new clock init using common clock framework
ARM: davinci: da8xx: add new USB PHY clock init using common clock
framework
ARM: davinci: da8xx: add new sata_refclk init using common clock
framework
ARM: davinci: remove CONFIG_DAVINCI_RESET_CLOCKS
ARM: davinci_all_defconfig: remove CONFIG_DAVINCI_RESET_CLOCKS
ARM: davinci: switch to common clock framework
ARM: davinci: da830: Remove legacy clock init
ARM: davinci: da850: Remove legacy clock init
ARM: davinci: dm355: Remove legacy clock init
ARM: davinci: dm365: Remove legacy clock init
ARM: davinci: dm644x: Remove legacy clock init
ARM: davinci: dm646x: Remove legacy clock init
ARM: davinci: da8xx: Remove legacy USB and SATA clock init
ARM: davinci: remove legacy clocks
ARM: davinci: add device tree support to timer
ARM: davinci: da8xx-dt: switch to device tree clocks
ARM: dts: da850: Add clocks
.../bindings/clock/ti/davinci/da8xx-cfgchip.txt | 93 +++
.../devicetree/bindings/clock/ti/davinci/pll.txt | 96 +++
.../devicetree/bindings/clock/ti/davinci/psc.txt | 71 ++
MAINTAINERS | 7 +
arch/arm/Kconfig | 5 +-
arch/arm/boot/dts/da850-enbw-cmc.dts | 4 +
arch/arm/boot/dts/da850-evm.dts | 4 +
arch/arm/boot/dts/da850-lcdk.dts | 9 +
arch/arm/boot/dts/da850-lego-ev3.dts | 4 +
arch/arm/boot/dts/da850.dtsi | 167 ++++
arch/arm/configs/davinci_all_defconfig | 1 -
arch/arm/mach-davinci/Kconfig | 13 +-
arch/arm/mach-davinci/Makefile | 4 +-
arch/arm/mach-davinci/board-da830-evm.c | 12 +-
arch/arm/mach-davinci/board-da850-evm.c | 2 +
arch/arm/mach-davinci/board-dm355-evm.c | 2 +
arch/arm/mach-davinci/board-dm355-leopard.c | 2 +
arch/arm/mach-davinci/board-dm365-evm.c | 2 +
arch/arm/mach-davinci/board-dm644x-evm.c | 2 +
arch/arm/mach-davinci/board-dm646x-evm.c | 2 +
arch/arm/mach-davinci/board-mityomapl138.c | 2 +
arch/arm/mach-davinci/board-neuros-osd2.c | 2 +
arch/arm/mach-davinci/board-omapl138-hawk.c | 11 +-
arch/arm/mach-davinci/board-sffsdr.c | 2 +
arch/arm/mach-davinci/clock.c | 745 -----------------
arch/arm/mach-davinci/clock.h | 76 --
arch/arm/mach-davinci/common.c | 3 -
arch/arm/mach-davinci/da830.c | 469 ++---------
arch/arm/mach-davinci/da850.c | 789 ++++--------------
arch/arm/mach-davinci/da8xx-dt.c | 60 --
arch/arm/mach-davinci/davinci.h | 8 +
arch/arm/mach-davinci/devices-da8xx.c | 43 +-
arch/arm/mach-davinci/devices.c | 1 -
arch/arm/mach-davinci/dm355.c | 425 ++--------
arch/arm/mach-davinci/dm365.c | 517 ++----------
arch/arm/mach-davinci/dm644x.c | 363 ++-------
arch/arm/mach-davinci/dm646x.c | 394 ++-------
arch/arm/mach-davinci/include/mach/clock.h | 3 -
arch/arm/mach-davinci/include/mach/common.h | 11 +-
arch/arm/mach-davinci/include/mach/da8xx.h | 6 +-
arch/arm/mach-davinci/pm_domain.c | 5 +
arch/arm/mach-davinci/psc.c | 137 ----
arch/arm/mach-davinci/psc.h | 12 -
arch/arm/mach-davinci/time.c | 46 +-
arch/arm/mach-davinci/usb-da8xx.c | 242 +-----
drivers/clk/Makefile | 1 +
drivers/clk/davinci/Makefile | 21 +
drivers/clk/davinci/da8xx-cfgchip.c | 790 ++++++++++++++++++
drivers/clk/davinci/pll-da830.c | 70 ++
drivers/clk/davinci/pll-da850.c | 212 +++++
drivers/clk/davinci/pll-dm355.c | 79 ++
drivers/clk/davinci/pll-dm365.c | 145 ++++
drivers/clk/davinci/pll-dm644x.c | 80 ++
drivers/clk/davinci/pll-dm646x.c | 84 ++
drivers/clk/davinci/pll.c | 901 +++++++++++++++++++++
drivers/clk/davinci/pll.h | 141 ++++
drivers/clk/davinci/psc-da830.c | 116 +++
drivers/clk/davinci/psc-da850.c | 149 ++++
drivers/clk/davinci/psc-dm355.c | 88 ++
drivers/clk/davinci/psc-dm365.c | 96 +++
drivers/clk/davinci/psc-dm644x.c | 83 ++
drivers/clk/davinci/psc-dm646x.c | 80 ++
drivers/clk/davinci/psc.c | 552 +++++++++++++
drivers/clk/davinci/psc.h | 108 +++
include/linux/platform_data/clk-da8xx-cfgchip.h | 21 +
include/linux/platform_data/clk-davinci-pll.h | 21 +
66 files changed, 4876 insertions(+), 3836 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip.txt
create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/psc.txt
delete mode 100644 arch/arm/mach-davinci/clock.c
delete mode 100644 arch/arm/mach-davinci/psc.c
create mode 100644 drivers/clk/davinci/Makefile
create mode 100644 drivers/clk/davinci/da8xx-cfgchip.c
create mode 100644 drivers/clk/davinci/pll-da830.c
create mode 100644 drivers/clk/davinci/pll-da850.c
create mode 100644 drivers/clk/davinci/pll-dm355.c
create mode 100644 drivers/clk/davinci/pll-dm365.c
create mode 100644 drivers/clk/davinci/pll-dm644x.c
create mode 100644 drivers/clk/davinci/pll-dm646x.c
create mode 100644 drivers/clk/davinci/pll.c
create mode 100644 drivers/clk/davinci/pll.h
create mode 100644 drivers/clk/davinci/psc-da830.c
create mode 100644 drivers/clk/davinci/psc-da850.c
create mode 100644 drivers/clk/davinci/psc-dm355.c
create mode 100644 drivers/clk/davinci/psc-dm365.c
create mode 100644 drivers/clk/davinci/psc-dm644x.c
create mode 100644 drivers/clk/davinci/psc-dm646x.c
create mode 100644 drivers/clk/davinci/psc.c
create mode 100644 drivers/clk/davinci/psc.h
create mode 100644 include/linux/platform_data/clk-da8xx-cfgchip.h
create mode 100644 include/linux/platform_data/clk-davinci-pll.h
--
2.7.4
The common clock framework will take care of disabling unused clocks when
we switch from the legacy davinci clocks and having this enabled will
cause compile errors after we switch, so remove it now.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
---
v8 changes:
- none
v7 changes:
- none
v6 changes:
- none
arch/arm/mach-davinci/Kconfig | 12 ------------
arch/arm/mach-davinci/common.c | 1 -
arch/arm/mach-davinci/include/mach/common.h | 6 ------
3 files changed, 19 deletions(-)
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index 05c3eecf..ba9912b 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -231,18 +231,6 @@ config DAVINCI_MUX_WARNINGS
to change the pin multiplexing setup. When there are no warnings
printed, it's safe to deselect DAVINCI_MUX for your product.
-config DAVINCI_RESET_CLOCKS
- bool "Reset unused clocks during boot"
- depends on ARCH_DAVINCI
- help
- Say Y if you want to reset unused clocks during boot.
- This option saves power, but assumes all drivers are
- using the clock framework. Broken drivers that do not
- yet use clock framework may not work with this option.
- If you are booting from another operating system, you
- probably do not want this option enabled until your
- device drivers work properly.
-
endmenu
endif
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
index bcb6a7b..e03f95c 100644
--- a/arch/arm/mach-davinci/common.c
+++ b/arch/arm/mach-davinci/common.c
@@ -118,5 +118,4 @@ void __init davinci_common_init(const struct davinci_soc_info *soc_info)
void __init davinci_init_late(void)
{
davinci_cpufreq_init();
- davinci_clk_disable_unused();
}
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 5f45d0a..ded8f5f 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -83,12 +83,6 @@ extern void davinci_common_init(const struct davinci_soc_info *soc_info);
extern void davinci_init_ide(void);
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
--
2.7.4
This adds the new USB PHY clock init in mach-davinci/usb-da8xx.c using
the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- rebased on "ARM: davinci: DA8XX: fix oops in USB PHY driver due to stack
allocated platform platform_data"
v7 changes:
- register platform device instead of registering clocks directly
- USB PHY clocks now treated as single device instead of registering them
separately
v6 changes:
- rename stuff to match changes in "clk: davinci: New driver for TI DA8XX USB
PHY clocks"
- take advantage of syscon lookup changes in "mfd: syscon: Add syscon_register()
function"
arch/arm/mach-davinci/board-da830-evm.c | 8 +++++++-
arch/arm/mach-davinci/board-omapl138-hawk.c | 9 +++++++--
arch/arm/mach-davinci/da8xx-dt.c | 8 +++++++-
arch/arm/mach-davinci/include/mach/da8xx.h | 1 +
arch/arm/mach-davinci/usb-da8xx.c | 26 ++++++++++++++++++++++++--
5 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index 3973124..6e77c45 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -110,6 +110,12 @@ static __init void da830_evm_usb_init(void)
{
int ret;
+#ifdef CONFIG_COMMON_CLK
+ ret = da8xx_register_usb_phy_clocks();
+ if (ret)
+ pr_warn("%s: USB PHY CLK registration failed: %d\n",
+ __func__, ret);
+#else
/* USB_REFCLKIN is not used. */
ret = da8xx_register_usb20_phy_clk(false);
if (ret)
@@ -120,7 +126,7 @@ static __init void da830_evm_usb_init(void)
if (ret)
pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n",
__func__, ret);
-
+#endif
ret = da8xx_register_usb_phy();
if (ret)
pr_warn("%s: USB PHY registration failed: %d\n",
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index eb09e33..6a866d2 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -231,7 +231,12 @@ static __init void omapl138_hawk_usb_init(void)
pr_warn("%s: USB 1.1 PinMux setup failed: %d\n", __func__, ret);
return;
}
-
+#ifdef CONFIG_COMMON_CLK
+ ret = da8xx_register_usb_phy_clocks();
+ if (ret)
+ pr_warn("%s: USB PHY CLK registration failed: %d\n",
+ __func__, ret);
+#else
ret = da8xx_register_usb20_phy_clk(false);
if (ret)
pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n",
@@ -241,7 +246,7 @@ static __init void omapl138_hawk_usb_init(void)
if (ret)
pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n",
__func__, ret);
-
+#endif
ret = da8xx_register_usb_phy();
if (ret)
pr_warn("%s: USB PHY registration failed: %d\n",
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index 91dd9cb..c4edf05 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -69,6 +69,12 @@ static void __init da850_init_machine(void)
da850_register_clocks();
+#ifdef CONFIG_COMMON_CLK
+ ret = da8xx_register_usb_phy_clocks();
+ if (ret)
+ pr_warn("%s: USB PHY CLK registration failed: %d\n",
+ __func__, ret);
+#else
ret = da8xx_register_usb20_phy_clk(false);
if (ret)
pr_warn("%s: registering USB 2.0 PHY clock failed: %d",
@@ -77,7 +83,7 @@ static void __init da850_init_machine(void)
if (ret)
pr_warn("%s: registering USB 1.1 PHY clock failed: %d",
__func__, ret);
-
+#endif
ret = da850_register_sata_refclk(sata_refclkpn);
if (ret)
pr_warn("%s: registering SATA REFCLK failed: %d",
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 612e454..5d7b1de 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -106,6 +106,7 @@ int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
int da8xx_register_usb_refclkin(int rate);
int da8xx_register_usb20_phy_clk(bool use_usb_refclkin);
int da8xx_register_usb11_phy_clk(bool use_usb_refclkin);
+int da8xx_register_usb_phy_clocks(void);
int da850_register_sata_refclk(int rate);
int da8xx_register_emac(void);
int da8xx_register_uio_pruss(void);
diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
index 67d634b..d0ba725 100644
--- a/arch/arm/mach-davinci/usb-da8xx.c
+++ b/arch/arm/mach-davinci/usb-da8xx.c
@@ -2,29 +2,35 @@
/*
* DA8xx USB
*/
-#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/mfd/syscon.h>
#include <linux/phy/phy.h>
+#include <linux/platform_data/clk-da8xx-cfgchip.h>
#include <linux/platform_data/phy-da8xx-usb.h>
#include <linux/platform_data/usb-davinci.h>
#include <linux/platform_device.h>
#include <linux/usb/musb.h>
-#include <mach/clock.h>
#include <mach/common.h>
#include <mach/cputype.h>
#include <mach/da8xx.h>
#include <mach/irqs.h>
+#ifndef CONFIG_COMMON_CLK
+#include <mach/clock.h>
#include "clock.h"
+#endif
#define DA8XX_USB0_BASE 0x01e00000
#define DA8XX_USB1_BASE 0x01e25000
+#ifndef CONFIG_COMMON_CLK
static struct clk *usb20_clk;
+#endif
static struct da8xx_usb_phy_platform_data da8xx_usb_phy_pdata;
@@ -136,6 +142,7 @@ int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata)
return platform_device_register(&da8xx_usb11_device);
}
+#ifndef CONFIG_COMMON_CLK
static struct clk usb_refclkin = {
.name = "usb_refclkin",
.set_rate = davinci_simple_set_rate,
@@ -362,3 +369,18 @@ int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
return ret;
}
+#endif
+static struct platform_device da8xx_usb_phy_clks_device = {
+ .name = "da830-usb-phy-clks",
+ .id = -1,
+};
+
+int __init da8xx_register_usb_phy_clocks(void)
+{
+ struct da8xx_cfgchip_clk_platform_data pdata;
+
+ pdata.cfgchip = da8xx_get_cfgchip();
+ da8xx_usb_phy_clks_device.dev.platform_data = &pdata;
+
+ return platform_device_register(&da8xx_usb_phy_clks_device);
+}
--
2.7.4
This adds the new board-specific clock init in mach-davinci/dm365.c
using the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Also clean up the #includes since we are adding some here.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- none
v7 changes:
- add clock platform device declarations
- register platform devices instead of registering clocks directly
- add davinci prefix to commit description
v6 changes:
- add blank lines between function calls
arch/arm/mach-davinci/board-dm365-evm.c | 2 +
arch/arm/mach-davinci/davinci.h | 1 +
arch/arm/mach-davinci/dm365.c | 88 ++++++++++++++++++++++++++++-----
3 files changed, 79 insertions(+), 12 deletions(-)
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index 0ac085b..36b69a1 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -741,6 +741,8 @@ static __init void dm365_evm_init(void)
{
int ret;
+ dm365_register_clocks();
+
ret = dm365_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index 6b6abf0a..c865226 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -94,6 +94,7 @@ int dm355_gpio_register(void);
/* DM365 function declarations */
void dm365_init(void);
void dm365_init_time(void);
+void dm365_register_clocks(void);
void dm365_init_asp(void);
void dm365_init_vc(void);
void dm365_init_ks(struct davinci_ks_platform_data *pdata);
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 871372a..93067e1 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -12,32 +12,35 @@
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/serial_8250.h>
-#include <linux/platform_device.h>
+#include <linux/clk-provider.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
-#include <linux/spi/spi.h>
+#include <linux/init.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/keyscan-davinci.h>
#include <linux/platform_data/spi-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/spi/spi.h>
#include <asm/mach/map.h>
+#include <mach/common.h>
#include <mach/cputype.h>
-#include "psc.h"
-#include <mach/mux.h>
#include <mach/irqs.h>
-#include <mach/time.h>
+#include <mach/mux.h>
#include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
+#include "asp.h"
#include "davinci.h"
-#include "clock.h"
#include "mux.h"
-#include "asp.h"
+
+#ifndef CONFIG_COMMON_CLK
+#include "clock.h"
+#include "psc.h"
+#endif
#define DM365_REF_FREQ 24000000 /* 24 MHz on the DM365 EVM */
#define DM365_RTC_BASE 0x01c69000
@@ -54,6 +57,7 @@
#define DM365_EMAC_CNTRL_RAM_OFFSET 0x1000
#define DM365_EMAC_CNTRL_RAM_SIZE 0x2000
+#ifndef CONFIG_COMMON_CLK
static struct pll_data pll1_data = {
.num = 1,
.phys_base = DAVINCI_PLL1_BASE,
@@ -485,7 +489,7 @@ static struct clk_lookup dm365_clks[] = {
CLK(NULL, "mjcp", &mjcp_clk),
CLK(NULL, NULL, NULL),
};
-
+#endif
/*----------------------------------------------------------------------*/
#define INTMUX 0x18
@@ -1171,8 +1175,68 @@ void __init dm365_init(void)
void __init dm365_init_time(void)
{
+#ifdef CONFIG_COMMON_CLK
+ struct clk *clk;
+
+ clk = clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM365_REF_FREQ);
+
+ davinci_timer_init(clk);
+#else
davinci_clk_init(dm365_clks);
davinci_timer_init(&timer0_clk);
+#endif
+}
+
+static struct resource dm365_pll1_resources[] = {
+ {
+ .start = DAVINCI_PLL1_BASE,
+ .end = DAVINCI_PLL1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm365_pll1_device = {
+ .name = "dm365-pll1",
+ .id = -1,
+ .resource = dm365_pll1_resources,
+ .num_resources = ARRAY_SIZE(dm365_pll1_resources),
+};
+
+static struct resource dm365_pll2_resources[] = {
+ {
+ .start = DAVINCI_PLL2_BASE,
+ .end = DAVINCI_PLL2_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm365_pll2_device = {
+ .name = "dm365-pll2",
+ .id = -1,
+ .resource = dm365_pll2_resources,
+ .num_resources = ARRAY_SIZE(dm365_pll2_resources),
+};
+
+static struct resource dm365_psc_resources[] = {
+ {
+ .start = DAVINCI_PWR_SLEEP_CNTRL_BASE,
+ .end = DAVINCI_PWR_SLEEP_CNTRL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm365_psc_device = {
+ .name = "dm365-psc",
+ .id = -1,
+ .resource = dm365_psc_resources,
+ .num_resources = ARRAY_SIZE(dm365_psc_resources),
+};
+
+void __init dm365_register_clocks(void)
+{
+ platform_device_register(&dm365_pll1_device);
+ platform_device_register(&dm365_pll2_device);
+ platform_device_register(&dm365_psc_device);
}
static struct resource dm365_vpss_resources[] = {
--
2.7.4
This adds the new SATA REFCLK clock init in mach-davinci/devices-da8xx.c
using the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Also, the #includes are sorted since we are adding some here.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
---
v8 changes:
- none
v7 changes:
- none
v6 changes:
- none
arch/arm/mach-davinci/devices-da8xx.c | 36 ++++++++++++++++++++++++++---------
1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 78390c6..73de449 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -10,25 +10,30 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/dma-contiguous.h>
-#include <linux/serial_8250.h>
#include <linux/ahci_platform.h>
+#include <linux/clk-provider.h>
#include <linux/clk.h>
-#include <linux/reboot.h>
+#include <linux/clkdev.h>
+#include <linux/dma-contiguous.h>
#include <linux/dmaengine.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/serial_8250.h>
-#include <mach/cputype.h>
#include <mach/common.h>
-#include <mach/time.h>
+#include <mach/cputype.h>
#include <mach/da8xx.h>
-#include <mach/clock.h>
+#include <mach/time.h>
+
+#include "asp.h"
#include "cpuidle.h"
#include "sram.h"
+#ifndef CONFIG_COMMON_CLK
+#include <mach/clock.h>
#include "clock.h"
-#include "asp.h"
+#endif
#define DA8XX_TPCC_BASE 0x01c00000
#define DA8XX_TPTC0_BASE 0x01c08000
@@ -1040,6 +1045,7 @@ int __init da8xx_register_spi_bus(int instance, unsigned num_chipselect)
}
#ifdef CONFIG_ARCH_DAVINCI_DA850
+#ifndef CONFIG_COMMON_CLK
static struct clk sata_refclk = {
.name = "sata_refclk",
.set_rate = davinci_simple_set_rate,
@@ -1061,6 +1067,18 @@ int __init da850_register_sata_refclk(int rate)
return 0;
}
+#else
+int __init da850_register_sata_refclk(int rate)
+{
+ struct clk *clk;
+
+ clk = clk_register_fixed_rate(NULL, "sata_refclk", NULL, 0, rate);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ return clk_register_clkdev(clk, "refclk", "ahci_da850");
+}
+#endif
static struct resource da850_sata_resources[] = {
{
--
2.7.4
This adds the new board-specific clock init in mach-davinci/dm355.c
using the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Also clean up the #includes since we are adding some here.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- none
v7 changes:
- add clock platform device declarations
- register platform devices instead of registering clocks directly
- add davinci prefix to commit description
v6 changes:
- add blank lines between function calls
arch/arm/mach-davinci/board-dm355-evm.c | 2 +
arch/arm/mach-davinci/board-dm355-leopard.c | 2 +
arch/arm/mach-davinci/davinci.h | 1 +
arch/arm/mach-davinci/dm355.c | 88 +++++++++++++++++++++++++----
4 files changed, 81 insertions(+), 12 deletions(-)
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index cb30637..ea03ddc 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -384,6 +384,8 @@ static __init void dm355_evm_init(void)
struct clk *aemif;
int ret;
+ dm355_register_clocks();
+
ret = dm355_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index 59743bd..09f8216 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -233,6 +233,8 @@ static __init void dm355_leopard_init(void)
struct clk *aemif;
int ret;
+ dm355_register_clocks();
+
ret = dm355_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index 270cef8..6b6abf0a 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -84,6 +84,7 @@ int davinci_init_wdt(void);
/* DM355 function declarations */
void dm355_init(void);
void dm355_init_time(void);
+void dm355_register_clocks(void);
void dm355_init_spi0(unsigned chipselect_mask,
const struct spi_board_info *info, unsigned len);
void dm355_init_asp1(u32 evt_enable);
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 0da7516..f53e07a 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -8,31 +8,34 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/serial_8250.h>
-#include <linux/platform_device.h>
+#include <linux/clk-provider.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
-#include <linux/spi/spi.h>
+#include <linux/init.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/spi-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/spi/spi.h>
#include <asm/mach/map.h>
+#include <mach/common.h>
#include <mach/cputype.h>
-#include "psc.h"
-#include <mach/mux.h>
#include <mach/irqs.h>
-#include <mach/time.h>
+#include <mach/mux.h>
#include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
+#include "asp.h"
#include "davinci.h"
-#include "clock.h"
#include "mux.h"
-#include "asp.h"
+
+#ifndef CONFIG_COMMON_CLK
+#include "clock.h"
+#include "psc.h"
+#endif
#define DM355_UART2_BASE (IO_PHYS + 0x206000)
#define DM355_OSD_BASE (IO_PHYS + 0x70200)
@@ -43,6 +46,7 @@
*/
#define DM355_REF_FREQ 24000000 /* 24 or 36 MHz */
+#ifndef CONFIG_COMMON_CLK
static struct pll_data pll1_data = {
.num = 1,
.phys_base = DAVINCI_PLL1_BASE,
@@ -382,7 +386,7 @@ static struct clk_lookup dm355_clks[] = {
CLK(NULL, "usb", &usb_clk),
CLK(NULL, NULL, NULL),
};
-
+#endif
/*----------------------------------------------------------------------*/
static u64 dm355_spi0_dma_mask = DMA_BIT_MASK(32);
@@ -1046,8 +1050,68 @@ void __init dm355_init(void)
void __init dm355_init_time(void)
{
+#ifdef CONFIG_COMMON_CLK
+ struct clk *clk;
+
+ clk = clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM355_REF_FREQ);
+
+ davinci_timer_init(clk);
+#else
davinci_clk_init(dm355_clks);
davinci_timer_init(&timer0_clk);
+#endif
+}
+
+static struct resource dm355_pll1_resources[] = {
+ {
+ .start = DAVINCI_PLL1_BASE,
+ .end = DAVINCI_PLL1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm355_pll1_device = {
+ .name = "dm355-pll1",
+ .id = -1,
+ .resource = dm355_pll1_resources,
+ .num_resources = ARRAY_SIZE(dm355_pll1_resources),
+};
+
+static struct resource dm355_pll2_resources[] = {
+ {
+ .start = DAVINCI_PLL2_BASE,
+ .end = DAVINCI_PLL2_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm355_pll2_device = {
+ .name = "dm355-pll2",
+ .id = -1,
+ .resource = dm355_pll2_resources,
+ .num_resources = ARRAY_SIZE(dm355_pll2_resources),
+};
+
+static struct resource dm355_psc_resources[] = {
+ {
+ .start = DAVINCI_PWR_SLEEP_CNTRL_BASE,
+ .end = DAVINCI_PWR_SLEEP_CNTRL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm355_psc_device = {
+ .name = "dm355-psc",
+ .id = -1,
+ .resource = dm355_psc_resources,
+ .num_resources = ARRAY_SIZE(dm355_psc_resources),
+};
+
+void __init dm355_register_clocks(void)
+{
+ platform_device_register(&dm355_pll1_device);
+ platform_device_register(&dm355_pll2_device);
+ platform_device_register(&dm355_psc_device);
}
int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
--
2.7.4
This adds the new board-specific clock init in mach-davinci/da850.c
using the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Also clean up the #includes since we are adding some here.
Some CFGCHIP macros were removed because we are now including
linux/mfd/da8xx-cfgchip.h which defines the same values.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- add platform data for PLL clocks
v7 changes:
- add clock platform device declarations
- register platform devices instead of registering clocks directly
- clkdev lookup is moved to drivers/clk
- add davinci prefix to commit description
v6 changes:
- add blank lines between function calls
- include da8xx_register_cfgchip()
- add async1 and async2 clock domains
arch/arm/mach-davinci/board-da850-evm.c | 2 +
arch/arm/mach-davinci/board-mityomapl138.c | 2 +
arch/arm/mach-davinci/board-omapl138-hawk.c | 2 +
arch/arm/mach-davinci/da850.c | 166 +++++++++++++++++++++++++---
arch/arm/mach-davinci/da8xx-dt.c | 2 +
arch/arm/mach-davinci/include/mach/da8xx.h | 1 +
6 files changed, 162 insertions(+), 13 deletions(-)
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 3063478..78a670a 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1334,6 +1334,8 @@ static __init void da850_evm_init(void)
{
int ret;
+ da850_register_clocks();
+
ret = da850_register_gpio();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index d1c8548..f442784 100644
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -502,6 +502,8 @@ static void __init mityomapl138_init(void)
{
int ret;
+ da850_register_clocks();
+
/* for now, no special EDMA channels are reserved */
ret = da850_register_edma(NULL);
if (ret)
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index 0d32042..eb09e33 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -281,6 +281,8 @@ static __init void omapl138_hawk_init(void)
{
int ret;
+ da850_register_clocks();
+
ret = da850_register_gpio();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 1dbf01c..ae7c429 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -11,39 +11,44 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
+
+#include <linux/clk-provider.h>
#include <linux/clkdev.h>
+#include <linux/cpufreq.h>
#include <linux/gpio.h>
#include <linux/init.h>
-#include <linux/clk.h>
+#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/platform_data/clk-da8xx-cfgchip.h>
+#include <linux/platform_data/clk-davinci-pll.h>
+#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_device.h>
-#include <linux/cpufreq.h>
+#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
-#include <linux/platform_data/gpio-davinci.h>
#include <asm/mach/map.h>
-#include "psc.h"
-#include <mach/irqs.h>
-#include <mach/cputype.h>
#include <mach/common.h>
-#include <mach/time.h>
-#include <mach/da8xx.h>
#include <mach/cpufreq.h>
+#include <mach/cputype.h>
+#include <mach/da8xx.h>
+#include <mach/irqs.h>
#include <mach/pm.h>
+#include <mach/time.h>
-#include "clock.h"
#include "mux.h"
+#ifndef CONFIG_COMMON_CLK
+#include "clock.h"
+#include "psc.h"
+#endif
+
#define DA850_PLL1_BASE 0x01e1a000
#define DA850_TIMER64P2_BASE 0x01f0c000
#define DA850_TIMER64P3_BASE 0x01f0d000
#define DA850_REF_FREQ 24000000
-#define CFGCHIP3_ASYNC3_CLKSRC BIT(4)
-#define CFGCHIP3_PLL1_MASTER_LOCK BIT(5)
-#define CFGCHIP0_PLL_MASTER_LOCK BIT(4)
-
+#ifndef CONFIG_COMMON_CLK
static int da850_set_armrate(struct clk *clk, unsigned long rate);
static int da850_round_armrate(struct clk *clk, unsigned long rate);
static int da850_set_pll0rate(struct clk *clk, unsigned long armrate);
@@ -583,6 +588,7 @@ static struct clk_lookup da850_clks[] = {
CLK("ecap.2", "fck", &ecap2_clk),
CLK(NULL, NULL, NULL),
};
+#endif
/*
* Device specific mux setup
@@ -1170,6 +1176,7 @@ int da850_register_cpufreq(char *async_clk)
return platform_device_register(&da850_cpufreq_device);
}
+#ifndef CONFIG_COMMON_CLK
static int da850_round_armrate(struct clk *clk, unsigned long rate)
{
int ret = 0, diff;
@@ -1232,12 +1239,14 @@ static int da850_set_pll0rate(struct clk *clk, unsigned long rate)
return 0;
}
+#endif /* CONFIG_COMMON_CLK */
#else
int __init da850_register_cpufreq(char *async_clk)
{
return 0;
}
+#ifndef CONFIG_COMMON_CLK
static int da850_set_armrate(struct clk *clk, unsigned long rate)
{
return -EINVAL;
@@ -1252,6 +1261,7 @@ static int da850_round_armrate(struct clk *clk, unsigned long rate)
{
return clk->rate;
}
+#endif /* CONFIG_COMMON_CLK */
#endif
/* VPIF resource, platform data */
@@ -1395,6 +1405,136 @@ void __init da850_init(void)
void __init da850_init_time(void)
{
+#ifdef CONFIG_COMMON_CLK
+ struct clk *clk;
+
+ clk = clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DA850_REF_FREQ);
+
+ davinci_timer_init(clk);
+#else
davinci_clk_init(da850_clks);
davinci_timer_init(&timerp64_0_clk);
+#endif
+}
+
+static struct resource da850_pll0_resources[] = {
+ {
+ .start = DA8XX_PLL0_BASE,
+ .end = DA8XX_PLL0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct davinci_pll_platform_data da850_pll0_pdata;
+
+static struct platform_device da850_pll0_device = {
+ .name = "da850-pll0",
+ .id = -1,
+ .resource = da850_pll0_resources,
+ .num_resources = ARRAY_SIZE(da850_pll0_resources),
+ .dev = {
+ .platform_data = &da850_pll0_pdata,
+ },
+};
+
+static struct resource da850_pll1_resources[] = {
+ {
+ .start = DA850_PLL1_BASE,
+ .end = DA850_PLL1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct davinci_pll_platform_data da850_pll1_pdata;
+
+static struct platform_device da850_pll1_device = {
+ .name = "da850-pll1",
+ .id = -1,
+ .resource = da850_pll1_resources,
+ .num_resources = ARRAY_SIZE(da850_pll1_resources),
+ .dev = {
+ .platform_data = &da850_pll1_pdata,
+ },
+};
+
+static struct resource da850_psc0_resources[] = {
+ {
+ .start = DA8XX_PSC0_BASE,
+ .end = DA8XX_PSC0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device da850_psc0_device = {
+ .name = "da850-psc0",
+ .id = -1,
+ .resource = da850_psc0_resources,
+ .num_resources = ARRAY_SIZE(da850_psc0_resources),
+};
+
+static struct resource da850_psc1_resources[] = {
+ {
+ .start = DA8XX_PSC1_BASE,
+ .end = DA8XX_PSC1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device da850_psc1_device = {
+ .name = "da850-psc1",
+ .id = -1,
+ .resource = da850_psc1_resources,
+ .num_resources = ARRAY_SIZE(da850_psc1_resources),
+};
+
+static struct da8xx_cfgchip_clk_platform_data da850_async1_pdata;
+
+static struct platform_device da850_async1_clksrc_device = {
+ .name = "da850-async1-clksrc",
+ .id = -1,
+ .dev = {
+ .platform_data = &da850_async1_pdata,
+ },
+};
+
+static struct da8xx_cfgchip_clk_platform_data da850_async3_pdata;
+
+static struct platform_device da850_async3_clksrc_device = {
+ .name = "da850-async3-clksrc",
+ .id = -1,
+ .dev = {
+ .platform_data = &da850_async3_pdata,
+ },
+};
+
+static struct da8xx_cfgchip_clk_platform_data da850_tbclksync_pdata;
+
+static struct platform_device da850_tbclksync_device = {
+ .name = "da830-tbclksync",
+ .id = -1,
+ .dev = {
+ .platform_data = &da850_tbclksync_pdata,
+ },
+};
+
+void __init da850_register_clocks(void)
+{
+ da850_pll0_pdata.cfgchip = da8xx_get_cfgchip();
+ platform_device_register(&da850_pll0_device);
+
+ da850_pll1_pdata.cfgchip = da8xx_get_cfgchip();
+ platform_device_register(&da850_pll1_device);
+
+ da850_async1_pdata.cfgchip = da8xx_get_cfgchip();
+ platform_device_register(&da850_async1_clksrc_device);
+
+ da850_async3_pdata.cfgchip = da8xx_get_cfgchip();
+ platform_device_register(&da850_async3_clksrc_device);
+
+ platform_device_register(&da850_psc0_device);
+
+ platform_device_register(&da850_psc1_device);
+
+ da850_tbclksync_pdata.cfgchip = da8xx_get_cfgchip();
+ platform_device_register(&da850_tbclksync_device);
}
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index ab199f4..91dd9cb 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -67,6 +67,8 @@ static void __init da850_init_machine(void)
int ret;
+ da850_register_clocks();
+
ret = da8xx_register_usb20_phy_clk(false);
if (ret)
pr_warn("%s: registering USB 2.0 PHY clock failed: %d",
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 64861ac..612e454 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -93,6 +93,7 @@ void da830_register_clocks(void);
void da850_init(void);
void da850_init_time(void);
+void da850_register_clocks(void);
int da830_register_edma(struct edma_rsv_info *rsv);
int da850_register_edma(struct edma_rsv_info *rsv[2]);
--
2.7.4
This adds the new board-specific clock init in mach-davinci/dm646x.c
using the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Also clean up the #includes since we are adding some here.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- register clkdev lookup for ref_clk and aux_clkin
v7 changes:
- add clock platform device declarations
- register platform devices instead of registering clocks directly
- add davinci prefix to commit description
v6 changes:
- add blank lines between function calls
arch/arm/mach-davinci/board-dm646x-evm.c | 2 +
arch/arm/mach-davinci/davinci.h | 1 +
arch/arm/mach-davinci/dm646x.c | 85 +++++++++++++++++++++++++++++---
3 files changed, 80 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index 2d37f5b..d672804 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -772,6 +772,8 @@ static __init void evm_init(void)
int ret;
struct davinci_soc_info *soc_info = &davinci_soc_info;
+ dm646x_register_clocks();
+
ret = dm646x_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index 2861a6f..a200977 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -115,6 +115,7 @@ int dm644x_gpio_register(void);
/* DM646x function declarations */
void dm646x_init(void);
void dm646x_init_time(unsigned long ref_clk_rate, unsigned long aux_clkin_rate);
+void dm646x_register_clocks(void);
void dm646x_init_mcasp0(struct snd_platform_data *pdata);
void dm646x_init_mcasp1(struct snd_platform_data *pdata);
int dm646x_init_edma(struct edma_rsv_info *rsv);
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index e1d6e92..553782f 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -8,29 +8,33 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/serial_8250.h>
-#include <linux/platform_device.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
#include <asm/mach/map.h>
+#include <mach/common.h>
#include <mach/cputype.h>
#include <mach/irqs.h>
-#include "psc.h"
#include <mach/mux.h>
-#include <mach/time.h>
#include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
+#include "asp.h"
#include "davinci.h"
-#include "clock.h"
#include "mux.h"
-#include "asp.h"
+
+#ifndef CONFIG_COMMON_CLK
+#include "clock.h"
+#include "psc.h"
+#endif
#define DAVINCI_VPIF_BASE (0x01C12000)
@@ -46,6 +50,7 @@
#define DM646X_EMAC_CNTRL_RAM_OFFSET 0x2000
#define DM646X_EMAC_CNTRL_RAM_SIZE 0x2000
+#ifndef CONFIG_COMMON_CLK
static struct pll_data pll1_data = {
.num = 1,
.phys_base = DAVINCI_PLL1_BASE,
@@ -356,6 +361,7 @@ static struct clk_lookup dm646x_clks[] = {
CLK(NULL, "vpif1", &vpif1_clk),
CLK(NULL, NULL, NULL),
};
+#endif
static struct emac_platform_data dm646x_emac_pdata = {
.ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET,
@@ -953,10 +959,73 @@ void __init dm646x_init(void)
void __init dm646x_init_time(unsigned long ref_clk_rate,
unsigned long aux_clkin_rate)
{
+#ifdef CONFIG_COMMON_CLK
+ struct clk *clk;
+
+ clk = clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, ref_clk_rate);
+ clk_register_clkdev(clk, "ref_clk", "dm646x-psc");
+ davinci_timer_init(clk);
+
+ clk = clk_register_fixed_rate(NULL, "aux_clkin", NULL, 0, aux_clkin_rate);
+ clk_register_clkdev(clk, "aux_clkin", "dm646x-psc");
+#else
ref_clk.rate = ref_clk_rate;
aux_clkin.rate = aux_clkin_rate;
davinci_clk_init(dm646x_clks);
davinci_timer_init(&timer0_clk);
+#endif
+}
+
+static struct resource dm646x_pll1_resources[] = {
+ {
+ .start = DAVINCI_PLL1_BASE,
+ .end = DAVINCI_PLL1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm646x_pll1_device = {
+ .name = "dm646x-pll1",
+ .id = -1,
+ .resource = dm646x_pll1_resources,
+ .num_resources = ARRAY_SIZE(dm646x_pll1_resources),
+};
+
+static struct resource dm646x_pll2_resources[] = {
+ {
+ .start = DAVINCI_PLL2_BASE,
+ .end = DAVINCI_PLL2_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm646x_pll2_device = {
+ .name = "dm646x-pll2",
+ .id = -1,
+ .resource = dm646x_pll2_resources,
+ .num_resources = ARRAY_SIZE(dm646x_pll2_resources),
+};
+
+static struct resource dm646x_psc_resources[] = {
+ {
+ .start = DAVINCI_PWR_SLEEP_CNTRL_BASE,
+ .end = DAVINCI_PWR_SLEEP_CNTRL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm646x_psc_device = {
+ .name = "dm646x-psc",
+ .id = -1,
+ .resource = dm646x_psc_resources,
+ .num_resources = ARRAY_SIZE(dm646x_psc_resources),
+};
+
+void __init dm646x_register_clocks(void)
+{
+ platform_device_register(&dm646x_pll1_device);
+ platform_device_register(&dm646x_pll2_device);
+ platform_device_register(&dm646x_psc_device);
}
static int __init dm646x_init_devices(void)
--
2.7.4
This adds the new board-specific clock init in mach-davinci/dm644x.c
using the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Also clean up the #includes since we are adding some here.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- none
v7 changes:
- add clock platform device declarations
- register platform devices instead of registering clocks directly
- add davinci prefix to commit description
v6 changes:
- add blank lines between function calls
arch/arm/mach-davinci/board-dm644x-evm.c | 2 +
arch/arm/mach-davinci/board-neuros-osd2.c | 2 +
arch/arm/mach-davinci/board-sffsdr.c | 2 +
arch/arm/mach-davinci/davinci.h | 1 +
arch/arm/mach-davinci/dm644x.c | 83 +++++++++++++++++++++++++++----
5 files changed, 81 insertions(+), 9 deletions(-)
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 95b55aa..91c7525 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -768,6 +768,8 @@ static __init void davinci_evm_init(void)
struct clk *aemif_clk;
struct davinci_soc_info *soc_info = &davinci_soc_info;
+ dm644x_register_clocks();
+
ret = dm644x_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index f287577..ae17d3e 100644
--- a/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -174,6 +174,8 @@ static __init void davinci_ntosd2_init(void)
struct clk *aemif_clk;
struct davinci_soc_info *soc_info = &davinci_soc_info;
+ dm644x_register_clocks();
+
ret = dm644x_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index 2922da9..933cc08 100644
--- a/arch/arm/mach-davinci/board-sffsdr.c
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -134,6 +134,8 @@ static __init void davinci_sffsdr_init(void)
{
struct davinci_soc_info *soc_info = &davinci_soc_info;
+ dm644x_register_clocks();
+
platform_add_devices(davinci_sffsdr_devices,
ARRAY_SIZE(davinci_sffsdr_devices));
sffsdr_init_i2c();
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index c865226..2861a6f 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -107,6 +107,7 @@ int dm365_gpio_register(void);
/* DM644x function declarations */
void dm644x_init(void);
void dm644x_init_time(void);
+void dm644x_register_clocks(void);
void dm644x_init_asp(void);
int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
int dm644x_gpio_register(void);
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 71a16fc..64f5193 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -8,28 +8,31 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/serial_8250.h>
+#include <linux/clk-provider.h>
#include <linux/dmaengine.h>
-#include <linux/platform_device.h>
+#include <linux/init.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
#include <asm/mach/map.h>
+#include <mach/common.h>
#include <mach/cputype.h>
#include <mach/irqs.h>
-#include "psc.h"
#include <mach/mux.h>
-#include <mach/time.h>
#include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
+#include "asp.h"
#include "davinci.h"
-#include "clock.h"
#include "mux.h"
-#include "asp.h"
+
+#ifndef CONFIG_COMMON_CLK
+#include "clock.h"
+#include "psc.h"
+#endif
/*
* Device specific clocks
@@ -43,6 +46,7 @@
#define DM644X_EMAC_CNTRL_RAM_OFFSET 0x2000
#define DM644X_EMAC_CNTRL_RAM_SIZE 0x2000
+#ifndef CONFIG_COMMON_CLK
static struct pll_data pll1_data = {
.num = 1,
.phys_base = DAVINCI_PLL1_BASE,
@@ -326,6 +330,7 @@ static struct clk_lookup dm644x_clks[] = {
CLK("davinci-wdt", NULL, &timer2_clk),
CLK(NULL, NULL, NULL),
};
+#endif
static struct emac_platform_data dm644x_emac_pdata = {
.ctrl_reg_offset = DM644X_EMAC_CNTRL_OFFSET,
@@ -934,8 +939,68 @@ void __init dm644x_init(void)
void __init dm644x_init_time(void)
{
+#ifdef CONFIG_COMMON_CLK
+ struct clk *clk;
+
+ clk = clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM644X_REF_FREQ);
+
+ davinci_timer_init(clk);
+#else
davinci_clk_init(dm644x_clks);
davinci_timer_init(&timer0_clk);
+#endif
+}
+
+static struct resource dm644x_pll1_resources[] = {
+ {
+ .start = DAVINCI_PLL1_BASE,
+ .end = DAVINCI_PLL1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm644x_pll1_device = {
+ .name = "dm644x-pll1",
+ .id = -1,
+ .resource = dm644x_pll1_resources,
+ .num_resources = ARRAY_SIZE(dm644x_pll1_resources),
+};
+
+static struct resource dm644x_pll2_resources[] = {
+ {
+ .start = DAVINCI_PLL2_BASE,
+ .end = DAVINCI_PLL2_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm644x_pll2_device = {
+ .name = "dm644x-pll2",
+ .id = -1,
+ .resource = dm644x_pll2_resources,
+ .num_resources = ARRAY_SIZE(dm644x_pll2_resources),
+};
+
+static struct resource dm644x_psc_resources[] = {
+ {
+ .start = DAVINCI_PWR_SLEEP_CNTRL_BASE,
+ .end = DAVINCI_PWR_SLEEP_CNTRL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm644x_psc_device = {
+ .name = "dm644x-psc",
+ .id = -1,
+ .resource = dm644x_psc_resources,
+ .num_resources = ARRAY_SIZE(dm644x_psc_resources),
+};
+
+void __init dm644x_register_clocks(void)
+{
+ platform_device_register(&dm644x_pll1_device);
+ platform_device_register(&dm644x_pll2_device);
+ platform_device_register(&dm644x_psc_device);
}
int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
--
2.7.4
This adds platform-specific declarations for the PSC clocks on TI
DM365 based systems.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
---
v8 changes:
- drop use of __init and __initconst attributes
- add parent clock mappings
v7 changes:
- split registration function into two, one for each PSC
- add platform_device_id table
- don't wrap lines for readability
- add LPSC_ALWAYS_ENABLED flag to timer0 clock
v6 changes:
- change how clkdev lookups are declared
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-dm365.c | 96 +++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/psc.c | 1 +
drivers/clk/davinci/psc.h | 1 +
4 files changed, 99 insertions(+)
create mode 100644 drivers/clk/davinci/psc-dm365.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index e0da5c3..78dc1eb 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -13,4 +13,5 @@ obj-y += psc.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += psc-da830.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += psc-da850.o
obj-$(CONFIG_ARCH_DAVINCI_DM355) += psc-dm355.o
+obj-$(CONFIG_ARCH_DAVINCI_DM365) += psc-dm365.o
endif
diff --git a/drivers/clk/davinci/psc-dm365.c b/drivers/clk/davinci/psc-dm365.c
new file mode 100644
index 0000000..3ad915f
--- /dev/null
+++ b/drivers/clk/davinci/psc-dm365.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DaVinci DM365
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+LPSC_CLKDEV1(vpss_slave_clkdev, "slave", "vpss");
+LPSC_CLKDEV1(spi1_clkdev, NULL, "spi_davinci.1");
+LPSC_CLKDEV1(mmcsd1_clkdev, NULL, "da830-mmc.1");
+LPSC_CLKDEV1(asp0_clkdev, NULL, "davinci-mcbsp");
+LPSC_CLKDEV1(usb_clkdev, "usb", NULL);
+LPSC_CLKDEV1(spi2_clkdev, NULL, "spi_davinci.2");
+LPSC_CLKDEV1(aemif_clkdev, "aemif", NULL);
+LPSC_CLKDEV1(mmcsd0_clkdev, NULL, "da830-mmc.0");
+LPSC_CLKDEV1(i2c_clkdev, NULL, "i2c_davinci.1");
+LPSC_CLKDEV1(uart0_clkdev, NULL, "serial8250.0");
+LPSC_CLKDEV1(uart1_clkdev, NULL, "serial8250.1");
+LPSC_CLKDEV1(spi0_clkdev, NULL, "spi_davinci.0");
+/* REVISIT: gpio-davinci.c should be modified to drop con_id */
+LPSC_CLKDEV1(gpio_clkdev, "gpio", NULL);
+LPSC_CLKDEV1(timer0_clkdev, "timer0", NULL);
+LPSC_CLKDEV1(timer2_clkdev, NULL, "davinci-wdt");
+LPSC_CLKDEV1(spi3_clkdev, NULL, "spi_davinci.3");
+LPSC_CLKDEV1(spi4_clkdev, NULL, "spi_davinci.4");
+LPSC_CLKDEV2(emac_clkdev, NULL, "davinci_emac.1",
+ "fck", "davinci_mdio.0");
+LPSC_CLKDEV1(voice_codec_clkdev, NULL, "davinci_voicecodec");
+LPSC_CLKDEV1(vpss_dac_clkdev, "vpss_dac", NULL);
+LPSC_CLKDEV1(vpss_master_clkdev, "master", "vpss");
+
+static const struct davinci_lpsc_clk_info dm365_psc_info[] = {
+ LPSC(1, 0, vpss_slave, pll1_sysclk5, vpss_slave_clkdev, 0),
+ LPSC(5, 0, timer3, pll1_auxclk, NULL, 0),
+ LPSC(6, 0, spi1, pll1_sysclk4, spi1_clkdev, 0),
+ LPSC(7, 0, mmcsd1, pll1_sysclk4, mmcsd1_clkdev, 0),
+ LPSC(8, 0, asp0, pll1_sysclk4, asp0_clkdev, 0),
+ LPSC(9, 0, usb, pll1_auxclk, usb_clkdev, 0),
+ LPSC(10, 0, pwm3, pll1_auxclk, NULL, 0),
+ LPSC(11, 0, spi2, pll1_sysclk4, spi2_clkdev, 0),
+ LPSC(12, 0, rto, pll1_sysclk4, NULL, 0),
+ LPSC(14, 0, aemif, pll1_sysclk4, aemif_clkdev, 0),
+ LPSC(15, 0, mmcsd0, pll1_sysclk8, mmcsd0_clkdev, 0),
+ LPSC(18, 0, i2c, pll1_auxclk, i2c_clkdev, 0),
+ LPSC(19, 0, uart0, pll1_auxclk, uart0_clkdev, 0),
+ LPSC(20, 0, uart1, pll1_sysclk4, uart1_clkdev, 0),
+ LPSC(22, 0, spi0, pll1_sysclk4, spi0_clkdev, 0),
+ LPSC(23, 0, pwm0, pll1_auxclk, NULL, 0),
+ LPSC(24, 0, pwm1, pll1_auxclk, NULL, 0),
+ LPSC(25, 0, pwm2, pll1_auxclk, NULL, 0),
+ LPSC(26, 0, gpio, pll1_sysclk4, gpio_clkdev, 0),
+ LPSC(27, 0, timer0, pll1_auxclk, timer0_clkdev, LPSC_ALWAYS_ENABLED),
+ LPSC(28, 0, timer1, pll1_auxclk, NULL, 0),
+ /* REVISIT: why can't this be disabled? */
+ LPSC(29, 0, timer2, pll1_auxclk, timer2_clkdev, LPSC_ALWAYS_ENABLED),
+ LPSC(31, 0, arm, pll2_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(38, 0, spi3, pll1_sysclk4, spi3_clkdev, 0),
+ LPSC(39, 0, spi4, pll1_auxclk, spi4_clkdev, 0),
+ LPSC(40, 0, emac, pll2_sysclk4, emac_clkdev, 0),
+ LPSC(44, 1, voice_codec, pll1_sysclk3, voice_codec_clkdev, 0),
+ LPSC(46, 1, vpss_dac, pll1_sysclk3, vpss_dac_clkdev, 0),
+ LPSC(47, 0, vpss_master, pll1_sysclk5, vpss_master_clkdev, 0),
+ LPSC(50, 0, mjcp, pll1_sysclk3, NULL, 0),
+ { }
+};
+
+static int dm365_psc_init(struct device *dev, void __iomem *base)
+{
+ return davinci_psc_register_clocks(dev, dm365_psc_info, 52, base);
+}
+
+static struct clk_bulk_data dm365_psc_parent_clks[] = {
+ { .id = "pll1_sysclk1" },
+ { .id = "pll1_sysclk3" },
+ { .id = "pll1_sysclk4" },
+ { .id = "pll1_sysclk5" },
+ { .id = "pll1_sysclk8" },
+ { .id = "pll2_sysclk2" },
+ { .id = "pll2_sysclk4" },
+ { .id = "pll1_auxclk" },
+};
+
+const struct davinci_psc_init_data dm365_psc_init_data = {
+ .parent_clks = dm365_psc_parent_clks,
+ .num_parent_clks = ARRAY_SIZE(dm365_psc_parent_clks),
+ .psc_init = &dm365_psc_init,
+};
diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
index 0825b62..7bcf316 100644
--- a/drivers/clk/davinci/psc.c
+++ b/drivers/clk/davinci/psc.c
@@ -493,6 +493,7 @@ static const struct platform_device_id davinci_psc_id_table[] = {
{ .name = "da850-psc0", .driver_data = (kernel_ulong_t)&da850_psc0_init_data },
{ .name = "da850-psc1", .driver_data = (kernel_ulong_t)&da850_psc1_init_data },
{ .name = "dm355-psc", .driver_data = (kernel_ulong_t)&dm355_psc_init_data },
+ { .name = "dm365-psc", .driver_data = (kernel_ulong_t)&dm365_psc_init_data },
{ }
};
diff --git a/drivers/clk/davinci/psc.h b/drivers/clk/davinci/psc.h
index d672e72..4f6210e 100644
--- a/drivers/clk/davinci/psc.h
+++ b/drivers/clk/davinci/psc.h
@@ -101,5 +101,6 @@ extern const struct davinci_psc_init_data da850_psc1_init_data;
extern const struct davinci_psc_init_data of_da850_psc0_init_data;
extern const struct davinci_psc_init_data of_da850_psc1_init_data;
extern const struct davinci_psc_init_data dm355_psc_init_data;
+extern const struct davinci_psc_init_data dm365_psc_init_data;
#endif /* __CLK_DAVINCI_PSC_H__ */
--
2.7.4
This adds a new driver for the USB PHY clocks in the CFGCHIP2 syscon
register on TI DA8XX-type SoCs.
The USB0 (USB 2.0) PHY clock is an interesting case because it calls
clk_enable() in a reentrant way. The USB 2.0 PSC only has to be enabled
temporarily while we are locking the PLL, which takes place during the
clk_enable() callback.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- none
v7 changes:
- convert to platform device
- rename clk local variable to usb0/usb1
- put code in da8xx-cfgchip.c instead of creating a new file
v6 changes:
- rename clocks to usb{0,1}_clk48
- rename USB 2.0 PSC clock to "fck"
- simplify {s,g}et_parent implementations
- use pr_fmt macro
drivers/clk/davinci/da8xx-cfgchip.c | 351 ++++++++++++++++++++++++++++++++++++
1 file changed, 351 insertions(+)
diff --git a/drivers/clk/davinci/da8xx-cfgchip.c b/drivers/clk/davinci/da8xx-cfgchip.c
index f0bdfea..858d378 100644
--- a/drivers/clk/davinci/da8xx-cfgchip.c
+++ b/drivers/clk/davinci/da8xx-cfgchip.c
@@ -343,6 +343,349 @@ static int __init of_da850_async3_init(struct device *dev, struct regmap *regmap
return of_da8xx_cfgchip_init_mux_clock(dev, &da850_async3_info, regmap);
}
+/* --- USB 2.0 PHY clock --- */
+
+struct da8xx_usb0_clk48 {
+ struct clk_hw hw;
+ struct clk *fck;
+ struct regmap *regmap;
+};
+
+#define to_da8xx_usb0_clk48(_hw) \
+ container_of((_hw), struct da8xx_usb0_clk48, hw)
+
+static int da8xx_usb0_clk48_prepare(struct clk_hw *hw)
+{
+ struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
+
+ /* The USB 2.0 PSC clock is only needed temporarily during the USB 2.0
+ * PHY clock enable, but since clk_prepare() can't be called in an
+ * atomic context (i.e. in clk_enable()), we have to prepare it here.
+ */
+ return clk_prepare(usb0->fck);
+}
+
+static void da8xx_usb0_clk48_unprepare(struct clk_hw *hw)
+{
+ struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
+
+ clk_unprepare(usb0->fck);
+}
+
+static int da8xx_usb0_clk48_enable(struct clk_hw *hw)
+{
+ struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
+ unsigned int mask, val;
+ int ret;
+
+ /* Locking the USB 2.O PLL requires that the USB 2.O PSC is enabled
+ * temporaily. It can be turned back off once the PLL is locked.
+ */
+ clk_enable(usb0->fck);
+
+ /* Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
+ * PHY may use the USB 2.0 PLL clock without USB 2.0 OTG being used.
+ */
+ mask = CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_PHY_PLLON;
+ val = CFGCHIP2_PHY_PLLON;
+
+ regmap_write_bits(usb0->regmap, CFGCHIP(2), mask, val);
+ ret = regmap_read_poll_timeout(usb0->regmap, CFGCHIP(2), val,
+ val & CFGCHIP2_PHYCLKGD, 0, 500000);
+
+ clk_disable(usb0->fck);
+
+ return ret;
+}
+
+static void da8xx_usb0_clk48_disable(struct clk_hw *hw)
+{
+ struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
+ unsigned int val;
+
+ val = CFGCHIP2_PHYPWRDN;
+ regmap_write_bits(usb0->regmap, CFGCHIP(2), val, val);
+}
+
+static int da8xx_usb0_clk48_is_enabled(struct clk_hw *hw)
+{
+ struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
+ unsigned int val;
+
+ regmap_read(usb0->regmap, CFGCHIP(2), &val);
+
+ return !!(val & CFGCHIP2_PHYCLKGD);
+}
+
+static unsigned long da8xx_usb0_clk48_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
+ unsigned int mask, val;
+
+ /* The parent clock rate must be one of the following */
+ mask = CFGCHIP2_REFFREQ_MASK;
+ switch (parent_rate) {
+ case 12000000:
+ val = CFGCHIP2_REFFREQ_12MHZ;
+ break;
+ case 13000000:
+ val = CFGCHIP2_REFFREQ_13MHZ;
+ break;
+ case 19200000:
+ val = CFGCHIP2_REFFREQ_19_2MHZ;
+ break;
+ case 20000000:
+ val = CFGCHIP2_REFFREQ_20MHZ;
+ break;
+ case 24000000:
+ val = CFGCHIP2_REFFREQ_24MHZ;
+ break;
+ case 26000000:
+ val = CFGCHIP2_REFFREQ_26MHZ;
+ break;
+ case 38400000:
+ val = CFGCHIP2_REFFREQ_38_4MHZ;
+ break;
+ case 40000000:
+ val = CFGCHIP2_REFFREQ_40MHZ;
+ break;
+ case 48000000:
+ val = CFGCHIP2_REFFREQ_48MHZ;
+ break;
+ default:
+ return 0;
+ }
+
+ regmap_write_bits(usb0->regmap, CFGCHIP(2), mask, val);
+
+ /* USB 2.0 PLL always supplies 48MHz */
+ return 48000000;
+}
+
+static long da8xx_usb0_clk48_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ return 48000000;
+}
+
+static int da8xx_usb0_clk48_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
+
+ return regmap_write_bits(usb0->regmap, CFGCHIP(2),
+ CFGCHIP2_USB2PHYCLKMUX,
+ index ? CFGCHIP2_USB2PHYCLKMUX : 0);
+}
+
+static u8 da8xx_usb0_clk48_get_parent(struct clk_hw *hw)
+{
+ struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
+ unsigned int val;
+
+ regmap_read(usb0->regmap, CFGCHIP(2), &val);
+
+ return (val & CFGCHIP2_USB2PHYCLKMUX) ? 1 : 0;
+}
+
+static const struct clk_ops da8xx_usb0_clk48_ops = {
+ .prepare = da8xx_usb0_clk48_prepare,
+ .unprepare = da8xx_usb0_clk48_unprepare,
+ .enable = da8xx_usb0_clk48_enable,
+ .disable = da8xx_usb0_clk48_disable,
+ .is_enabled = da8xx_usb0_clk48_is_enabled,
+ .recalc_rate = da8xx_usb0_clk48_recalc_rate,
+ .round_rate = da8xx_usb0_clk48_round_rate,
+ .set_parent = da8xx_usb0_clk48_set_parent,
+ .get_parent = da8xx_usb0_clk48_get_parent,
+};
+
+static struct da8xx_usb0_clk48 *
+da8xx_cfgchip_register_usb0_clk48(struct device *dev,
+ struct regmap *regmap)
+{
+ const char * const parent_names[] = { "usb_refclkin", "pll0_auxclk" };
+ struct clk *fck_clk;
+ struct da8xx_usb0_clk48 *usb0;
+ struct clk_init_data init;
+ int ret;
+
+ fck_clk = devm_clk_get(dev, "fck");
+ if (IS_ERR(fck_clk)) {
+ if (PTR_ERR(fck_clk) != -EPROBE_DEFER)
+ dev_err(dev, "Missing fck clock\n");
+ return ERR_CAST(fck_clk);
+ }
+
+ usb0 = devm_kzalloc(dev, sizeof(*usb0), GFP_KERNEL);
+ if (!usb0)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = "usb0_clk48";
+ init.ops = &da8xx_usb0_clk48_ops;
+ init.parent_names = parent_names;
+ init.num_parents = 2;
+
+ usb0->hw.init = &init;
+ usb0->fck = fck_clk;
+ usb0->regmap = regmap;
+
+ ret = devm_clk_hw_register(dev, &usb0->hw);
+ if (ret < 0)
+ return ERR_PTR(ret);
+
+ return usb0;
+}
+
+/* --- USB 1.1 PHY clock --- */
+
+struct da8xx_usb1_clk48 {
+ struct clk_hw hw;
+ struct regmap *regmap;
+};
+
+#define to_da8xx_usb1_clk48(_hw) \
+ container_of((_hw), struct da8xx_usb1_clk48, hw)
+
+static int da8xx_usb1_clk48_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct da8xx_usb1_clk48 *usb1 = to_da8xx_usb1_clk48(hw);
+
+ return regmap_write_bits(usb1->regmap, CFGCHIP(2),
+ CFGCHIP2_USB1PHYCLKMUX,
+ index ? CFGCHIP2_USB1PHYCLKMUX : 0);
+}
+
+static u8 da8xx_usb1_clk48_get_parent(struct clk_hw *hw)
+{
+ struct da8xx_usb1_clk48 *usb1 = to_da8xx_usb1_clk48(hw);
+ unsigned int val;
+
+ regmap_read(usb1->regmap, CFGCHIP(2), &val);
+
+ return (val & CFGCHIP2_USB1PHYCLKMUX) ? 1 : 0;
+}
+
+static const struct clk_ops da8xx_usb1_clk48_ops = {
+ .set_parent = da8xx_usb1_clk48_set_parent,
+ .get_parent = da8xx_usb1_clk48_get_parent,
+};
+
+/**
+ * da8xx_cfgchip_register_usb1_clk48 - Register a new USB 1.1 PHY clock
+ * @regmap: The CFGCHIP regmap
+ */
+static struct da8xx_usb1_clk48 *
+da8xx_cfgchip_register_usb1_clk48(struct device *dev,
+ struct regmap *regmap)
+{
+ const char * const parent_names[] = { "usb0_clk48", "usb_refclkin" };
+ struct da8xx_usb1_clk48 *usb1;
+ struct clk_init_data init;
+ int ret;
+
+ usb1 = devm_kzalloc(dev, sizeof(*usb1), GFP_KERNEL);
+ if (!usb1)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = "usb1_clk48";
+ init.ops = &da8xx_usb1_clk48_ops;
+ init.parent_names = parent_names;
+ init.num_parents = 2;
+
+ usb1->hw.init = &init;
+ usb1->regmap = regmap;
+
+ ret = devm_clk_hw_register(dev, &usb1->hw);
+ if (ret < 0)
+ return ERR_PTR(ret);
+
+ return usb1;
+}
+
+static int da8xx_cfgchip_register_usb_phy_clk(struct device *dev,
+ struct regmap *regmap)
+{
+ struct da8xx_usb0_clk48 *usb0;
+ struct da8xx_usb1_clk48 *usb1;
+ struct clk_hw *parent;
+
+ usb0 = da8xx_cfgchip_register_usb0_clk48(dev, regmap);
+ if (IS_ERR(usb0))
+ return PTR_ERR(usb0);
+
+ /*
+ * All existing boards use pll0_auxclk as the parent and new boards
+ * should use device tree, so hard-coding the value (1) here.
+ */
+ parent = clk_hw_get_parent_by_index(&usb0->hw, 1);
+ if (parent)
+ clk_set_parent(usb0->hw.clk, parent->clk);
+ else
+ dev_warn(dev, "Failed to find usb0 parent clock\n");
+
+ usb1 = da8xx_cfgchip_register_usb1_clk48(dev, regmap);
+ if (IS_ERR(usb1))
+ return PTR_ERR(usb1);
+
+ /*
+ * All existing boards use usb0_clk48 as the parent and new boards
+ * should use device tree, so hard-coding the value (0) here.
+ */
+ parent = clk_hw_get_parent_by_index(&usb1->hw, 0);
+ if (parent)
+ clk_set_parent(usb1->hw.clk, parent->clk);
+ else
+ dev_warn(dev, "Failed to find usb1 parent clock\n");
+
+ clk_hw_register_clkdev(&usb0->hw, "usb0_clk48", "da8xx-usb-phy");
+ clk_hw_register_clkdev(&usb1->hw, "usb1_clk48", "da8xx-usb-phy");
+
+ return 0;
+}
+
+static int of_da8xx_usb_phy_clk_init(struct device *dev, struct regmap *regmap)
+{
+ struct clk_hw_onecell_data *clk_data;
+ struct da8xx_usb0_clk48 *usb0;
+ struct da8xx_usb1_clk48 *usb1;
+
+ clk_data = devm_kzalloc(dev, sizeof(*clk_data) + 2 *
+ sizeof(*clk_data->hws), GFP_KERNEL);
+ if (!clk_data)
+ return -ENOMEM;
+
+ clk_data->num = 2;
+
+ usb0 = da8xx_cfgchip_register_usb0_clk48(dev, regmap);
+ if (IS_ERR(usb0)) {
+ if (PTR_ERR(usb0) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ dev_warn(dev, "Failed to register usb0_clk48 (%ld)\n",
+ PTR_ERR(usb0));
+
+ clk_data->hws[0] = ERR_PTR(-ENOENT);
+ } else {
+ clk_data->hws[0] = &usb0->hw;
+ }
+
+ usb1 = da8xx_cfgchip_register_usb1_clk48(dev, regmap);
+ if (IS_ERR(usb1)) {
+ if (PTR_ERR(usb0) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ dev_warn(dev, "Failed to register usb1_clk48 (%ld)\n",
+ PTR_ERR(usb1));
+
+ clk_data->hws[1] = ERR_PTR(-ENOENT);
+ } else {
+ clk_data->hws[1] = &usb1->hw;
+ }
+
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
+}
+
/* --- platform device --- */
static const struct of_device_id da8xx_cfgchip_of_match[] = {
@@ -362,6 +705,10 @@ static const struct of_device_id da8xx_cfgchip_of_match[] = {
.compatible = "ti,da850-async3-clksrc",
.data = of_da850_async3_init,
},
+ {
+ .compatible = "ti,da830-usb-phy-clocks",
+ .data = of_da8xx_usb_phy_clk_init,
+ },
{ }
};
@@ -382,6 +729,10 @@ static const struct platform_device_id da8xx_cfgchip_id_table[] = {
.name = "da850-async3-clksrc",
.driver_data = (kernel_ulong_t)da850_cfgchip_register_async3,
},
+ {
+ .name = "da830-usb-phy-clks",
+ .driver_data = (kernel_ulong_t)da8xx_cfgchip_register_usb_phy_clk,
+ },
{ }
};
--
2.7.4
This adds a new binding for the clocks present in the CFGCHIP syscon
registers in TI DA8XX SoCs.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
---
v8 changes:
- none
v7 changes:
- none
v6 changes:
- combine "dt-bindings: clock: Add bindings for DA8XX CFGCHIP gate clocks",
"dt-bindings: clock: Add binding for TI DA8XX CFGCHIP mux clocks" and
"dt-bindings: clock: Add bindings for TI DA8XX USB PHY clocks" into a single
file containing all CFGCHIP clocks bindings
- added compatible = "ti,da830-div4p5ena"
- added compatible = "ti,da850-async1-clksrc"
- renamed other compatible strings
- changed and added some clk-names strings
- USB PHY clocks are combined into a single node with #clock-cells = <1>
.../bindings/clock/ti/davinci/da8xx-cfgchip.txt | 93 ++++++++++++++++++++++
1 file changed, 93 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip.txt
diff --git a/Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip.txt b/Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip.txt
new file mode 100644
index 0000000..1e03dce
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip.txt
@@ -0,0 +1,93 @@
+Binding for TI DA8XX/OMAP-L13X/AM17XX/AM18XX CFGCHIP clocks
+
+TI DA8XX/OMAP-L13X/AM17XX/AM18XX SoCs contain a general purpose set of
+registers call CFGCHIPn. Some of these registers function as clock
+gates. This document describes the bindings for those clocks.
+
+All of the clock nodes described below must be child nodes of a CFGCHIP node
+(compatible = "ti,da830-cfgchip").
+
+USB PHY clocks
+--------------
+Required properties:
+- compatible: shall be "ti,da830-usb-phy-clocks".
+- #clock-cells: from common clock binding; shall be set to 1.
+- clocks: phandles to the parent clocks corresponding to clock-names
+- clock-names: shall be "fck", "usb_refclkin", "auxclk"
+
+This node provides two clocks. The clock at index 0 is the USB 2.0 PHY 48MHz
+clock and the clock at index 1 is the USB 1.1 PHY 48MHz clock.
+
+eHRPWM Time Base Clock (TBCLK)
+------------------------------
+Required properties:
+- compatible: shall be "ti,da830-tbclksync".
+- #clock-cells: from common clock binding; shall be set to 0.
+- clocks: phandle to the parent clock
+- clock-names: shall be "fck"
+
+PLL DIV4.5 divider
+------------------
+Required properties:
+- compatible: shall be "ti,da830-div4p5ena".
+- #clock-cells: from common clock binding; shall be set to 0.
+- clocks: phandle to the parent clock
+- clock-names: shall be "pll0_pllout"
+
+EMIFA clock source (ASYNC1)
+---------------------------
+Required properties:
+- compatible: shall be "ti,da850-async1-clksrc".
+- #clock-cells: from common clock binding; shall be set to 0.
+- clocks: phandles to the parent clocks corresponding to clock-names
+- clock-names: shall be "pll0_sysclk3", "div4.5"
+
+ASYNC3 clock source
+-------------------
+Required properties:
+- compatible: shall be "ti,da850-async3-clksrc".
+- #clock-cells: from common clock binding; shall be set to 0.
+- clocks: phandles to the parent clocks corresponding to clock-names
+- clock-names: shall be "pll0_sysclk2", "pll1_sysclk2"
+
+Examples:
+
+ cfgchip: syscon@1417c {
+ compatible = "ti,da830-cfgchip", "syscon", "simple-mfd";
+ reg = <0x1417c 0x14>;
+
+ usb_phy_clk: usb-phy-clocks {
+ compatible = "ti,da830-usb-phy-clocks";
+ #clock-cells = <1>;
+ clocks = <&psc1 1>, <&usb_refclkin>, <&pll0_auxclk>;
+ clock-names = "fck", "usb_refclkin", "auxclk";
+ };
+ ehrpwm_tbclk: ehrpwm_tbclk {
+ compatible = "ti,da830-tbclksync";
+ #clock-cells = <0>;
+ clocks = <&psc1 17>;
+ clock-names = "fck";
+ };
+ div4p5_clk: div4.5 {
+ compatible = "ti,da830-div4p5ena";
+ #clock-cells = <0>;
+ clocks = <&pll0_pllout>;
+ clock-names = "pll0_pllout";
+ };
+ async1_clk: async1 {
+ compatible = "ti,da850-async1-clksrc";
+ #clock-cells = <0>;
+ clocks = <&pll0_sysclk 3>, <&div4p5_clk>;
+ clock-names = "pll0_sysclk3", "div4.5";
+ };
+ async3_clk: async3 {
+ compatible = "ti,da850-async3-clksrc";
+ #clock-cells = <0>;
+ clocks = <&pll0_sysclk 2>, <&pll1_sysclk 2>;
+ clock-names = "pll0_sysclk2", "pll1_sysclk2";
+ };
+ };
+
+Also see:
+- Documentation/devicetree/bindings/clock/clock-bindings.txt
+
--
2.7.4
This adds platform-specific declarations for the PSC clocks on TI DA830/
OMAP-L137/AM17XX SoCs.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- drop use of __init and __initconst attributes
- add parent clock mappings
v7 changes:
- split registration function into two, one for each PSC
- add platform_device_id table
v6 changes:
- change how clkdev lookups are declared
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-da830.c | 116 ++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/psc.c | 2 +
drivers/clk/davinci/psc.h | 3 ++
4 files changed, 122 insertions(+)
create mode 100644 drivers/clk/davinci/psc-da830.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index cd1bf2c..fb14c8c 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -10,4 +10,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DM644x) += pll-dm644x.o
obj-$(CONFIG_ARCH_DAVINCI_DM646x) += pll-dm646x.o
obj-y += psc.o
+obj-$(CONFIG_ARCH_DAVINCI_DA830) += psc-da830.o
endif
diff --git a/drivers/clk/davinci/psc-da830.c b/drivers/clk/davinci/psc-da830.c
new file mode 100644
index 0000000..f61abf5
--- /dev/null
+++ b/drivers/clk/davinci/psc-da830.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DA830/OMAP-L137/AM17XX
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+LPSC_CLKDEV1(spi0_clkdev, NULL, "spi_davinci.0");
+LPSC_CLKDEV1(mmcsd_clkdev, NULL, "da830-mmc.0");
+LPSC_CLKDEV1(uart0_clkdev, NULL, "serial8250.0");
+
+static const struct davinci_lpsc_clk_info da830_psc0_info[] = {
+ LPSC(0, 0, tpcc, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(1, 0, tptc0, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(2, 0, tptc1, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(3, 0, aemif, pll0_sysclk3, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(4, 0, spi0, pll0_sysclk2, spi0_clkdev, 0),
+ LPSC(5, 0, mmcsd, pll0_sysclk2, mmcsd_clkdev, 0),
+ LPSC(6, 0, aintc, pll0_sysclk4, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(7, 0, arm_rom, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(8, 0, secu_mgr, pll0_sysclk4, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(9, 0, uart0, pll0_sysclk2, uart0_clkdev, 0),
+ LPSC(10, 0, scr0_ss, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(11, 0, scr1_ss, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(12, 0, scr2_ss, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(13, 0, pruss, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(14, 0, arm, pll0_sysclk6, NULL, LPSC_ALWAYS_ENABLED),
+ { }
+};
+
+static int da830_psc0_init(struct device *dev, void __iomem *base)
+{
+ return davinci_psc_register_clocks(dev, da830_psc0_info, 16, base);
+}
+
+static struct clk_bulk_data da830_psc0_parent_clks[] = {
+ { .id = "pll0_sysclk2" },
+ { .id = "pll0_sysclk3" },
+ { .id = "pll0_sysclk4" },
+ { .id = "pll0_sysclk6" },
+};
+
+const struct davinci_psc_init_data da830_psc0_init_data = {
+ .parent_clks = da830_psc0_parent_clks,
+ .num_parent_clks = ARRAY_SIZE(da830_psc0_parent_clks),
+ .psc_init = &da830_psc0_init,
+};
+
+LPSC_CLKDEV2(usb0_clkdev, NULL, "musb-da8xx",
+ NULL, "cppi41-dmaengine");
+LPSC_CLKDEV1(usb1_clkdev, NULL, "ohci-da8xx");
+/* REVISIT: gpio-davinci.c should be modified to drop con_id */
+LPSC_CLKDEV1(gpio_clkdev, "gpio", NULL);
+LPSC_CLKDEV2(emac_clkdev, NULL, "davinci_emac.1",
+ "fck", "davinci_mdio.0");
+LPSC_CLKDEV1(mcasp0_clkdev, NULL, "davinci-mcasp.0");
+LPSC_CLKDEV1(mcasp1_clkdev, NULL, "davinci-mcasp.1");
+LPSC_CLKDEV1(mcasp2_clkdev, NULL, "davinci-mcasp.2");
+LPSC_CLKDEV1(spi1_clkdev, NULL, "spi_davinci.1");
+LPSC_CLKDEV1(i2c1_clkdev, NULL, "i2c_davinci.2");
+LPSC_CLKDEV1(uart1_clkdev, NULL, "serial8250.1");
+LPSC_CLKDEV1(uart2_clkdev, NULL, "serial8250.2");
+LPSC_CLKDEV1(lcdc_clkdev, "fck", "da8xx_lcdc.0");
+LPSC_CLKDEV2(pwm_clkdev, "fck", "ehrpwm.0",
+ "fck", "ehrpwm.1");
+LPSC_CLKDEV3(ecap_clkdev, "fck", "ecap.0",
+ "fck", "ecap.1",
+ "fck", "ecap.2");
+LPSC_CLKDEV2(eqep_clkdev, NULL, "eqep.0",
+ NULL, "eqep.1");
+
+static const struct davinci_lpsc_clk_info da830_psc1_info[] = {
+ LPSC(1, 0, usb0, pll0_sysclk2, usb0_clkdev, 0),
+ LPSC(2, 0, usb1, pll0_sysclk4, usb1_clkdev, 0),
+ LPSC(3, 0, gpio, pll0_sysclk4, gpio_clkdev, 0),
+ LPSC(5, 0, emac, pll0_sysclk4, emac_clkdev, 0),
+ LPSC(6, 0, emif3, pll0_sysclk5, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(7, 0, mcasp0, pll0_sysclk2, mcasp0_clkdev, 0),
+ LPSC(8, 0, mcasp1, pll0_sysclk2, mcasp1_clkdev, 0),
+ LPSC(9, 0, mcasp2, pll0_sysclk2, mcasp2_clkdev, 0),
+ LPSC(10, 0, spi1, pll0_sysclk2, spi1_clkdev, 0),
+ LPSC(11, 0, i2c1, pll0_sysclk4, i2c1_clkdev, 0),
+ LPSC(12, 0, uart1, pll0_sysclk2, uart1_clkdev, 0),
+ LPSC(13, 0, uart2, pll0_sysclk2, uart2_clkdev, 0),
+ LPSC(16, 0, lcdc, pll0_sysclk2, lcdc_clkdev, 0),
+ LPSC(17, 0, pwm, pll0_sysclk2, pwm_clkdev, 0),
+ LPSC(20, 0, ecap, pll0_sysclk2, ecap_clkdev, 0),
+ LPSC(21, 0, eqep, pll0_sysclk2, eqep_clkdev, 0),
+ { }
+};
+
+static int da830_psc1_init(struct device *dev, void __iomem *base)
+{
+ return davinci_psc_register_clocks(dev, da830_psc1_info, 32, base);
+}
+
+static struct clk_bulk_data da830_psc1_parent_clks[] = {
+ { .id = "pll0_sysclk2" },
+ { .id = "pll0_sysclk4" },
+ { .id = "pll0_sysclk5" },
+};
+
+const struct davinci_psc_init_data da830_psc1_init_data = {
+ .parent_clks = da830_psc1_parent_clks,
+ .num_parent_clks = ARRAY_SIZE(da830_psc1_parent_clks),
+ .psc_init = &da830_psc1_init,
+};
diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
index 5613607..d4cff87 100644
--- a/drivers/clk/davinci/psc.c
+++ b/drivers/clk/davinci/psc.c
@@ -486,6 +486,8 @@ static const struct of_device_id davinci_psc_of_match[] = {
};
static const struct platform_device_id davinci_psc_id_table[] = {
+ { .name = "da830-psc0", .driver_data = (kernel_ulong_t)&da830_psc0_init_data },
+ { .name = "da830-psc1", .driver_data = (kernel_ulong_t)&da830_psc1_init_data },
{ }
};
diff --git a/drivers/clk/davinci/psc.h b/drivers/clk/davinci/psc.h
index 4240134..852e9aa 100644
--- a/drivers/clk/davinci/psc.h
+++ b/drivers/clk/davinci/psc.h
@@ -94,4 +94,7 @@ struct davinci_psc_init_data {
int (*psc_init)(struct device *dev, void __iomem *base);
};
+extern const struct davinci_psc_init_data da830_psc0_init_data;
+extern const struct davinci_psc_init_data da830_psc1_init_data;
+
#endif /* __CLK_DAVINCI_PSC_H__ */
--
2.7.4
This adds platform-specific declarations for the PSC clocks on TI DA850/
OMAP-L138/AM18XX SoCs.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
---
v8 changes:
- drop use of __init and __initconst attributes
- add parent clock mappings
v7 changes:
- split registration function into two, one for each PSC
- add platform_device_id table
- add additional clkdev lookups for clock platform devices
- add LPSC_SET_RATE_PARENT flag to LCDC clock
- fix davinci_nand device name
v6 changes:
- change how clkdev lookups are declared
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-da850.c | 149 ++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/psc.c | 4 ++
drivers/clk/davinci/psc.h | 4 ++
4 files changed, 158 insertions(+)
create mode 100644 drivers/clk/davinci/psc-da850.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index fb14c8c..aef0390 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -11,4 +11,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DM646x) += pll-dm646x.o
obj-y += psc.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += psc-da830.o
+obj-$(CONFIG_ARCH_DAVINCI_DA850) += psc-da850.o
endif
diff --git a/drivers/clk/davinci/psc-da850.c b/drivers/clk/davinci/psc-da850.c
new file mode 100644
index 0000000..dca2dd2
--- /dev/null
+++ b/drivers/clk/davinci/psc-da850.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DA850/OMAP-L138/AM18XX
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+LPSC_CLKDEV2(emifa_clkdev, NULL, "ti-aemif",
+ "aemif", "davinci_nand.0");
+LPSC_CLKDEV1(spi0_clkdev, NULL, "spi_davinci.0");
+LPSC_CLKDEV1(mmcsd0_clkdev, NULL, "da830-mmc.0");
+LPSC_CLKDEV1(uart0_clkdev, NULL, "serial8250.0");
+/* REVISIT: used dev_id instead of con_id */
+LPSC_CLKDEV1(arm_clkdev, "arm", NULL);
+LPSC_CLKDEV1(dsp_clkdev, NULL, "davinci-rproc.0");
+
+static const struct davinci_lpsc_clk_info da850_psc0_info[] = {
+ LPSC(0, 0, tpcc0, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(1, 0, tptc0, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(2, 0, tptc1, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(3, 0, emifa, async1, emifa_clkdev, 0),
+ LPSC(4, 0, spi0, pll0_sysclk2, spi0_clkdev, 0),
+ LPSC(5, 0, mmcsd0, pll0_sysclk2, mmcsd0_clkdev, 0),
+ LPSC(6, 0, aintc, pll0_sysclk4, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(7, 0, arm_rom, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(9, 0, uart0, pll0_sysclk2, uart0_clkdev, 0),
+ LPSC(13, 0, pruss, pll0_sysclk2, NULL, 0),
+ LPSC(14, 0, arm, pll0_sysclk6, arm_clkdev, LPSC_ALWAYS_ENABLED | LPSC_SET_RATE_PARENT),
+ LPSC(15, 1, dsp, pll0_sysclk1, dsp_clkdev, LPSC_FORCE | LPSC_LOCAL_RESET),
+ { }
+};
+
+LPSC_CLKDEV3(usb0_clkdev, "fck", "da830-usb-phy-clks",
+ NULL, "musb-da8xx",
+ NULL, "cppi41-dmaengine");
+LPSC_CLKDEV1(usb1_clkdev, NULL, "ohci-da8xx");
+/* REVISIT: gpio-davinci.c should be modified to drop con_id */
+LPSC_CLKDEV1(gpio_clkdev, "gpio", NULL);
+LPSC_CLKDEV2(emac_clkdev, NULL, "davinci_emac.1",
+ "fck", "davinci_mdio.0");
+LPSC_CLKDEV1(mcasp0_clkdev, NULL, "davinci-mcasp.0");
+LPSC_CLKDEV1(sata_clkdev, "fck", "ahci_da850");
+LPSC_CLKDEV1(vpif_clkdev, NULL, "vpif");
+LPSC_CLKDEV1(spi1_clkdev, NULL, "spi_davinci.1");
+LPSC_CLKDEV1(i2c1_clkdev, NULL, "i2c_davinci.2");
+LPSC_CLKDEV1(uart1_clkdev, NULL, "serial8250.1");
+LPSC_CLKDEV1(uart2_clkdev, NULL, "serial8250.2");
+LPSC_CLKDEV1(mcbsp0_clkdev, NULL, "davinci-mcbsp.0");
+LPSC_CLKDEV1(mcbsp1_clkdev, NULL, "davinci-mcbsp.1");
+LPSC_CLKDEV1(lcdc_clkdev, "fck", "da8xx_lcdc.0");
+LPSC_CLKDEV3(ehrpwm_clkdev, "fck", "ehrpwm.0",
+ "fck", "ehrpwm.1",
+ NULL, "da830-tbclksync");
+LPSC_CLKDEV1(mmcsd1_clkdev, NULL, "da830-mmc.1");
+LPSC_CLKDEV3(ecap_clkdev, "fck", "ecap.0",
+ "fck", "ecap.1",
+ "fck", "ecap.2");
+
+static int da850_psc0_init(struct device *dev, void __iomem *base)
+{
+ return davinci_psc_register_clocks(dev, da850_psc0_info, 16, base);
+}
+
+static int of_da850_psc0_init(struct device *dev, void __iomem *base)
+{
+ return of_davinci_psc_clk_init(dev, da850_psc0_info, 16, base);
+}
+
+static struct clk_bulk_data da850_psc0_parent_clks[] = {
+ { .id = "pll0_sysclk1" },
+ { .id = "pll0_sysclk2" },
+ { .id = "pll0_sysclk4" },
+ { .id = "pll0_sysclk6" },
+ { .id = "async1" },
+};
+
+const struct davinci_psc_init_data da850_psc0_init_data = {
+ .parent_clks = da850_psc0_parent_clks,
+ .num_parent_clks = ARRAY_SIZE(da850_psc0_parent_clks),
+ .psc_init = &da850_psc0_init,
+};
+
+const struct davinci_psc_init_data of_da850_psc0_init_data = {
+ .parent_clks = da850_psc0_parent_clks,
+ .num_parent_clks = ARRAY_SIZE(da850_psc0_parent_clks),
+ .psc_init = &of_da850_psc0_init,
+};
+
+static const struct davinci_lpsc_clk_info da850_psc1_info[] = {
+ LPSC(0, 0, tpcc1, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(1, 0, usb0, pll0_sysclk2, usb0_clkdev, 0),
+ LPSC(2, 0, usb1, pll0_sysclk4, usb1_clkdev, 0),
+ LPSC(3, 0, gpio, pll0_sysclk4, gpio_clkdev, 0),
+ LPSC(5, 0, emac, pll0_sysclk4, emac_clkdev, 0),
+ LPSC(6, 0, ddr, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(7, 0, mcasp0, async3, mcasp0_clkdev, 0),
+ LPSC(8, 0, sata, pll0_sysclk2, sata_clkdev, LPSC_FORCE),
+ LPSC(9, 0, vpif, pll0_sysclk2, vpif_clkdev, 0),
+ LPSC(10, 0, spi1, async3, spi1_clkdev, 0),
+ LPSC(11, 0, i2c1, pll0_sysclk4, i2c1_clkdev, 0),
+ LPSC(12, 0, uart1, async3, uart1_clkdev, 0),
+ LPSC(13, 0, uart2, async3, uart2_clkdev, 0),
+ LPSC(14, 0, mcbsp0, async3, mcbsp0_clkdev, 0),
+ LPSC(15, 0, mcbsp1, async3, mcbsp1_clkdev, 0),
+ LPSC(16, 0, lcdc, pll0_sysclk2, lcdc_clkdev, 0),
+ LPSC(17, 0, ehrpwm, async3, ehrpwm_clkdev, 0),
+ LPSC(18, 0, mmcsd1, pll0_sysclk2, mmcsd1_clkdev, 0),
+ LPSC(20, 0, ecap, async3, ecap_clkdev, 0),
+ LPSC(21, 0, tptc2, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ { }
+};
+
+static int da850_psc1_init(struct device *dev, void __iomem *base)
+{
+ return davinci_psc_register_clocks(dev, da850_psc1_info, 32, base);
+}
+
+static int of_da850_psc1_init(struct device *dev, void __iomem *base)
+{
+ return of_davinci_psc_clk_init(dev, da850_psc1_info, 32, base);
+}
+
+static struct clk_bulk_data da850_psc1_parent_clks[] = {
+ { .id = "pll0_sysclk2" },
+ { .id = "pll0_sysclk4" },
+ { .id = "async3" },
+};
+
+const struct davinci_psc_init_data da850_psc1_init_data = {
+ .parent_clks = da850_psc1_parent_clks,
+ .num_parent_clks = ARRAY_SIZE(da850_psc1_parent_clks),
+ .psc_init = &da850_psc1_init,
+};
+
+const struct davinci_psc_init_data of_da850_psc1_init_data = {
+ .parent_clks = da850_psc1_parent_clks,
+ .num_parent_clks = ARRAY_SIZE(da850_psc1_parent_clks),
+ .psc_init = &of_da850_psc1_init,
+};
diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
index d4cff87..fa39536 100644
--- a/drivers/clk/davinci/psc.c
+++ b/drivers/clk/davinci/psc.c
@@ -482,12 +482,16 @@ int of_davinci_psc_clk_init(struct device *dev,
}
static const struct of_device_id davinci_psc_of_match[] = {
+ { .compatible = "ti,da850-psc0", .data = &of_da850_psc0_init_data },
+ { .compatible = "ti,da850-psc1", .data = &of_da850_psc1_init_data },
{ }
};
static const struct platform_device_id davinci_psc_id_table[] = {
{ .name = "da830-psc0", .driver_data = (kernel_ulong_t)&da830_psc0_init_data },
{ .name = "da830-psc1", .driver_data = (kernel_ulong_t)&da830_psc1_init_data },
+ { .name = "da850-psc0", .driver_data = (kernel_ulong_t)&da850_psc0_init_data },
+ { .name = "da850-psc1", .driver_data = (kernel_ulong_t)&da850_psc1_init_data },
{ }
};
diff --git a/drivers/clk/davinci/psc.h b/drivers/clk/davinci/psc.h
index 852e9aa..476bd74 100644
--- a/drivers/clk/davinci/psc.h
+++ b/drivers/clk/davinci/psc.h
@@ -96,5 +96,9 @@ struct davinci_psc_init_data {
extern const struct davinci_psc_init_data da830_psc0_init_data;
extern const struct davinci_psc_init_data da830_psc1_init_data;
+extern const struct davinci_psc_init_data da850_psc0_init_data;
+extern const struct davinci_psc_init_data da850_psc1_init_data;
+extern const struct davinci_psc_init_data of_da850_psc0_init_data;
+extern const struct davinci_psc_init_data of_da850_psc1_init_data;
#endif /* __CLK_DAVINCI_PSC_H__ */
--
2.7.4
This adds platform-specific declarations for the PLL clocks on TI
DM644x based systems.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- drop __init and __initconst attributes
- add a clkdev lookup for each SYSCLK
v7 changes:
- split registration functions for each PLL
- Add platform_device_id lookup
v6 changes:
- Added dm644x_pll{1,2}_info with controller-specific information
- Add empty lines between function calls
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-dm644x.c | 80 ++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/pll.c | 2 +
drivers/clk/davinci/pll.h | 3 ++
4 files changed, 86 insertions(+)
create mode 100644 drivers/clk/davinci/pll-dm644x.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index 353aa02..59d8ab6 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -6,4 +6,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DA830) += pll-da830.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o
obj-$(CONFIG_ARCH_DAVINCI_DM355) += pll-dm355.o
obj-$(CONFIG_ARCH_DAVINCI_DM365) += pll-dm365.o
+obj-$(CONFIG_ARCH_DAVINCI_DM644x) += pll-dm644x.o
endif
diff --git a/drivers/clk/davinci/pll-dm644x.c b/drivers/clk/davinci/pll-dm644x.c
new file mode 100644
index 0000000..69bf785
--- /dev/null
+++ b/drivers/clk/davinci/pll-dm644x.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DM644X
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/bitops.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+static const struct davinci_pll_clk_info dm644x_pll1_info = {
+ .name = "pll1",
+ .pllm_mask = GENMASK(4, 0),
+ .pllm_min = 1,
+ .pllm_max = 32,
+ .pllout_min_rate = 400000000,
+ .pllout_max_rate = 600000000, /* 810MHz @ 1.3V, -810 only */
+ .flags = PLL_HAS_CLKMODE | PLL_HAS_POSTDIV,
+};
+
+SYSCLK(1, pll1_sysclk1, pll1_pllen, 4, SYSCLK_FIXED_DIV);
+SYSCLK(2, pll1_sysclk2, pll1_pllen, 4, SYSCLK_FIXED_DIV);
+SYSCLK(3, pll1_sysclk3, pll1_pllen, 4, SYSCLK_FIXED_DIV);
+SYSCLK(5, pll1_sysclk5, pll1_pllen, 4, SYSCLK_FIXED_DIV);
+
+int dm644x_pll1_init(struct device *dev, void __iomem *base)
+{
+ struct clk *clk;
+
+ davinci_pll_clk_register(dev, &dm644x_pll1_info, "ref_clk", base);
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk1, base);
+ clk_register_clkdev(clk, "pll1_sysclk1", "dm644x-psc");
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk2, base);
+ clk_register_clkdev(clk, "pll1_sysclk2", "dm644x-psc");
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk3, base);
+ clk_register_clkdev(clk, "pll1_sysclk3", "dm644x-psc");
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk5, base);
+ clk_register_clkdev(clk, "pll1_sysclk5", "dm644x-psc");
+
+ clk = davinci_pll_auxclk_register(dev, "pll1_auxclk", base);
+ clk_register_clkdev(clk, "pll1_auxclk", "dm644x-psc");
+
+ davinci_pll_sysclkbp_clk_register(dev, "pll1_sysclkbp", base);
+
+ return 0;
+}
+
+static const struct davinci_pll_clk_info dm644x_pll2_info = {
+ .name = "pll2",
+ .pllm_mask = GENMASK(4, 0),
+ .pllm_min = 1,
+ .pllm_max = 32,
+ .pllout_min_rate = 400000000,
+ .pllout_max_rate = 900000000,
+ .flags = PLL_HAS_POSTDIV | PLL_POSTDIV_FIXED_DIV,
+};
+
+SYSCLK(1, pll2_sysclk1, pll2_pllen, 4, 0);
+SYSCLK(2, pll2_sysclk2, pll2_pllen, 4, 0);
+
+int dm644x_pll2_init(struct device *dev, void __iomem *base)
+{
+ davinci_pll_clk_register(dev, &dm644x_pll2_info, "oscin", base);
+
+ davinci_pll_sysclk_register(dev, &pll2_sysclk1, base);
+
+ davinci_pll_sysclk_register(dev, &pll2_sysclk2, base);
+
+ davinci_pll_sysclkbp_clk_register(dev, "pll2_sysclkbp", base);
+
+ return 0;
+}
diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c
index 3d8f4d2..0a1e68f 100644
--- a/drivers/clk/davinci/pll.c
+++ b/drivers/clk/davinci/pll.c
@@ -784,6 +784,8 @@ static const struct platform_device_id davinci_pll_id_table[] = {
{ .name = "dm355-pll2", .driver_data = (kernel_ulong_t)dm355_pll2_init },
{ .name = "dm365-pll1", .driver_data = (kernel_ulong_t)dm365_pll1_init },
{ .name = "dm365-pll2", .driver_data = (kernel_ulong_t)dm365_pll2_init },
+ { .name = "dm644x-pll1", .driver_data = (kernel_ulong_t)dm644x_pll1_init },
+ { .name = "dm644x-pll2", .driver_data = (kernel_ulong_t)dm644x_pll2_init },
{ }
};
diff --git a/drivers/clk/davinci/pll.h b/drivers/clk/davinci/pll.h
index bf9fdc8..d8af4f5 100644
--- a/drivers/clk/davinci/pll.h
+++ b/drivers/clk/davinci/pll.h
@@ -132,4 +132,7 @@ int dm355_pll2_init(struct device *dev, void __iomem *base);
int dm365_pll1_init(struct device *dev, void __iomem *base);
int dm365_pll2_init(struct device *dev, void __iomem *base);
+int dm644x_pll1_init(struct device *dev, void __iomem *base);
+int dm644x_pll2_init(struct device *dev, void __iomem *base);
+
#endif /* __CLK_DAVINCI_PLL_H___ */
--
2.7.4
This adds a new binding for the Power Sleep Controller (PSC) for the
mach-davinci family of processors.
Note: Although TI Keystone has a very similar PSC, we are not using the
existing bindings. Keystone is using a legacy one-node-per-clock binding
(actually two nodes if you count the separate reset binding for the same
IP block). Also, some davinci LPSCs have quirks that aren't handled by
the keystone bindings, so we would be adding one compatible string per
clock with quirks instead of just a new compatible string for each
controller.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
---
v8 changes:
- None
v7 changes:
- Fixed clock-names property typo
- Added #power-domain-cells property
v6 changes:
- added clocks and clock-names properties
- expanded examples
.../devicetree/bindings/clock/ti/davinci/psc.txt | 71 ++++++++++++++++++++++
1 file changed, 71 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/psc.txt
diff --git a/Documentation/devicetree/bindings/clock/ti/davinci/psc.txt b/Documentation/devicetree/bindings/clock/ti/davinci/psc.txt
new file mode 100644
index 0000000..dae4ad8
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti/davinci/psc.txt
@@ -0,0 +1,71 @@
+Binding for TI DaVinci Power Sleep Controller (PSC)
+
+The PSC provides power management, clock gating and reset functionality. It is
+primarily used for clocking.
+
+Required properties:
+- compatible: shall be one of:
+ - "ti,da850-psc0" for PSC0 on DA850/OMAP-L138/AM18XX
+ - "ti,da850-psc1" for PSC1 on DA850/OMAP-L138/AM18XX
+- reg: physical base address and size of the controller's register area
+- #clock-cells: from common clock binding; shall be set to 1
+- #power-domain-cells: from generic power domain binding; shall be set to 1.
+- clocks: phandles to clocks corresponding to the clock-names property
+- clock-names: list of parent clock names - depends on compatible value
+ - for "ti,da850-psc0", shall be "pll0_sysclk1", "pll0_sysclk2",
+ "pll0_sysclk4", "pll0_sysclk6", "async1"
+ - for "ti,da850-psc1", shall be "pll0_sysclk2", "pll0_sysclk4", "async3"
+
+Optional properties:
+- #reset-cells: from reset binding; shall be set to 1 - only applicable when
+ at least one local domain provides a local reset.
+
+Consumers:
+
+ Clock, power domain and reset consumers shall use the local power domain
+ module ID (LPSC) as the index corresponding to the clock cell. Refer to
+ the device-specific datasheet to find these numbers. NB: Most local
+ domains only provide a clock/power domain and not a reset.
+
+Examples:
+
+ psc0: clock-controller@10000 {
+ compatible = "ti,da850-psc0";
+ reg = <0x10000 0x1000>;
+ #clock-cells = <1>;
+ #power-domain-cells = <1>;
+ #reset-cells = <1>;
+ clocks = <&pll0_sysclk 1>, <&pll0_sysclk 2>,
+ <&pll0_sysclk 4>, <&pll0_sysclk 6>, <&async1_clk>;
+ clock_names = "pll0_sysclk1", "pll0_sysclk2",
+ "pll0_sysclk4", "pll0_sysclk6", "async1";
+ };
+ psc1: clock-controller@227000 {
+ compatible = "ti,da850-psc1";
+ reg = <0x227000 0x1000>;
+ #clock-cells = <1>;
+ #power-domain-cells = <1>;
+ clocks = <&pll0_sysclk 2>, <&pll0_sysclk 4>, <&async3_clk>;
+ clock_names = "pll0_sysclk2", "pll0_sysclk4", "async3";
+ };
+
+ /* consumer */
+ dsp: dsp@11800000 {
+ compatible = "ti,da850-dsp";
+ reg = <0x11800000 0x40000>,
+ <0x11e00000 0x8000>,
+ <0x11f00000 0x8000>,
+ <0x01c14044 0x4>,
+ <0x01c14174 0x8>;
+ reg-names = "l2sram", "l1pram", "l1dram", "host1cfg", "chipsig";
+ interrupt-parent = <&intc>;
+ interrupts = <28>;
+ clocks = <&psc0 15>;
+ power-domains = <&psc0 15>;
+ resets = <&psc0 15>;
+ };
+
+Also see:
+- Documentation/devicetree/bindings/clock/clock-bindings.txt
+- Documentation/devicetree/bindings/power/power_domain.txt
+- Documentation/devicetree/bindings/reset/reset.txt
--
2.7.4
This adds platform-specific declarations for the PLL clocks on TI DA830/
OMAP-L137/AM17XX SoCs.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- drop __init and __initconst attributes
- add a clkdev lookup for each SYSCLK
v7 changes:
- include clkdev lookup registration here instead of in mach-davinci
- Add platform_device_id lookup
v6 changes:
- Added da830_pll_info with controller-specific information
- Add empty lines between function calls
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-da830.c | 70 +++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/pll.c | 1 +
drivers/clk/davinci/pll.h | 4 +++
4 files changed, 76 insertions(+)
create mode 100644 drivers/clk/davinci/pll-da830.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index d9673bd..9061e19 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -2,4 +2,5 @@
ifeq ($(CONFIG_COMMON_CLK), y)
obj-y += pll.o
+obj-$(CONFIG_ARCH_DAVINCI_DA830) += pll-da830.o
endif
diff --git a/drivers/clk/davinci/pll-da830.c b/drivers/clk/davinci/pll-da830.c
new file mode 100644
index 0000000..929a3d3
--- /dev/null
+++ b/drivers/clk/davinci/pll-da830.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DA830/OMAP-L137/AM17XX
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/clkdev.h>
+#include <linux/bitops.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+static const struct davinci_pll_clk_info da830_pll_info = {
+ .name = "pll0",
+ .pllm_mask = GENMASK(4, 0),
+ .pllm_min = 4,
+ .pllm_max = 32,
+ .pllout_min_rate = 300000000,
+ .pllout_max_rate = 600000000,
+ .flags = PLL_HAS_CLKMODE | PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
+};
+
+/*
+ * NB: Technically, the clocks flagged as SYSCLK_FIXED_DIV are "fixed ratio",
+ * meaning that we could change the divider as long as we keep the correct
+ * ratio between all of the clocks, but we don't support that because there is
+ * currently not a need for it.
+ */
+
+SYSCLK(2, pll0_sysclk2, pll0_pllen, 5, SYSCLK_FIXED_DIV);
+SYSCLK(3, pll0_sysclk3, pll0_pllen, 5, 0);
+SYSCLK(4, pll0_sysclk4, pll0_pllen, 5, SYSCLK_FIXED_DIV);
+SYSCLK(5, pll0_sysclk5, pll0_pllen, 5, 0);
+SYSCLK(6, pll0_sysclk6, pll0_pllen, 5, SYSCLK_FIXED_DIV);
+SYSCLK(7, pll0_sysclk7, pll0_pllen, 5, 0);
+
+int da830_pll_init(struct device *dev, void __iomem *base)
+{
+ struct clk *clk;
+
+ davinci_pll_clk_register(dev, &da830_pll_info, "ref_clk", base);
+
+ clk = davinci_pll_sysclk_register(dev, &pll0_sysclk2, base);
+ clk_register_clkdev(clk, "pll0_sysclk2", "da830-psc0");
+ clk_register_clkdev(clk, "pll0_sysclk2", "da830-psc1");
+
+ clk = davinci_pll_sysclk_register(dev, &pll0_sysclk3, base);
+ clk_register_clkdev(clk, "pll0_sysclk3", "da830-psc0");
+
+ clk = davinci_pll_sysclk_register(dev, &pll0_sysclk4, base);
+ clk_register_clkdev(clk, "pll0_sysclk4", "da830-psc0");
+ clk_register_clkdev(clk, "pll0_sysclk4", "da830-psc1");
+
+ clk = davinci_pll_sysclk_register(dev, &pll0_sysclk5, base);
+ clk_register_clkdev(clk, "pll0_sysclk5", "da830-psc1");
+
+ clk = davinci_pll_sysclk_register(dev, &pll0_sysclk6, base);
+ clk_register_clkdev(clk, "pll0_sysclk6", "da830-psc0");
+
+ clk = davinci_pll_sysclk_register(dev, &pll0_sysclk7, base);
+
+ clk = davinci_pll_auxclk_register(dev, "pll0_auxclk", base);
+ clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+ clk_register_clkdev(clk, "timer0", NULL);
+ clk_register_clkdev(clk, NULL, "davinci-wdt");
+
+ return 0;
+}
diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c
index 22ee95c..eaf8049 100644
--- a/drivers/clk/davinci/pll.c
+++ b/drivers/clk/davinci/pll.c
@@ -775,6 +775,7 @@ static const struct of_device_id davinci_pll_of_match[] = {
};
static const struct platform_device_id davinci_pll_id_table[] = {
+ { .name = "da830-pll", .driver_data = (kernel_ulong_t)da830_pll_init },
{ }
};
diff --git a/drivers/clk/davinci/pll.h b/drivers/clk/davinci/pll.h
index 52103ae..0de2c61 100644
--- a/drivers/clk/davinci/pll.h
+++ b/drivers/clk/davinci/pll.h
@@ -117,4 +117,8 @@ int of_davinci_pll_init(struct device *dev,
u8 max_sysclk_id,
void __iomem *base);
+/* Platform-specific callbacks */
+
+int da830_pll_init(struct device *dev, void __iomem *base);
+
#endif /* __CLK_DAVINCI_PLL_H___ */
--
2.7.4
This adds platform-specific declarations for the PLL clocks on TI DA850/
OMAP-L138/AM18XX SoCs.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- drop __init and __initconst attributes
- add a clkdev lookup for each SYSCLK
v7 changes:
- include clkdev lookup registration here instead of in mach-davinci
- split registration functions for each PLL
- Add platform_device_id lookup
v6 changes:
- Added da850_pll{0,1}_info with controller-specific information
- Added OBSCLK data
- Add empty lines between function calls
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-da850.c | 212 ++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/pll.c | 4 +
drivers/clk/davinci/pll.h | 5 +
4 files changed, 222 insertions(+)
create mode 100644 drivers/clk/davinci/pll-da850.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index 9061e19..13049d4 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -3,4 +3,5 @@
ifeq ($(CONFIG_COMMON_CLK), y)
obj-y += pll.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += pll-da830.o
+obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o
endif
diff --git a/drivers/clk/davinci/pll-da850.c b/drivers/clk/davinci/pll-da850.c
new file mode 100644
index 0000000..2a038b7
--- /dev/null
+++ b/drivers/clk/davinci/pll-da850.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DA850/OMAP-L138/AM18XX
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/of.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+#define OCSEL_OCSRC_OSCIN 0x14
+#define OCSEL_OCSRC_PLL0_SYSCLK(n) (0x16 + (n))
+#define OCSEL_OCSRC_PLL1_OBSCLK 0x1e
+#define OCSEL_OCSRC_PLL1_SYSCLK(n) (0x16 + (n))
+
+static const struct davinci_pll_clk_info da850_pll0_info = {
+ .name = "pll0",
+ .unlock_reg = CFGCHIP(0),
+ .unlock_mask = CFGCHIP0_PLL_MASTER_LOCK,
+ .pllm_mask = GENMASK(4, 0),
+ .pllm_min = 4,
+ .pllm_max = 32,
+ .pllout_min_rate = 300000000,
+ .pllout_max_rate = 600000000,
+ .flags = PLL_HAS_CLKMODE | PLL_HAS_PREDIV | PLL_HAS_POSTDIV |
+ PLL_HAS_EXTCLKSRC,
+};
+
+/*
+ * NB: Technically, the clocks flagged as SYSCLK_FIXED_DIV are "fixed ratio",
+ * meaning that we could change the divider as long as we keep the correct
+ * ratio between all of the clocks, but we don't support that because there is
+ * currently not a need for it.
+ */
+
+SYSCLK(1, pll0_sysclk1, pll0_pllen, 5, SYSCLK_FIXED_DIV);
+SYSCLK(2, pll0_sysclk2, pll0_pllen, 5, SYSCLK_FIXED_DIV);
+SYSCLK(3, pll0_sysclk3, pll0_pllen, 5, 0);
+SYSCLK(4, pll0_sysclk4, pll0_pllen, 5, SYSCLK_FIXED_DIV);
+SYSCLK(5, pll0_sysclk5, pll0_pllen, 5, 0);
+SYSCLK(6, pll0_sysclk6, pll0_pllen, 5, SYSCLK_ARM_RATE | SYSCLK_FIXED_DIV);
+SYSCLK(7, pll0_sysclk7, pll0_pllen, 5, 0);
+
+static const char * const da850_pll0_obsclk_parent_names[] = {
+ "oscin",
+ "pll0_sysclk1",
+ "pll0_sysclk2",
+ "pll0_sysclk3",
+ "pll0_sysclk4",
+ "pll0_sysclk5",
+ "pll0_sysclk6",
+ "pll0_sysclk7",
+ "pll1_obsclk",
+};
+
+static u32 da850_pll0_obsclk_table[] = {
+ OCSEL_OCSRC_OSCIN,
+ OCSEL_OCSRC_PLL0_SYSCLK(1),
+ OCSEL_OCSRC_PLL0_SYSCLK(2),
+ OCSEL_OCSRC_PLL0_SYSCLK(3),
+ OCSEL_OCSRC_PLL0_SYSCLK(4),
+ OCSEL_OCSRC_PLL0_SYSCLK(5),
+ OCSEL_OCSRC_PLL0_SYSCLK(6),
+ OCSEL_OCSRC_PLL0_SYSCLK(7),
+ OCSEL_OCSRC_PLL1_OBSCLK,
+};
+
+static const struct davinci_pll_obsclk_info da850_pll0_obsclk_info = {
+ .name = "pll0_obsclk",
+ .parent_names = da850_pll0_obsclk_parent_names,
+ .num_parents = ARRAY_SIZE(da850_pll0_obsclk_parent_names),
+ .table = da850_pll0_obsclk_table,
+ .ocsrc_mask = GENMASK(4, 0),
+};
+
+int da850_pll0_init(struct device *dev, void __iomem *base)
+{
+ struct clk *clk;
+
+ davinci_pll_clk_register(dev, &da850_pll0_info, "ref_clk", base);
+
+ clk = davinci_pll_sysclk_register(dev, &pll0_sysclk1, base);
+ clk_register_clkdev(clk, "pll0_sysclk1", "da850-psc0");
+
+ clk = davinci_pll_sysclk_register(dev, &pll0_sysclk2, base);
+ clk_register_clkdev(clk, "pll0_sysclk2", "da850-psc0");
+ clk_register_clkdev(clk, "pll0_sysclk2", "da850-psc1");
+ clk_register_clkdev(clk, "pll0_sysclk2", "da850-async3-clksrc");
+
+ clk = davinci_pll_sysclk_register(dev, &pll0_sysclk3, base);
+ clk_register_clkdev(clk, "pll0_sysclk3", "da850-async1-clksrc");
+
+ clk = davinci_pll_sysclk_register(dev, &pll0_sysclk4, base);
+ clk_register_clkdev(clk, "pll0_sysclk4", "da850-psc0");
+ clk_register_clkdev(clk, "pll0_sysclk4", "da850-psc1");
+
+ davinci_pll_sysclk_register(dev, &pll0_sysclk5, base);
+
+ clk = davinci_pll_sysclk_register(dev, &pll0_sysclk6, base);
+ clk_register_clkdev(clk, "pll0_sysclk6", "da850-psc0");
+
+ davinci_pll_sysclk_register(dev, &pll0_sysclk7, base);
+
+ davinci_pll_auxclk_register(dev, "pll0_auxclk", base);
+
+ clk = clk_register_fixed_factor(dev, "async2", "pll0_auxclk",
+ CLK_IS_CRITICAL, 1, 1);
+
+ clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+ clk_register_clkdev(clk, "timer0", NULL);
+ clk_register_clkdev(clk, NULL, "davinci-wdt");
+
+ davinci_pll_obsclk_register(dev, &da850_pll0_obsclk_info, base);
+
+ return 0;
+}
+
+static const struct davinci_pll_sysclk_info *da850_pll0_sysclk_info[] = {
+ &pll0_sysclk1,
+ &pll0_sysclk2,
+ &pll0_sysclk3,
+ &pll0_sysclk4,
+ &pll0_sysclk5,
+ &pll0_sysclk6,
+ &pll0_sysclk7,
+ NULL
+};
+
+int of_da850_pll0_init(struct device *dev, void __iomem *base)
+{
+ return of_davinci_pll_init(dev, &da850_pll0_info,
+ &da850_pll0_obsclk_info,
+ da850_pll0_sysclk_info, 7, base);
+}
+
+static const struct davinci_pll_clk_info da850_pll1_info = {
+ .name = "pll1",
+ .unlock_reg = CFGCHIP(3),
+ .unlock_mask = CFGCHIP3_PLL1_MASTER_LOCK,
+ .pllm_mask = GENMASK(4, 0),
+ .pllm_min = 4,
+ .pllm_max = 32,
+ .pllout_min_rate = 300000000,
+ .pllout_max_rate = 600000000,
+ .flags = PLL_HAS_POSTDIV,
+};
+
+SYSCLK(1, pll1_sysclk1, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(2, pll1_sysclk2, pll1_pllen, 5, 0);
+SYSCLK(3, pll1_sysclk3, pll1_pllen, 5, 0);
+
+static const char * const da850_pll1_obsclk_parent_names[] = {
+ "oscin",
+ "pll1_sysclk1",
+ "pll1_sysclk2",
+ "pll1_sysclk3",
+};
+
+static u32 da850_pll1_obsclk_table[] = {
+ OCSEL_OCSRC_OSCIN,
+ OCSEL_OCSRC_PLL1_SYSCLK(1),
+ OCSEL_OCSRC_PLL1_SYSCLK(2),
+ OCSEL_OCSRC_PLL1_SYSCLK(3),
+};
+
+static const struct davinci_pll_obsclk_info da850_pll1_obsclk_info = {
+ .name = "pll1_obsclk",
+ .parent_names = da850_pll1_obsclk_parent_names,
+ .num_parents = ARRAY_SIZE(da850_pll1_obsclk_parent_names),
+ .table = da850_pll1_obsclk_table,
+ .ocsrc_mask = GENMASK(4, 0),
+};
+
+int da850_pll1_init(struct device *dev, void __iomem *base)
+{
+ struct clk *clk;
+
+ davinci_pll_clk_register(dev, &da850_pll1_info, "oscin", base);
+
+ davinci_pll_sysclk_register(dev, &pll1_sysclk1, base);
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk2, base);
+ clk_register_clkdev(clk, "pll1_sysclk2", "da850-async3-clksrc");
+
+ davinci_pll_sysclk_register(dev, &pll1_sysclk3, base);
+
+ davinci_pll_obsclk_register(dev, &da850_pll1_obsclk_info, base);
+
+ return 0;
+}
+
+static const struct davinci_pll_sysclk_info *da850_pll1_sysclk_info[] = {
+ &pll1_sysclk1,
+ &pll1_sysclk2,
+ &pll1_sysclk3,
+ NULL
+};
+
+int of_da850_pll1_init(struct device *dev, void __iomem *base)
+{
+ return of_davinci_pll_init(dev, &da850_pll1_info,
+ &da850_pll1_obsclk_info,
+ da850_pll1_sysclk_info, 3, base);
+}
diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c
index eaf8049..535f725 100644
--- a/drivers/clk/davinci/pll.c
+++ b/drivers/clk/davinci/pll.c
@@ -771,11 +771,15 @@ int of_davinci_pll_init(struct device *dev,
}
static const struct of_device_id davinci_pll_of_match[] = {
+ { .compatible = "ti,da850-pll0", .data = of_da850_pll0_init },
+ { .compatible = "ti,da850-pll1", .data = of_da850_pll1_init },
{ }
};
static const struct platform_device_id davinci_pll_id_table[] = {
{ .name = "da830-pll", .driver_data = (kernel_ulong_t)da830_pll_init },
+ { .name = "da850-pll0", .driver_data = (kernel_ulong_t)da850_pll0_init },
+ { .name = "da850-pll1", .driver_data = (kernel_ulong_t)da850_pll1_init },
{ }
};
diff --git a/drivers/clk/davinci/pll.h b/drivers/clk/davinci/pll.h
index 0de2c61..53b8d51 100644
--- a/drivers/clk/davinci/pll.h
+++ b/drivers/clk/davinci/pll.h
@@ -121,4 +121,9 @@ int of_davinci_pll_init(struct device *dev,
int da830_pll_init(struct device *dev, void __iomem *base);
+int da850_pll0_init(struct device *dev, void __iomem *base);
+int da850_pll1_init(struct device *dev, void __iomem *base);
+int of_da850_pll0_init(struct device *dev, void __iomem *base);
+int of_da850_pll1_init(struct device *dev, void __iomem *base);
+
#endif /* __CLK_DAVINCI_PLL_H___ */
--
2.7.4
This adds a new driver for mach-davinci PLL clocks. This is porting the
code from arch/arm/mach-davinci/clock.c to the common clock framework.
Additionally, it adds device tree support for these clocks.
The ifeq ($(CONFIG_COMMON_CLK), y) in the Makefile is needed to prevent
compile errors until the clock code in arch/arm/mach-davinci is removed.
Note: although there are similar clocks for TI Keystone we are not able
to share the code for a few reasons. The keystone clocks are device tree
only and use legacy one-node-per-clock bindings. Also the register
layouts are a bit different, which would add even more if/else mess
to the keystone clocks. And the keystone PLL driver doesn't support
setting clock rates.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- use platform data to pass CFGCHIP from legacy board files
- change div_info parameter to array of pointer instead of array of struct
v7 changes:
- convert to platform device driver
- rename PLL_HAS_OSCIN to PLL_HAS_CLKMODE
- add comments to clarify which clock domain "oscin" is
v6 changes:
- Added R: Sekhar Nori <[email protected]> to MAINTAINERS
- Split main PLL clock into oscdiv, prediv, pllout, postdiv and pllen clocks
- Added min/max rate checking for pllout in set_rate
- Added min/max PLLM value checking for pllout in set_rate
- Fixed sysclk set_rate (checking GOSTAT and setting GOSET)
- Added *_clk_info structs for passing controller-specific info
- Added quirks for optional PREDIV and POSTDIV registers
- Added quirk for DM355 broken PREDIV register
- Added quirk for DM365 2x PLLM register
- Handle unlocking PLL registers via CFGCHIP
- Use pr_fmt macro
MAINTAINERS | 7 +
drivers/clk/Makefile | 1 +
drivers/clk/davinci/Makefile | 5 +
drivers/clk/davinci/pll.c | 888 ++++++++++++++++++++++++++
drivers/clk/davinci/pll.h | 120 ++++
include/linux/platform_data/clk-davinci-pll.h | 21 +
6 files changed, 1042 insertions(+)
create mode 100644 drivers/clk/davinci/Makefile
create mode 100644 drivers/clk/davinci/pll.c
create mode 100644 drivers/clk/davinci/pll.h
create mode 100644 include/linux/platform_data/clk-davinci-pll.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 93a12af..161fdba 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13793,6 +13793,13 @@ F: arch/arm/mach-davinci/
F: drivers/i2c/busses/i2c-davinci.c
F: arch/arm/boot/dts/da850*
+TI DAVINCI SERIES CLOCK DRIVER
+M: David Lechner <[email protected]>
+R: Sekhar Nori <[email protected]>
+S: Maintained
+F: Documentation/devicetree/bindings/clock/ti/davinci/
+F: drivers/clk/davinci/
+
TI DAVINCI SERIES GPIO DRIVER
M: Keerthy <[email protected]>
L: [email protected]
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 71ec41e..07ac0fdb 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_ARCH_ARTPEC) += axis/
obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/
obj-y += bcm/
obj-$(CONFIG_ARCH_BERLIN) += berlin/
+obj-$(CONFIG_ARCH_DAVINCI) += davinci/
obj-$(CONFIG_H8300) += h8300/
obj-$(CONFIG_ARCH_HISI) += hisilicon/
obj-y += imgtec/
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
new file mode 100644
index 0000000..d9673bd
--- /dev/null
+++ b/drivers/clk/davinci/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+ifeq ($(CONFIG_COMMON_CLK), y)
+obj-y += pll.o
+endif
diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c
new file mode 100644
index 0000000..22ee95c
--- /dev/null
+++ b/drivers/clk/davinci/pll.c
@@ -0,0 +1,888 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock driver for TI Davinci SoCs
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ *
+ * Based on arch/arm/mach-davinci/clock.c
+ * Copyright (C) 2006-2007 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/notifier.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_data/clk-davinci-pll.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+#define MAX_NAME_SIZE 20
+#define OSCIN_CLK_NAME "oscin"
+
+#define REVID 0x000
+#define PLLCTL 0x100
+#define OCSEL 0x104
+#define PLLSECCTL 0x108
+#define PLLM 0x110
+#define PREDIV 0x114
+#define PLLDIV1 0x118
+#define PLLDIV2 0x11c
+#define PLLDIV3 0x120
+#define OSCDIV 0x124
+#define POSTDIV 0x128
+#define BPDIV 0x12c
+#define PLLCMD 0x138
+#define PLLSTAT 0x13c
+#define ALNCTL 0x140
+#define DCHANGE 0x144
+#define CKEN 0x148
+#define CKSTAT 0x14c
+#define SYSTAT 0x150
+#define PLLDIV4 0x160
+#define PLLDIV5 0x164
+#define PLLDIV6 0x168
+#define PLLDIV7 0x16c
+#define PLLDIV8 0x170
+#define PLLDIV9 0x174
+
+#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)
+
+/* shared by most *DIV registers */
+#define DIV_RATIO_SHIFT 0
+#define DIV_RATIO_WIDTH 5
+#define DIV_ENABLE_SHIFT 15
+
+#define PLLCMD_GOSET BIT(0)
+#define PLLSTAT_GOSTAT BIT(0)
+
+#define CKEN_OBSCLK_SHIFT 1
+#define CKEN_AUXEN_SHIFT 0
+
+/*
+ * 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
+
+/**
+ * struct davinci_pll_clk - Main PLL clock (aka PLLOUT)
+ * @hw: clk_hw for the pll
+ * @base: Base memory address
+ * @pllm_min: The minimum allowable PLLM[PLLM] value
+ * @pllm_max: The maxiumum allowable PLLM[PLLM] value
+ * @pllm_mask: Bitmask for PLLM[PLLM] value
+ */
+struct davinci_pll_clk {
+ struct clk_hw hw;
+ void __iomem *base;
+ u32 pllm_min;
+ u32 pllm_max;
+ u32 pllm_mask;
+};
+
+#define to_davinci_pll_clk(_hw) \
+ container_of((_hw), struct davinci_pll_clk, hw)
+
+static unsigned long davinci_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
+ unsigned long rate = parent_rate;
+ u32 mult;
+
+ mult = readl(pll->base + PLLM) & pll->pllm_mask;
+ rate *= mult + 1;
+
+ return rate;
+}
+
+static int davinci_pll_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
+ struct clk_hw *parent = req->best_parent_hw;
+ unsigned long parent_rate = req->best_parent_rate;
+ unsigned long rate = req->rate;
+ unsigned long best_rate, r;
+ u32 mult;
+
+ /* there is a limited range of valid outputs (see datasheet) */
+ if (rate < req->min_rate)
+ return -EINVAL;
+
+ rate = min(rate, req->max_rate);
+ mult = rate / parent_rate;
+ best_rate = parent_rate * mult;
+
+ /* easy case when there is no PREDIV */
+ if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
+ if (best_rate < req->min_rate)
+ return -EINVAL;
+
+ if (mult < pll->pllm_min || mult > pll->pllm_max)
+ return -EINVAL;
+
+ req->rate = best_rate;
+
+ return 0;
+ }
+
+ /* see if the PREDIV clock can help us */
+ best_rate = 0;
+
+ for (mult = pll->pllm_min; mult <= pll->pllm_max; mult++) {
+ parent_rate = clk_hw_round_rate(parent, rate / mult);
+ r = parent_rate * mult;
+ if (r < req->min_rate)
+ continue;
+ if (r > rate || r > req->max_rate)
+ break;
+ if (r > best_rate) {
+ best_rate = r;
+ req->rate = best_rate;
+ req->best_parent_rate = parent_rate;
+ if (best_rate == rate)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int davinci_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
+ u32 mult;
+
+ mult = rate / parent_rate;
+ writel(mult - 1, pll->base + PLLM);
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int davinci_pll_debug_init(struct clk_hw *hw, struct dentry *dentry);
+#else
+#define davinci_pll_debug_init NULL
+#endif
+
+static const struct clk_ops davinci_pll_ops = {
+ .recalc_rate = davinci_pll_recalc_rate,
+ .determine_rate = davinci_pll_determine_rate,
+ .set_rate = davinci_pll_set_rate,
+ .debug_init = davinci_pll_debug_init,
+};
+
+/* PLLM works differently on DM365 */
+static unsigned long dm365_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
+ unsigned long rate = parent_rate;
+ u32 mult;
+
+ mult = readl(pll->base + PLLM) & pll->pllm_mask;
+ rate *= mult * 2;
+
+ return rate;
+}
+
+static const struct clk_ops dm365_pll_ops = {
+ .recalc_rate = dm365_pll_recalc_rate,
+ .debug_init = davinci_pll_debug_init,
+};
+
+/**
+ * davinci_pll_div_register - common *DIV clock implementation
+ * @name: the clock name
+ * @parent_name: the parent clock name
+ * @reg: the *DIV register
+ * @fixed: if true, the divider is a fixed value
+ * @flags: bitmap of CLK_* flags from clock-provider.h
+ */
+static struct clk *davinci_pll_div_register(struct device *dev,
+ const char *name,
+ const char *parent_name,
+ void __iomem *reg,
+ bool fixed, u32 flags)
+{
+ const char * const *parent_names = parent_name ? &parent_name : NULL;
+ int num_parents = parent_name ? 1 : 0;
+ const struct clk_ops *divider_ops = &clk_divider_ops;
+ struct clk_gate *gate;
+ struct clk_divider *divider;
+
+ gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ gate->reg = reg;
+ gate->bit_idx = DIV_ENABLE_SHIFT;
+
+ divider = devm_kzalloc(dev, sizeof(*divider), GFP_KERNEL);
+ if (!divider)
+ return ERR_PTR(-ENOMEM);
+
+ divider->reg = reg;
+ divider->shift = DIV_RATIO_SHIFT;
+ divider->width = DIV_RATIO_WIDTH;
+
+ if (fixed) {
+ divider->flags |= CLK_DIVIDER_READ_ONLY;
+ divider_ops = &clk_divider_ro_ops;
+ }
+
+ return clk_register_composite(dev, name, parent_names, num_parents,
+ NULL, NULL, ÷r->hw, divider_ops,
+ &gate->hw, &clk_gate_ops, flags);
+}
+
+struct davinci_pllen_clk {
+ struct clk_hw hw;
+ void __iomem *base;
+};
+
+#define to_davinci_pllen_clk(_hw) \
+ container_of((_hw), struct davinci_pllen_clk, hw)
+
+static const struct clk_ops davinci_pllen_ops = {
+ /* this clocks just uses the clock notification feature */
+};
+
+/*
+ * The PLL has to be switched into bypass mode while we are chaning the rate,
+ * so we do that on the PLLEN clock since it is the end of the line. This will
+ * switch to bypass before any of the parent clocks (PREDIV, PLL, POSTDIV) are
+ * changed and will switch back to the PLL after the changes have been made.
+ */
+static int davinci_pllen_rate_change(struct notifier_block *nb,
+ unsigned long flags, void *data)
+{
+ struct clk_notifier_data *cnd = data;
+ struct clk_hw *hw = __clk_get_hw(cnd->clk);
+ struct davinci_pllen_clk *pll = to_davinci_pllen_clk(hw);
+ u32 ctrl;
+
+ ctrl = readl(pll->base + PLLCTL);
+
+ if (flags == PRE_RATE_CHANGE) {
+ /* Switch the PLL to bypass mode */
+ ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
+ writel(ctrl, pll->base + PLLCTL);
+
+ udelay(PLL_BYPASS_TIME);
+
+ /* Reset and enable PLL */
+ ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
+ writel(ctrl, pll->base + PLLCTL);
+ } else {
+ udelay(PLL_RESET_TIME);
+
+ /* Bring PLL out of reset */
+ ctrl |= PLLCTL_PLLRST;
+ writel(ctrl, pll->base + PLLCTL);
+
+ udelay(PLL_LOCK_TIME);
+
+ /* Remove PLL from bypass mode */
+ ctrl |= PLLCTL_PLLEN;
+ writel(ctrl, pll->base + PLLCTL);
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct davinci_pll_platform_data *davinci_pll_get_pdata(struct device *dev)
+{
+ struct davinci_pll_platform_data *pdata = dev_get_platdata(dev);
+
+ /*
+ * Platform data is optional, so allocate a new struct if one was not
+ * provided. For device tree, this will always be the case.
+ */
+ if (!pdata)
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return NULL;
+
+ /* for device tree, we need to fill in the struct */
+ if (dev->of_node)
+ pdata->cfgchip =
+ syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
+
+ return pdata;
+}
+
+static struct notifier_block davinci_pllen_notifier = {
+ .notifier_call = davinci_pllen_rate_change,
+};
+
+/**
+ * davinci_pll_clk_register - Register a PLL clock
+ * @info: The device-specific clock info
+ * @parent_name: The parent clock name
+ * @base: The PLL's memory region
+ *
+ * This creates a series of clocks that represent the PLL.
+ *
+ * OSCIN > [PREDIV >] PLL > [POSTDIV >] PLLEN
+ *
+ * - OSCIN is the parent clock (on secondary PLL, may come from primary PLL)
+ * - PREDIV and POSTDIV are optional (depends on the PLL controller)
+ * - PLL is the PLL output (aka PLLOUT)
+ * - PLLEN is the bypass multiplexer
+ *
+ * Returns: The PLLOUT clock or a negative error code.
+ */
+struct clk *davinci_pll_clk_register(struct device *dev,
+ const struct davinci_pll_clk_info *info,
+ const char *parent_name,
+ void __iomem *base)
+{
+ struct davinci_pll_platform_data *pdata;
+ char prediv_name[MAX_NAME_SIZE];
+ char pllout_name[MAX_NAME_SIZE];
+ char postdiv_name[MAX_NAME_SIZE];
+ char pllen_name[MAX_NAME_SIZE];
+ struct clk_init_data init;
+ struct davinci_pll_clk *pllout;
+ struct davinci_pllen_clk *pllen;
+ struct clk *pllout_clk, *clk;
+
+ pdata = davinci_pll_get_pdata(dev);
+ if (!pdata)
+ return ERR_PTR(-ENOMEM);
+
+ if (info->flags & PLL_HAS_CLKMODE) {
+ /*
+ * If a PLL has PLLCTL[CLKMODE], then it is the primary PLL.
+ * We register a clock named "oscin" that serves as the internal
+ * "input clock" domain shared by both PLLs (if there are 2)
+ * and will be the parent clock to the AUXCLK, SYSCLKBP and
+ * OBSCLK domains. NB: The various TRMs use "OSCIN" to mean
+ * a number of different things. In this driver we use it to
+ * mean the signal after the PLLCTL[CLKMODE] switch.
+ */
+ clk = clk_register_fixed_factor(dev, OSCIN_CLK_NAME,
+ parent_name, 0, 1, 1);
+ if (IS_ERR(clk))
+ return clk;
+
+ parent_name = OSCIN_CLK_NAME;
+ }
+
+ if (info->flags & PLL_HAS_PREDIV) {
+ bool fixed = info->flags & PLL_PREDIV_FIXED_DIV;
+ u32 flags = 0;
+
+ snprintf(prediv_name, MAX_NAME_SIZE, "%s_prediv", info->name);
+
+ if (info->flags & PLL_PREDIV_ALWAYS_ENABLED)
+ flags |= CLK_IS_CRITICAL;
+
+ /* Some? DM355 chips don't correctly report the PREDIV value */
+ if (info->flags & PLL_PREDIV_FIXED8)
+ clk = clk_register_fixed_factor(dev, prediv_name,
+ parent_name, flags, 1, 8);
+ else
+ clk = davinci_pll_div_register(dev, prediv_name,
+ parent_name, base + PREDIV, fixed, flags);
+ if (IS_ERR(clk))
+ return clk;
+
+ parent_name = prediv_name;
+ }
+
+ /* Unlock writing to PLL registers */
+ if (info->unlock_reg) {
+ if (IS_ERR_OR_NULL(pdata->cfgchip))
+ dev_warn(dev, "Failed to get CFGCHIP (%ld)\n",
+ PTR_ERR(pdata->cfgchip));
+ else
+ regmap_write_bits(pdata->cfgchip, info->unlock_reg,
+ info->unlock_mask, 0);
+ }
+
+ pllout = devm_kzalloc(dev, sizeof(*pllout), GFP_KERNEL);
+ if (!pllout)
+ return ERR_PTR(-ENOMEM);
+
+ snprintf(pllout_name, MAX_NAME_SIZE, "%s_pllout", info->name);
+
+ init.name = pllout_name;
+ if (info->flags & PLL_PLLM_2X)
+ init.ops = &dm365_pll_ops;
+ else
+ init.ops = &davinci_pll_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.flags = 0;
+
+ if (info->flags & PLL_HAS_PREDIV)
+ init.flags |= CLK_SET_RATE_PARENT;
+
+ pllout->hw.init = &init;
+ pllout->base = base;
+ pllout->pllm_mask = info->pllm_mask;
+ pllout->pllm_min = info->pllm_min;
+ pllout->pllm_max = info->pllm_max;
+
+ pllout_clk = devm_clk_register(dev, &pllout->hw);
+ if (IS_ERR(pllout_clk))
+ return pllout_clk;
+
+ clk_hw_set_rate_range(&pllout->hw, info->pllout_min_rate,
+ info->pllout_max_rate);
+
+ parent_name = pllout_name;
+
+ if (info->flags & PLL_HAS_POSTDIV) {
+ bool fixed = info->flags & PLL_POSTDIV_FIXED_DIV;
+ u32 flags = CLK_SET_RATE_PARENT;
+
+ snprintf(postdiv_name, MAX_NAME_SIZE, "%s_postdiv", info->name);
+
+ if (info->flags & PLL_POSTDIV_ALWAYS_ENABLED)
+ flags |= CLK_IS_CRITICAL;
+
+ clk = davinci_pll_div_register(dev, postdiv_name, parent_name,
+ base + POSTDIV, fixed, flags);
+ if (IS_ERR(clk))
+ return clk;
+
+ parent_name = postdiv_name;
+ }
+
+ pllen = devm_kzalloc(dev, sizeof(*pllout), GFP_KERNEL);
+ if (!pllen)
+ return ERR_PTR(-ENOMEM);
+
+ snprintf(pllen_name, MAX_NAME_SIZE, "%s_pllen", info->name);
+
+ init.name = pllen_name;
+ init.ops = &davinci_pllen_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.flags = CLK_SET_RATE_PARENT;
+
+ pllen->hw.init = &init;
+ pllen->base = base;
+
+ clk = devm_clk_register(dev, &pllen->hw);
+ if (IS_ERR(clk))
+ return clk;
+
+ clk_notifier_register(clk, &davinci_pllen_notifier);
+
+ return pllout_clk;
+}
+
+/**
+ * davinci_pll_auxclk_register - Register bypass clock (AUXCLK)
+ * @name: The clock name
+ * @base: The PLL memory region
+ */
+struct clk *davinci_pll_auxclk_register(struct device *dev,
+ const char *name,
+ void __iomem *base)
+{
+ return clk_register_gate(dev, name, OSCIN_CLK_NAME, 0, base + CKEN,
+ CKEN_AUXEN_SHIFT, 0, NULL);
+}
+
+/**
+ * davinci_pll_sysclkbp_clk_register - Register bypass divider clock (SYSCLKBP)
+ * @name: The clock name
+ * @base: The PLL memory region
+ */
+struct clk *davinci_pll_sysclkbp_clk_register(struct device *dev,
+ const char *name,
+ void __iomem *base)
+{
+ return clk_register_divider(dev, name, OSCIN_CLK_NAME, 0, base + BPDIV,
+ DIV_RATIO_SHIFT, DIV_RATIO_WIDTH,
+ CLK_DIVIDER_READ_ONLY, NULL);
+}
+
+/**
+ * davinci_pll_obsclk_register - Register oscillator divider clock (OBSCLK)
+ * @info: The clock info
+ * @base: The PLL memory region
+ */
+struct clk *
+davinci_pll_obsclk_register(struct device *dev,
+ const struct davinci_pll_obsclk_info *info,
+ void __iomem *base)
+{
+ struct clk_mux *mux;
+ struct clk_gate *gate;
+ struct clk_divider *divider;
+ u32 oscdiv;
+
+ mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ return ERR_PTR(-ENOMEM);
+
+ mux->reg = base + OCSEL;
+ mux->table = info->table;
+ mux->mask = info->ocsrc_mask;
+
+ gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ gate->reg = base + CKEN;
+ gate->bit_idx = CKEN_OBSCLK_SHIFT;
+
+ divider = devm_kzalloc(dev, sizeof(*divider), GFP_KERNEL);
+ if (!divider)
+ return ERR_PTR(-ENOMEM);
+
+ divider->reg = base + OSCDIV;
+ divider->shift = DIV_RATIO_SHIFT;
+ divider->width = DIV_RATIO_WIDTH;
+
+ /* make sure divider is enabled just in case bootloader disabled it */
+ oscdiv = readl(base + OSCDIV);
+ oscdiv |= BIT(DIV_ENABLE_SHIFT);
+ writel(oscdiv, base + OSCDIV);
+
+ return clk_register_composite(dev, info->name, info->parent_names,
+ info->num_parents,
+ &mux->hw, &clk_mux_ops,
+ ÷r->hw, &clk_divider_ops,
+ &gate->hw, &clk_gate_ops, 0);
+}
+
+/* The PLL SYSCLKn clocks have a mechanism for synchronizing rate changes. */
+static int davinci_pll_sysclk_rate_change(struct notifier_block *nb,
+ unsigned long flags, void *data)
+{
+ struct clk_notifier_data *cnd = data;
+ struct clk_hw *hw = __clk_get_hw(clk_get_parent(cnd->clk));
+ struct davinci_pllen_clk *pll = to_davinci_pllen_clk(hw);
+ u32 pllcmd, pllstat;
+
+ switch (flags) {
+ case POST_RATE_CHANGE:
+ /* apply the changes */
+ pllcmd = readl(pll->base + PLLCMD);
+ pllcmd |= PLLCMD_GOSET;
+ writel(pllcmd, pll->base + PLLCMD);
+ /* fallthrough */
+ case PRE_RATE_CHANGE:
+ /* Wait until for outstanding changes to take effect */
+ do {
+ pllstat = readl(pll->base + PLLSTAT);
+ } while (pllstat & PLLSTAT_GOSTAT);
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block davinci_pll_sysclk_notifier = {
+ .notifier_call = davinci_pll_sysclk_rate_change,
+};
+
+/**
+ * davinci_pll_sysclk_register - Register divider clocks (SYSCLKn)
+ * @info: The clock info
+ * @base: The PLL memory region
+ */
+struct clk *
+davinci_pll_sysclk_register(struct device *dev,
+ const struct davinci_pll_sysclk_info *info,
+ void __iomem *base)
+{
+ const struct clk_ops *divider_ops = &clk_divider_ops;
+ struct clk_gate *gate;
+ struct clk_divider *divider;
+ struct clk *clk;
+ u32 reg;
+ u32 flags = 0;
+
+ /* PLLDIVn registers are not entirely consecutive */
+ if (info->id < 4)
+ reg = PLLDIV1 + 4 * (info->id - 1);
+ else
+ reg = PLLDIV4 + 4 * (info->id - 4);
+
+ gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ gate->reg = base + reg;
+ gate->bit_idx = DIV_ENABLE_SHIFT;
+
+ divider = devm_kzalloc(dev, sizeof(*divider), GFP_KERNEL);
+ if (!divider)
+ return ERR_PTR(-ENOMEM);
+
+ divider->reg = base + reg;
+ divider->shift = DIV_RATIO_SHIFT;
+ divider->width = info->ratio_width;
+ divider->flags = 0;
+
+ if (info->flags & SYSCLK_FIXED_DIV) {
+ divider->flags |= CLK_DIVIDER_READ_ONLY;
+ divider_ops = &clk_divider_ro_ops;
+ }
+
+ /* Only the ARM clock can change the parent PLL rate */
+ if (info->flags & SYSCLK_ARM_RATE)
+ flags |= CLK_SET_RATE_PARENT;
+
+ if (info->flags & SYSCLK_ALWAYS_ENABLED)
+ flags |= CLK_IS_CRITICAL;
+
+ clk = clk_register_composite(dev, info->name, &info->parent_name, 1,
+ NULL, NULL, ÷r->hw, divider_ops,
+ &gate->hw, &clk_gate_ops, flags);
+ if (IS_ERR(clk))
+ return clk;
+
+ clk_notifier_register(clk, &davinci_pll_sysclk_notifier);
+
+ return clk;
+}
+
+int of_davinci_pll_init(struct device *dev,
+ const struct davinci_pll_clk_info *info,
+ const struct davinci_pll_obsclk_info *obsclk_info,
+ const struct davinci_pll_sysclk_info **div_info,
+ u8 max_sysclk_id,
+ void __iomem *base)
+{
+ struct device_node *node = dev->of_node;
+ struct device_node *child;
+ const char *parent_name;
+ struct clk *clk;
+
+ if (info->flags & PLL_HAS_CLKMODE)
+ parent_name = of_clk_get_parent_name(node, 0);
+ else
+ parent_name = OSCIN_CLK_NAME;
+
+ clk = davinci_pll_clk_register(dev, info, parent_name, base);
+ if (IS_ERR(clk)) {
+ dev_err(dev, "failed to register %s\n", info->name);
+ return PTR_ERR(clk);
+ }
+
+ child = of_get_child_by_name(node, "pllout");
+ if (of_device_is_available(child))
+ of_clk_add_provider(child, of_clk_src_simple_get, clk);
+ of_node_put(child);
+
+ child = of_get_child_by_name(node, "sysclk");
+ if (of_device_is_available(child)) {
+ struct clk_onecell_data *clk_data;
+ struct clk **clks;
+ int n_clks = max_sysclk_id + 1;
+ int i;
+
+ clk_data = devm_kzalloc(dev, sizeof(*clk_data), GFP_KERNEL);
+ if (!clk_data)
+ return -ENOMEM;
+
+ clks = devm_kmalloc_array(dev, n_clks, sizeof(*clks), GFP_KERNEL);
+ if (!clks)
+ return -ENOMEM;
+
+ clk_data->clks = clks;
+ clk_data->clk_num = n_clks;
+
+ for (i = 0; i < n_clks; i++)
+ clks[i] = ERR_PTR(-ENOENT);
+
+ for (; *div_info; div_info++) {
+ clk = davinci_pll_sysclk_register(dev, *div_info, base);
+ if (IS_ERR(clk))
+ dev_warn(dev, "failed to register %s (%ld)\n",
+ (*div_info)->name, PTR_ERR(clk));
+ else
+ clks[(*div_info)->id] = clk;
+ }
+ of_clk_add_provider(child, of_clk_src_onecell_get, clk_data);
+ }
+ of_node_put(child);
+
+ child = of_get_child_by_name(node, "auxclk");
+ if (of_device_is_available(child)) {
+ char child_name[MAX_NAME_SIZE];
+
+ snprintf(child_name, MAX_NAME_SIZE, "%s_auxclk", info->name);
+
+ clk = davinci_pll_auxclk_register(dev, child_name, base);
+ if (IS_ERR(clk))
+ dev_warn(dev, "failed to register %s (%ld)\n",
+ child_name, PTR_ERR(clk));
+ else
+ of_clk_add_provider(child, of_clk_src_simple_get, clk);
+ }
+ of_node_put(child);
+
+ child = of_get_child_by_name(node, "obsclk");
+ if (of_device_is_available(child)) {
+ if (obsclk_info)
+ clk = davinci_pll_obsclk_register(dev, obsclk_info, base);
+ else
+ clk = ERR_PTR(-EINVAL);
+
+ if (IS_ERR(clk))
+ dev_warn(dev, "failed to register obsclk (%ld)\n",
+ PTR_ERR(clk));
+ else
+ of_clk_add_provider(child, of_clk_src_simple_get, clk);
+ }
+ of_node_put(child);
+
+ return 0;
+}
+
+static const struct of_device_id davinci_pll_of_match[] = {
+ { }
+};
+
+static const struct platform_device_id davinci_pll_id_table[] = {
+ { }
+};
+
+typedef int (*davinci_pll_init)(struct device *dev, void __iomem *base);
+
+static int davinci_pll_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const struct of_device_id *of_id;
+ davinci_pll_init pll_init = NULL;
+ struct resource *res;
+ void __iomem *base;
+
+ of_id = of_match_device(davinci_pll_of_match, dev);
+ if (of_id)
+ pll_init = of_id->data;
+ else if (pdev->id_entry)
+ pll_init = (void *)pdev->id_entry->driver_data;
+
+ if (!pll_init) {
+ dev_err(dev, "unable to find driver data\n");
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(base)) {
+ dev_err(dev, "ioremap failed\n");
+ return PTR_ERR(base);
+ }
+
+ return pll_init(dev, base);
+}
+
+static struct platform_driver davinci_pll_driver = {
+ .probe = davinci_pll_probe,
+ .driver = {
+ .name = "davinci-pll-clk",
+ .of_match_table = davinci_pll_of_match,
+ },
+ .id_table = davinci_pll_id_table,
+};
+
+static int __init davinci_pll_driver_init(void)
+{
+ return platform_driver_register(&davinci_pll_driver);
+}
+
+/* has to be postcore_initcall because PSC devices depend on PLL parent clocks */
+postcore_initcall(davinci_pll_driver_init);
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+
+#define DEBUG_REG(n) \
+{ \
+ .name = #n, \
+ .offset = n, \
+}
+
+static const struct debugfs_reg32 davinci_pll_regs[] = {
+ DEBUG_REG(REVID),
+ DEBUG_REG(PLLCTL),
+ DEBUG_REG(OCSEL),
+ DEBUG_REG(PLLSECCTL),
+ DEBUG_REG(PLLM),
+ DEBUG_REG(PREDIV),
+ DEBUG_REG(PLLDIV1),
+ DEBUG_REG(PLLDIV2),
+ DEBUG_REG(PLLDIV3),
+ DEBUG_REG(OSCDIV),
+ DEBUG_REG(POSTDIV),
+ DEBUG_REG(BPDIV),
+ DEBUG_REG(PLLCMD),
+ DEBUG_REG(PLLSTAT),
+ DEBUG_REG(ALNCTL),
+ DEBUG_REG(DCHANGE),
+ DEBUG_REG(CKEN),
+ DEBUG_REG(CKSTAT),
+ DEBUG_REG(SYSTAT),
+ DEBUG_REG(PLLDIV4),
+ DEBUG_REG(PLLDIV5),
+ DEBUG_REG(PLLDIV6),
+ DEBUG_REG(PLLDIV7),
+ DEBUG_REG(PLLDIV8),
+ DEBUG_REG(PLLDIV9),
+};
+
+static int davinci_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
+{
+ struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
+ struct debugfs_regset32 *regset;
+ struct dentry *d;
+
+ regset = kzalloc(sizeof(regset), GFP_KERNEL);
+ if (!regset)
+ return -ENOMEM;
+
+ regset->regs = davinci_pll_regs;
+ regset->nregs = ARRAY_SIZE(davinci_pll_regs);
+ regset->base = pll->base;
+
+ d = debugfs_create_regset32("registers", 0400, dentry, regset);
+ if (IS_ERR(d)) {
+ kfree(regset);
+ return PTR_ERR(d);
+ }
+
+ return 0;
+}
+#endif
diff --git a/drivers/clk/davinci/pll.h b/drivers/clk/davinci/pll.h
new file mode 100644
index 0000000..52103ae
--- /dev/null
+++ b/drivers/clk/davinci/pll.h
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for TI Davinci PSC controllers
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#ifndef __CLK_DAVINCI_PLL_H___
+#define __CLK_DAVINCI_PLL_H___
+
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/types.h>
+
+#define PLL_HAS_CLKMODE BIT(0) /* PLL has PLLCTL[CLKMODE] */
+#define PLL_HAS_PREDIV BIT(1) /* has prediv before PLL */
+#define PLL_PREDIV_ALWAYS_ENABLED BIT(2) /* don't clear DEN bit */
+#define PLL_PREDIV_FIXED_DIV BIT(3) /* fixed divider value */
+#define PLL_HAS_POSTDIV BIT(4) /* has postdiv after PLL */
+#define PLL_POSTDIV_ALWAYS_ENABLED BIT(5) /* don't clear DEN bit */
+#define PLL_POSTDIV_FIXED_DIV BIT(6) /* fixed divider value */
+#define PLL_HAS_EXTCLKSRC BIT(7) /* has selectable bypass */
+#define PLL_PLLM_2X BIT(8) /* PLLM value is 2x (DM365) */
+#define PLL_PREDIV_FIXED8 BIT(9) /* DM355 quirk */
+
+/** davinci_pll_clk_info - controller-specific PLL info
+ * @name: The name of the PLL
+ * @unlock_reg: Option CFGCHIP register for unlocking PLL
+ * @unlock_mask: Bitmask used with @unlock_reg
+ * @pllm_mask: Bitmask for PLLM[PLLM] value
+ * @pllm_min: Minimum allowable value for PLLM[PLLM]
+ * @pllm_max: Maximum allowable value for PLLM[PLLM]
+ * @pllout_min_rate: Minimum allowable rate for PLLOUT
+ * @pllout_max_rate: Maximum allowable rate for PLLOUT
+ * @flags: Bitmap of PLL_* flags.
+ */
+struct davinci_pll_clk_info {
+ const char *name;
+ u32 unlock_reg;
+ u32 unlock_mask;
+ u32 pllm_mask;
+ u32 pllm_min;
+ u32 pllm_max;
+ unsigned long pllout_min_rate;
+ unsigned long pllout_max_rate;
+ u32 flags;
+};
+
+#define SYSCLK_ARM_RATE BIT(0) /* Controls ARM rate */
+#define SYSCLK_ALWAYS_ENABLED BIT(1) /* Or bad things happen */
+#define SYSCLK_FIXED_DIV BIT(2) /* Fixed divider */
+
+/** davinci_pll_sysclk_info - SYSCLKn-specific info
+ * @name: The name of the clock
+ * @parent_name: The name of the parent clock
+ * @id: "n" in "SYSCLKn"
+ * @ratio_width: Width (in bits) of RATIO in PLLDIVn register
+ * @flags: Bitmap of SYSCLK_* flags.
+ */
+struct davinci_pll_sysclk_info {
+ const char *name;
+ const char *parent_name;
+ u32 id;
+ u32 ratio_width;
+ u32 flags;
+};
+
+#define SYSCLK(i, n, p, w, f) \
+static const struct davinci_pll_sysclk_info n = { \
+ .name = #n, \
+ .parent_name = #p, \
+ .id = (i), \
+ .ratio_width = (w), \
+ .flags = (f), \
+}
+
+/** davinci_pll_obsclk_info - OBSCLK-specific info
+ * @name: The name of the clock
+ * @parent_names: Array of names of the parent clocks
+ * @num_parents: Length of @parent_names
+ * @table: Array of values to write to OCSEL[OCSRC] cooresponding to
+ * @parent_names
+ * @ocsrc_mask: Bitmask for OCSEL[OCSRC]
+ */
+struct davinci_pll_obsclk_info {
+ const char *name;
+ const char * const *parent_names;
+ u8 num_parents;
+ u32 *table;
+ u32 ocsrc_mask;
+};
+
+struct clk *davinci_pll_clk_register(struct device *dev,
+ const struct davinci_pll_clk_info *info,
+ const char *parent_name,
+ void __iomem *base);
+struct clk *davinci_pll_auxclk_register(struct device *dev,
+ const char *name,
+ void __iomem *base);
+struct clk *davinci_pll_sysclkbp_clk_register(struct device *dev,
+ const char *name,
+ void __iomem *base);
+struct clk *
+davinci_pll_obsclk_register(struct device *dev,
+ const struct davinci_pll_obsclk_info *info,
+ void __iomem *base);
+struct clk *
+davinci_pll_sysclk_register(struct device *dev,
+ const struct davinci_pll_sysclk_info *info,
+ void __iomem *base);
+
+int of_davinci_pll_init(struct device *dev,
+ const struct davinci_pll_clk_info *info,
+ const struct davinci_pll_obsclk_info *obsclk_info,
+ const struct davinci_pll_sysclk_info **div_info,
+ u8 max_sysclk_id,
+ void __iomem *base);
+
+#endif /* __CLK_DAVINCI_PLL_H___ */
diff --git a/include/linux/platform_data/clk-davinci-pll.h b/include/linux/platform_data/clk-davinci-pll.h
new file mode 100644
index 0000000..e55dab1
--- /dev/null
+++ b/include/linux/platform_data/clk-davinci-pll.h
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock driver for TI Davinci SoCs
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#ifndef __LINUX_PLATFORM_DATA_CLK_DAVINCI_PLL_H__
+#define __LINUX_PLATFORM_DATA_CLK_DAVINCI_PLL_H__
+
+#include <linux/regmap.h>
+
+/**
+ * davinci_pll_platform_data
+ * @cfgchip: CFGCHIP syscon regmap
+ */
+struct davinci_pll_platform_data {
+ struct regmap *cfgchip;
+};
+
+#endif /* __LINUX_PLATFORM_DATA_CLK_DAVINCI_PLL_H__ */
--
2.7.4
This adds a new binding for the PLL IP blocks in the mach-davinci
family of processors. Currently, only da850 has device tree support
but these bindings can also work for other SoCs in this family just
by adding new compatible strings.
Note: Although these PLL controllers are very similar to the TI Keystone
SoCs, we are not re-using those bindings. The Keystone bindings use a
legacy one-node-per-clock binding. Furthermore, the mach-davinici SoCs
have a slightly different PLL register layout and a number of quirks
that can't be handled by the existing bindings, so the keystone bindings
could not be used as-is anyway.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
---
v8 changes:
- None
v7 changes:
- None (there was some debate about having child nodes, but the consensus was
that this is "good enough" as it is)
v6 changes:
- Added clock-names property
- Added ti,clkmode-square-wave property
- Added pllout child node
- Added obsclk child node
- Expanded examples
.../devicetree/bindings/clock/ti/davinci/pll.txt | 96 ++++++++++++++++++++++
1 file changed, 96 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
diff --git a/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt b/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
new file mode 100644
index 0000000..36998e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
@@ -0,0 +1,96 @@
+Binding for TI DaVinci PLL Controllers
+
+The PLL provides clocks to most of the components on the SoC. In addition
+to the PLL itself, this controller also contains bypasses, gates, dividers,
+an multiplexers for various clock signals.
+
+Required properties:
+- compatible: shall be one of:
+ - "ti,da850-pll0" for PLL0 on DA850/OMAP-L138/AM18XX
+ - "ti,da850-pll1" for PLL1 on DA850/OMAP-L138/AM18XX
+- reg: physical base address and size of the controller's register area.
+- clocks: phandles corresponding to the clock names
+- clock-names: names of the clock sources - depends on compatible string
+ - for "ti,da850-pll0", shall be "clksrc", "extclksrc"
+ - for "ti,da850-pll1", shall be "clksrc"
+
+Optional properties:
+- ti,clkmode-square-wave: Indicates that the the board is supplying a square
+ wave input on the OSCIN pin instead of using a crystal oscillator.
+ This property is only valid when compatible = "ti,da850-pll0".
+
+
+Optional child nodes:
+
+pllout
+ Describes the main PLL clock output (before POSTDIV). The node name must
+ be "pllout".
+
+ Required properties:
+ - #clock-cells: shall be 0
+
+sysclk
+ Describes the PLLDIVn divider clocks that provide the SYSCLKn clock
+ domains. The node name must be "sysclk". Consumers of this node should
+ use "n" in "SYSCLKn" as the index parameter for the clock cell.
+
+ Required properties:
+ - #clock-cells: shall be 1
+
+auxclk
+ Describes the AUXCLK output of the PLL. The node name must be "auxclk".
+ This child node is only valid when compatible = "ti,da850-pll0".
+
+ Required properties:
+ - #clock-cells: shall be 0
+
+obsclk
+ Describes the OBSCLK output of the PLL. The node name must be "obsclk".
+
+ Required properties:
+ - #clock-cells: shall be 0
+
+
+Examples:
+
+ pll0: clock-controller@11000 {
+ compatible = "ti,da850-pll0";
+ reg = <0x11000 0x1000>;
+ clocks = <&ref_clk>, <&pll1_sysclk 3>;
+ clock-names = "clksrc", "extclksrc";
+ ti,clkmode-square-wave;
+
+ pll0_pllout: pllout {
+ #clock-cells = <0>;
+ };
+
+ pll0_sysclk: sysclk {
+ #clock-cells = <1>;
+ };
+
+ pll0_auxclk: auxclk {
+ #clock-cells = <0>;
+ };
+
+ pll0_obsclk: obsclk {
+ #clock-cells = <0>;
+ };
+ };
+
+ pll1: clock-controller@21a000 {
+ compatible = "ti,da850-pll1";
+ reg = <0x21a000 0x1000>;
+ clocks = <&ref_clk>;
+ clock-names = "clksrc";
+
+ pll0_sysclk: sysclk {
+ #clock-cells = <1>;
+ };
+
+ pll0_obsclk: obsclk {
+ #clock-cells = <0>;
+ };
+ };
+
+Also see:
+- Documentation/devicetree/bindings/clock/clock-bindings.txt
--
2.7.4
This adds platform-specific declarations for the PLL clocks on TI
DM365 based systems.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- drop __init and __initconst attributes
- add a clkdev lookup for each SYSCLK
v7 changes:
- split registration functions for each PLL
- Add platform_device_id lookup
v6 changes:
- Added dm365_pll{1,2}_info with controller-specific information
- Changed OBSCLK data
- Add empty lines between function calls
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-dm365.c | 145 ++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/pll.c | 2 +
drivers/clk/davinci/pll.h | 3 +
4 files changed, 151 insertions(+)
create mode 100644 drivers/clk/davinci/pll-dm365.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index 6720bd0..353aa02 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -5,4 +5,5 @@ obj-y += pll.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += pll-da830.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o
obj-$(CONFIG_ARCH_DAVINCI_DM355) += pll-dm355.o
+obj-$(CONFIG_ARCH_DAVINCI_DM365) += pll-dm365.o
endif
diff --git a/drivers/clk/davinci/pll-dm365.c b/drivers/clk/davinci/pll-dm365.c
new file mode 100644
index 0000000..5f8d9f4
--- /dev/null
+++ b/drivers/clk/davinci/pll-dm365.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DM365
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/bitops.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+#define OCSEL_OCSRC_ENABLE 0
+
+static const struct davinci_pll_clk_info dm365_pll1_info = {
+ .name = "pll1",
+ .pllm_mask = GENMASK(9, 0),
+ .pllm_min = 1,
+ .pllm_max = 1023,
+ .flags = PLL_HAS_CLKMODE | PLL_HAS_PREDIV | PLL_HAS_POSTDIV |
+ PLL_POSTDIV_ALWAYS_ENABLED | PLL_PLLM_2X,
+};
+
+SYSCLK(1, pll1_sysclk1, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(2, pll1_sysclk2, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(3, pll1_sysclk3, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(4, pll1_sysclk4, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(5, pll1_sysclk5, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(6, pll1_sysclk6, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(7, pll1_sysclk7, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(8, pll1_sysclk8, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(9, pll1_sysclk9, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+
+/*
+ * This is a bit of a hack to make OCSEL[OCSRC] on DM365 look like OCSEL[OCSRC]
+ * on DA850. On DM365, OCSEL[OCSRC] is just an enable/disable bit instead of a
+ * multiplexer. By modeling it as a single parent mux clock, the clock code will
+ * still do the right thing in this case.
+ */
+static const char * const dm365_pll_obsclk_parent_names[] = {
+ "oscin",
+};
+
+static u32 dm365_pll_obsclk_table[] = {
+ OCSEL_OCSRC_ENABLE,
+};
+
+static const struct davinci_pll_obsclk_info dm365_pll1_obsclk_info = {
+ .name = "pll1_obsclk",
+ .parent_names = dm365_pll_obsclk_parent_names,
+ .num_parents = ARRAY_SIZE(dm365_pll_obsclk_parent_names),
+ .table = dm365_pll_obsclk_table,
+ .ocsrc_mask = BIT(4),
+};
+
+int dm365_pll1_init(struct device *dev, void __iomem *base)
+{
+ struct clk *clk;
+
+ davinci_pll_clk_register(dev, &dm365_pll1_info, "ref_clk", base);
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk1, base);
+ clk_register_clkdev(clk, "pll1_sysclk1", "dm365-psc");
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk2, base);
+ clk_register_clkdev(clk, "pll1_sysclk2", "dm365-psc");
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk3, base);
+ clk_register_clkdev(clk, "pll1_sysclk3", "dm365-psc");
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk4, base);
+ clk_register_clkdev(clk, "pll1_sysclk4", "dm365-psc");
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk5, base);
+ clk_register_clkdev(clk, "pll1_sysclk5", "dm365-psc");
+
+ davinci_pll_sysclk_register(dev, &pll1_sysclk6, base);
+
+ davinci_pll_sysclk_register(dev, &pll1_sysclk7, base);
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk8, base);
+ clk_register_clkdev(clk, "pll1_sysclk8", "dm365-psc");
+
+ davinci_pll_sysclk_register(dev, &pll1_sysclk9, base);
+
+ clk = davinci_pll_auxclk_register(dev, "pll1_auxclk", base);
+ clk_register_clkdev(clk, "pll1_auxclk", "dm355-psc");
+
+ davinci_pll_sysclkbp_clk_register(dev, "pll1_sysclkbp", base);
+
+ davinci_pll_obsclk_register(dev, &dm365_pll1_obsclk_info, base);
+
+ return 0;
+}
+
+static const struct davinci_pll_clk_info dm365_pll2_info = {
+ .name = "pll2",
+ .pllm_mask = GENMASK(9, 0),
+ .pllm_min = 1,
+ .pllm_max = 1023,
+ .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV | PLL_POSTDIV_ALWAYS_ENABLED |
+ PLL_PLLM_2X,
+};
+
+SYSCLK(1, pll2_sysclk1, pll2_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(2, pll2_sysclk2, pll2_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(3, pll2_sysclk3, pll2_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(4, pll2_sysclk4, pll2_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(5, pll2_sysclk5, pll2_pllen, 5, SYSCLK_ALWAYS_ENABLED);
+
+static const struct davinci_pll_obsclk_info dm365_pll2_obsclk_info = {
+ .name = "pll2_obsclk",
+ .parent_names = dm365_pll_obsclk_parent_names,
+ .num_parents = ARRAY_SIZE(dm365_pll_obsclk_parent_names),
+ .table = dm365_pll_obsclk_table,
+ .ocsrc_mask = BIT(4),
+};
+
+int dm365_pll2_init(struct device *dev, void __iomem *base)
+{
+ struct clk *clk;
+
+ davinci_pll_clk_register(dev, &dm365_pll2_info, "oscin", base);
+
+ davinci_pll_sysclk_register(dev, &pll2_sysclk1, base);
+
+ clk = davinci_pll_sysclk_register(dev, &pll2_sysclk2, base);
+ clk_register_clkdev(clk, "pll1_sysclk2", "dm365-psc");
+
+ davinci_pll_sysclk_register(dev, &pll2_sysclk3, base);
+
+ clk = davinci_pll_sysclk_register(dev, &pll2_sysclk4, base);
+ clk_register_clkdev(clk, "pll1_sysclk4", "dm365-psc");
+
+ davinci_pll_sysclk_register(dev, &pll2_sysclk5, base);
+
+ davinci_pll_auxclk_register(dev, "pll2_auxclk", base);
+
+ davinci_pll_obsclk_register(dev, &dm365_pll2_obsclk_info, base);
+
+ return 0;
+}
diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c
index 305d2e9..3d8f4d2 100644
--- a/drivers/clk/davinci/pll.c
+++ b/drivers/clk/davinci/pll.c
@@ -782,6 +782,8 @@ static const struct platform_device_id davinci_pll_id_table[] = {
{ .name = "da850-pll1", .driver_data = (kernel_ulong_t)da850_pll1_init },
{ .name = "dm355-pll1", .driver_data = (kernel_ulong_t)dm355_pll1_init },
{ .name = "dm355-pll2", .driver_data = (kernel_ulong_t)dm355_pll2_init },
+ { .name = "dm365-pll1", .driver_data = (kernel_ulong_t)dm365_pll1_init },
+ { .name = "dm365-pll2", .driver_data = (kernel_ulong_t)dm365_pll2_init },
{ }
};
diff --git a/drivers/clk/davinci/pll.h b/drivers/clk/davinci/pll.h
index d90d308..bf9fdc8 100644
--- a/drivers/clk/davinci/pll.h
+++ b/drivers/clk/davinci/pll.h
@@ -129,4 +129,7 @@ int of_da850_pll1_init(struct device *dev, void __iomem *base);
int dm355_pll1_init(struct device *dev, void __iomem *base);
int dm355_pll2_init(struct device *dev, void __iomem *base);
+int dm365_pll1_init(struct device *dev, void __iomem *base);
+int dm365_pll2_init(struct device *dev, void __iomem *base);
+
#endif /* __CLK_DAVINCI_PLL_H___ */
--
2.7.4
This adds a new driver for the gate and multiplexer clocks in the
CFGCHIPn syscon registers on TI DA8XX-type SoCs.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- register clkdev lookup for async1 and async3
v7 changes:
- convert to platform device
v6 changes:
- added DIV4.5 and ASYNC1 clocks
- refactored code to be more generic
- added functions for registering clocks from board files (no longer device
tree only)
- use pr_fmt macro
drivers/clk/davinci/Makefile | 2 +
drivers/clk/davinci/da8xx-cfgchip.c | 439 ++++++++++++++++++++++++
include/linux/platform_data/clk-da8xx-cfgchip.h | 21 ++
3 files changed, 462 insertions(+)
create mode 100644 drivers/clk/davinci/da8xx-cfgchip.c
create mode 100644 include/linux/platform_data/clk-da8xx-cfgchip.h
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index 6c388d4..11178b7 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -1,6 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
ifeq ($(CONFIG_COMMON_CLK), y)
+obj-$(CONFIG_ARCH_DAVINCI_DA8XX) += da8xx-cfgchip.o
+
obj-y += pll.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += pll-da830.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o
diff --git a/drivers/clk/davinci/da8xx-cfgchip.c b/drivers/clk/davinci/da8xx-cfgchip.c
new file mode 100644
index 0000000..f0bdfea
--- /dev/null
+++ b/drivers/clk/davinci/da8xx-cfgchip.c
@@ -0,0 +1,439 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for DA8xx/AM17xx/AM18xx/OMAP-L13x CFGCHIP
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_data/clk-da8xx-cfgchip.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+/* --- Gate clocks --- */
+
+#define DA8XX_GATE_CLOCK_IS_DIV4P5 BIT(1)
+
+struct da8xx_cfgchip_gate_clk_info {
+ const char *name;
+ u32 cfgchip;
+ u32 bit;
+ u32 flags;
+};
+
+struct da8xx_cfgchip_gate_clk {
+ struct clk_hw hw;
+ struct regmap *regmap;
+ u32 reg;
+ u32 mask;
+};
+
+#define to_da8xx_cfgchip_gate_clk(_hw) \
+ container_of((_hw), struct da8xx_cfgchip_gate_clk, hw)
+
+static int da8xx_cfgchip_gate_clk_enable(struct clk_hw *hw)
+{
+ struct da8xx_cfgchip_gate_clk *clk = to_da8xx_cfgchip_gate_clk(hw);
+
+ return regmap_write_bits(clk->regmap, clk->reg, clk->mask, clk->mask);
+}
+
+static void da8xx_cfgchip_gate_clk_disable(struct clk_hw *hw)
+{
+ struct da8xx_cfgchip_gate_clk *clk = to_da8xx_cfgchip_gate_clk(hw);
+
+ regmap_write_bits(clk->regmap, clk->reg, clk->mask, 0);
+}
+
+static int da8xx_cfgchip_gate_clk_is_enabled(struct clk_hw *hw)
+{
+ struct da8xx_cfgchip_gate_clk *clk = to_da8xx_cfgchip_gate_clk(hw);
+ unsigned int val;
+
+ regmap_read(clk->regmap, clk->reg, &val);
+
+ return !!(val & clk->mask);
+}
+
+static unsigned long da8xx_cfgchip_div4p5_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ /* this clock divides by 4.5 */
+ return parent_rate * 2 / 9;
+}
+
+static const struct clk_ops da8xx_cfgchip_gate_clk_ops = {
+ .enable = da8xx_cfgchip_gate_clk_enable,
+ .disable = da8xx_cfgchip_gate_clk_disable,
+ .is_enabled = da8xx_cfgchip_gate_clk_is_enabled,
+};
+
+static const struct clk_ops da8xx_cfgchip_div4p5_clk_ops = {
+ .enable = da8xx_cfgchip_gate_clk_enable,
+ .disable = da8xx_cfgchip_gate_clk_disable,
+ .is_enabled = da8xx_cfgchip_gate_clk_is_enabled,
+ .recalc_rate = da8xx_cfgchip_div4p5_recalc_rate,
+};
+
+static struct da8xx_cfgchip_gate_clk * __init
+da8xx_cfgchip_gate_clk_register(struct device *dev,
+ const struct da8xx_cfgchip_gate_clk_info *info,
+ struct regmap *regmap)
+{
+ struct clk *parent;
+ const char *parent_name;
+ struct da8xx_cfgchip_gate_clk *gate;
+ struct clk_init_data init;
+ int ret;
+
+ parent = devm_clk_get(dev, NULL);
+ if (IS_ERR(parent))
+ return ERR_CAST(parent);
+
+ parent_name = __clk_get_name(parent);
+
+ gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = info->name;
+ if (info->flags & DA8XX_GATE_CLOCK_IS_DIV4P5)
+ init.ops = &da8xx_cfgchip_div4p5_clk_ops;
+ else
+ init.ops = &da8xx_cfgchip_gate_clk_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.flags = 0;
+
+ gate->hw.init = &init;
+ gate->regmap = regmap;
+ gate->reg = info->cfgchip;
+ gate->mask = info->bit;
+
+ ret = devm_clk_hw_register(dev, &gate->hw);
+ if (ret < 0)
+ return ERR_PTR(ret);
+
+ return gate;
+}
+
+static const struct da8xx_cfgchip_gate_clk_info da8xx_tbclksync_info __initconst = {
+ .name = "ehrpwm_tbclk",
+ .cfgchip = CFGCHIP(1),
+ .bit = CFGCHIP1_TBCLKSYNC,
+};
+
+static int __init da8xx_cfgchip_register_tbclk(struct device *dev,
+ struct regmap *regmap)
+{
+ struct da8xx_cfgchip_gate_clk *gate;
+
+ gate = da8xx_cfgchip_gate_clk_register(dev, &da8xx_tbclksync_info,
+ regmap);
+ if (IS_ERR(gate))
+ return PTR_ERR(gate);
+
+ clk_hw_register_clkdev(&gate->hw, "tbclk", "ehrpwm.0");
+ clk_hw_register_clkdev(&gate->hw, "tbclk", "ehrpwm.1");
+
+ return 0;
+}
+
+static const struct da8xx_cfgchip_gate_clk_info da8xx_div4p5ena_info __initconst = {
+ .name = "div4.5",
+ .cfgchip = CFGCHIP(3),
+ .bit = CFGCHIP3_DIV45PENA,
+ .flags = DA8XX_GATE_CLOCK_IS_DIV4P5,
+};
+
+static int __init da8xx_cfgchip_register_div4p5(struct device *dev,
+ struct regmap *regmap)
+{
+ struct da8xx_cfgchip_gate_clk *gate;
+
+ gate = da8xx_cfgchip_gate_clk_register(dev, &da8xx_div4p5ena_info, regmap);
+ if (IS_ERR(gate))
+ return PTR_ERR(gate);
+
+ return 0;
+}
+
+static int __init
+of_da8xx_cfgchip_gate_clk_init(struct device *dev,
+ const struct da8xx_cfgchip_gate_clk_info *info,
+ struct regmap *regmap)
+{
+ struct da8xx_cfgchip_gate_clk *gate;
+
+ gate = da8xx_cfgchip_gate_clk_register(dev, info, regmap);
+ if (IS_ERR(gate))
+ return PTR_ERR(gate);
+
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, gate);
+}
+
+static int __init of_da8xx_tbclksync_init(struct device *dev,
+ struct regmap *regmap)
+{
+ return of_da8xx_cfgchip_gate_clk_init(dev, &da8xx_tbclksync_info, regmap);
+}
+
+static int __init of_da8xx_div4p5ena_init(struct device *dev,
+ struct regmap *regmap)
+{
+ return of_da8xx_cfgchip_gate_clk_init(dev, &da8xx_div4p5ena_info, regmap);
+}
+
+/* --- MUX clocks --- */
+
+struct da8xx_cfgchip_mux_clk_info {
+ const char *name;
+ const char *parent0;
+ const char *parent1;
+ u32 cfgchip;
+ u32 bit;
+};
+
+struct da8xx_cfgchip_mux_clk {
+ struct clk_hw hw;
+ struct regmap *regmap;
+ u32 reg;
+ u32 mask;
+};
+
+#define to_da8xx_cfgchip_mux_clk(_hw) \
+ container_of((_hw), struct da8xx_cfgchip_mux_clk, hw)
+
+static int da8xx_cfgchip_mux_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct da8xx_cfgchip_mux_clk *clk = to_da8xx_cfgchip_mux_clk(hw);
+ unsigned int val = index ? clk->mask : 0;
+
+ return regmap_write_bits(clk->regmap, clk->reg, clk->mask, val);
+}
+
+static u8 da8xx_cfgchip_mux_clk_get_parent(struct clk_hw *hw)
+{
+ struct da8xx_cfgchip_mux_clk *clk = to_da8xx_cfgchip_mux_clk(hw);
+ unsigned int val;
+
+ regmap_read(clk->regmap, clk->reg, &val);
+
+ return (val & clk->mask) ? 1 : 0;
+}
+
+static const struct clk_ops da8xx_cfgchip_mux_clk_ops = {
+ .set_parent = da8xx_cfgchip_mux_clk_set_parent,
+ .get_parent = da8xx_cfgchip_mux_clk_get_parent,
+};
+
+static struct da8xx_cfgchip_mux_clk * __init
+da8xx_cfgchip_mux_clk_register(struct device *dev,
+ const struct da8xx_cfgchip_mux_clk_info *info,
+ struct regmap *regmap)
+{
+ const char * const parent_names[] = { info->parent0, info->parent1 };
+ struct da8xx_cfgchip_mux_clk *mux;
+ struct clk_init_data init;
+ int ret;
+
+ mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = info->name;
+ init.ops = &da8xx_cfgchip_mux_clk_ops;
+ init.parent_names = parent_names;
+ init.num_parents = 2;
+ init.flags = 0;
+
+ mux->hw.init = &init;
+ mux->regmap = regmap;
+ mux->reg = info->cfgchip;
+ mux->mask = info->bit;
+
+ ret = devm_clk_hw_register(dev, &mux->hw);
+ if (ret < 0)
+ return ERR_PTR(ret);
+
+ return mux;
+}
+
+static const struct da8xx_cfgchip_mux_clk_info da850_async1_info __initconst = {
+ .name = "async1",
+ .parent0 = "pll0_sysclk3",
+ .parent1 = "div4.5",
+ .cfgchip = CFGCHIP(3),
+ .bit = CFGCHIP3_EMA_CLKSRC,
+};
+
+static int __init da8xx_cfgchip_register_async1(struct device *dev,
+ struct regmap *regmap)
+{
+ struct da8xx_cfgchip_mux_clk *mux;
+
+ mux = da8xx_cfgchip_mux_clk_register(dev, &da850_async1_info, regmap);
+ if (IS_ERR(mux))
+ return PTR_ERR(mux);
+
+ clk_hw_register_clkdev(&mux->hw, "async1", "da850-psc0");
+
+ return 0;
+}
+
+static const struct da8xx_cfgchip_mux_clk_info da850_async3_info __initconst = {
+ .name = "async3",
+ .parent0 = "pll0_sysclk2",
+ .parent1 = "pll1_sysclk2",
+ .cfgchip = CFGCHIP(3),
+ .bit = CFGCHIP3_ASYNC3_CLKSRC,
+};
+
+static int __init da850_cfgchip_register_async3(struct device *dev,
+ struct regmap *regmap)
+{
+ struct da8xx_cfgchip_mux_clk *mux;
+ struct clk_hw *parent;
+
+ mux = da8xx_cfgchip_mux_clk_register(dev, &da850_async3_info, regmap);
+ if (IS_ERR(mux))
+ return PTR_ERR(mux);
+
+ clk_hw_register_clkdev(&mux->hw, "async3", "da850-psc1");
+
+ /* pll1_sysclk2 is not affected by CPU scaling, so use it for async3 */
+ parent = clk_hw_get_parent_by_index(&mux->hw, 1);
+ if (parent)
+ clk_set_parent(mux->hw.clk, parent->clk);
+ else
+ dev_warn(dev, "Failed to find async3 parent clock\n");
+
+ return 0;
+}
+
+static int __init
+of_da8xx_cfgchip_init_mux_clock(struct device *dev,
+ const struct da8xx_cfgchip_mux_clk_info *info,
+ struct regmap *regmap)
+{
+ struct da8xx_cfgchip_mux_clk *mux;
+
+ mux = da8xx_cfgchip_mux_clk_register(dev, info, regmap);
+ if (IS_ERR(mux))
+ return PTR_ERR(mux);
+
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &mux->hw);
+}
+
+static int __init of_da850_async1_init(struct device *dev, struct regmap *regmap)
+{
+ return of_da8xx_cfgchip_init_mux_clock(dev, &da850_async1_info, regmap);
+}
+
+static int __init of_da850_async3_init(struct device *dev, struct regmap *regmap)
+{
+ return of_da8xx_cfgchip_init_mux_clock(dev, &da850_async3_info, regmap);
+}
+
+/* --- platform device --- */
+
+static const struct of_device_id da8xx_cfgchip_of_match[] = {
+ {
+ .compatible = "ti,da830-tbclksync",
+ .data = of_da8xx_tbclksync_init,
+ },
+ {
+ .compatible = "ti,da830-div4p5ena",
+ .data = of_da8xx_div4p5ena_init,
+ },
+ {
+ .compatible = "ti,da850-async1-clksrc",
+ .data = of_da850_async1_init,
+ },
+ {
+ .compatible = "ti,da850-async3-clksrc",
+ .data = of_da850_async3_init,
+ },
+ { }
+};
+
+static const struct platform_device_id da8xx_cfgchip_id_table[] = {
+ {
+ .name = "da830-tbclksync",
+ .driver_data = (kernel_ulong_t)da8xx_cfgchip_register_tbclk,
+ },
+ {
+ .name = "da830-div4p5ena",
+ .driver_data = (kernel_ulong_t)da8xx_cfgchip_register_div4p5,
+ },
+ {
+ .name = "da850-async1-clksrc",
+ .driver_data = (kernel_ulong_t)da8xx_cfgchip_register_async1,
+ },
+ {
+ .name = "da850-async3-clksrc",
+ .driver_data = (kernel_ulong_t)da850_cfgchip_register_async3,
+ },
+ { }
+};
+
+typedef int (*da8xx_cfgchip_init)(struct device *dev, void __iomem *base);
+
+static int da8xx_cfgchip_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct da8xx_cfgchip_clk_platform_data *pdata = dev->platform_data;
+ const struct of_device_id *of_id;
+ da8xx_cfgchip_init clk_init = NULL;
+ struct regmap *regmap = NULL;
+
+ of_id = of_match_device(da8xx_cfgchip_of_match, dev);
+ if (of_id) {
+ struct device_node *parent;
+
+ clk_init = of_id->data;
+ parent = of_get_parent(dev->of_node);
+ regmap = syscon_node_to_regmap(parent);
+ of_node_put(parent);
+ } else if (pdev->id_entry && pdata) {
+ clk_init = (void *)pdev->id_entry->driver_data;
+ regmap = pdata->cfgchip;
+ }
+
+ if (!clk_init) {
+ dev_err(dev, "unable to find driver data\n");
+ return -EINVAL;
+ }
+
+ if (IS_ERR_OR_NULL(regmap)) {
+ dev_err(dev, "no regmap for CFGCHIP syscon\n");
+ return regmap ? PTR_ERR(regmap) : -ENOENT;
+ }
+
+ return clk_init(dev, regmap);
+}
+
+static struct platform_driver da8xx_cfgchip_driver = {
+ .probe = da8xx_cfgchip_probe,
+ .driver = {
+ .name = "da8xx-cfgchip-clk",
+ .of_match_table = da8xx_cfgchip_of_match,
+ },
+ .id_table = da8xx_cfgchip_id_table,
+};
+
+static int __init da8xx_cfgchip_driver_init(void)
+{
+ return platform_driver_register(&da8xx_cfgchip_driver);
+}
+
+/* has to be postcore_initcall because PSC devices depend on the async3 clock */
+postcore_initcall(da8xx_cfgchip_driver_init);
diff --git a/include/linux/platform_data/clk-da8xx-cfgchip.h b/include/linux/platform_data/clk-da8xx-cfgchip.h
new file mode 100644
index 0000000..de0f77d
--- /dev/null
+++ b/include/linux/platform_data/clk-da8xx-cfgchip.h
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * clk-da8xx-cfgchip - TI DaVinci DA8xx CFGCHIP clock driver
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#ifndef __LINUX_PLATFORM_DATA_CLK_DA8XX_CFGCHIP_H__
+#define __LINUX_PLATFORM_DATA_CLK_DA8XX_CFGCHIP_H__
+
+#include <linux/regmap.h>
+
+/**
+ * da8xx_cfgchip_clk_platform_data
+ * @cfgchip: CFGCHIP syscon regmap
+ */
+struct da8xx_cfgchip_clk_platform_data {
+ struct regmap *cfgchip;
+};
+
+#endif /* __LINUX_PLATFORM_DATA_CLK_DA8XX_CFGCHIP_H__ */
--
2.7.4
This adds platform-specific declarations for the PSC clocks on TI
DM355 based systems.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- drop use of __init and __initconst attributes
- add parent clock mappings
v7 changes:
- split registration function into two, one for each PSC
- add platform_device_id table
- don't wrap lines for readability
- add LPSC_ALWAYS_ENABLED flag to timer0 clock
v6 changes:
- change how clkdev lookups are declared
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-dm355.c | 88 +++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/psc.c | 1 +
drivers/clk/davinci/psc.h | 1 +
4 files changed, 91 insertions(+)
create mode 100644 drivers/clk/davinci/psc-dm355.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index aef0390..e0da5c3 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -12,4 +12,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DM646x) += pll-dm646x.o
obj-y += psc.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += psc-da830.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += psc-da850.o
+obj-$(CONFIG_ARCH_DAVINCI_DM355) += psc-dm355.o
endif
diff --git a/drivers/clk/davinci/psc-dm355.c b/drivers/clk/davinci/psc-dm355.c
new file mode 100644
index 0000000..249a053
--- /dev/null
+++ b/drivers/clk/davinci/psc-dm355.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DaVinci DM355
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+LPSC_CLKDEV1(vpss_master_clkdev, "master", "vpss");
+LPSC_CLKDEV1(vpss_slave_clkdev, "slave", "vpss");
+LPSC_CLKDEV1(spi1_clkdev, NULL, "spi_davinci.1");
+LPSC_CLKDEV1(mmcsd1_clkdev, NULL, "dm6441-mmc.1");
+LPSC_CLKDEV1(mcbsp1_clkdev, NULL, "davinci-mcbsp.1");
+LPSC_CLKDEV1(usb_clkdev, "usb", NULL);
+LPSC_CLKDEV1(spi2_clkdev, NULL, "spi_davinci.2");
+LPSC_CLKDEV1(aemif_clkdev, "aemif", NULL);
+LPSC_CLKDEV1(mmcsd0_clkdev, NULL, "dm6441-mmc.0");
+LPSC_CLKDEV1(mcbsp0_clkdev, NULL, "davinci-mcbsp.0");
+LPSC_CLKDEV1(i2c_clkdev, NULL, "i2c_davinci.1");
+LPSC_CLKDEV1(uart0_clkdev, NULL, "serial8250.0");
+LPSC_CLKDEV1(uart1_clkdev, NULL, "serial8250.1");
+LPSC_CLKDEV1(uart2_clkdev, NULL, "serial8250.2");
+LPSC_CLKDEV1(spi0_clkdev, NULL, "spi_davinci.0");
+/* REVISIT: gpio-davinci.c should be modified to drop con_id */
+LPSC_CLKDEV1(gpio_clkdev, "gpio", NULL);
+LPSC_CLKDEV1(timer0_clkdev, "timer0", NULL);
+LPSC_CLKDEV1(timer2_clkdev, NULL, "davinci-wdt");
+LPSC_CLKDEV1(vpss_dac_clkdev, "vpss_dac", NULL);
+
+static const struct davinci_lpsc_clk_info dm355_psc_info[] = {
+ LPSC(0, 0, vpss_master, pll1_sysclk4, vpss_master_clkdev, 0),
+ LPSC(1, 0, vpss_slave, pll1_sysclk4, vpss_slave_clkdev, 0),
+ LPSC(5, 0, timer3, pll1_auxclk, NULL, 0),
+ LPSC(6, 0, spi1, pll1_sysclk2, spi1_clkdev, 0),
+ LPSC(7, 0, mmcsd1, pll1_sysclk2, mmcsd1_clkdev, 0),
+ LPSC(8, 0, asp1, pll1_sysclk2, NULL, 0),
+ LPSC(9, 0, usb, pll1_sysclk2, usb_clkdev, 0),
+ LPSC(10, 0, pwm3, pll1_auxclk, NULL, 0),
+ LPSC(11, 0, spi2, pll1_sysclk2, spi2_clkdev, 0),
+ LPSC(12, 0, rto, pll1_auxclk, NULL, 0),
+ LPSC(14, 0, aemif, pll1_sysclk2, aemif_clkdev, 0),
+ LPSC(15, 0, mmcsd0, pll1_sysclk2, mmcsd0_clkdev, 0),
+ LPSC(17, 0, asp0, pll1_sysclk2, NULL, 0),
+ LPSC(18, 0, i2c, pll1_auxclk, i2c_clkdev, 0),
+ LPSC(19, 0, uart0, pll1_auxclk, uart0_clkdev, 0),
+ LPSC(20, 0, uart1, pll1_auxclk, uart1_clkdev, 0),
+ LPSC(21, 0, uart2, pll1_sysclk2, uart2_clkdev, 0),
+ LPSC(22, 0, spi0, pll1_sysclk2, spi0_clkdev, 0),
+ LPSC(23, 0, pwm0, pll1_auxclk, NULL, 0),
+ LPSC(24, 0, pwm1, pll1_auxclk, NULL, 0),
+ LPSC(25, 0, pwm2, pll1_auxclk, NULL, 0),
+ LPSC(26, 0, gpio, pll1_sysclk2, gpio_clkdev, 0),
+ LPSC(27, 0, timer0, pll1_auxclk, timer0_clkdev, LPSC_ALWAYS_ENABLED),
+ LPSC(28, 0, timer1, pll1_auxclk, NULL, 0),
+ /* REVISIT: why can't this be disabled? */
+ LPSC(29, 0, timer2, pll1_auxclk, timer2_clkdev, LPSC_ALWAYS_ENABLED),
+ LPSC(31, 0, arm, pll1_sysclk1, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(40, 0, mjcp, pll1_sysclk1, NULL, 0),
+ LPSC(41, 0, vpss_dac, pll1_sysclk3, vpss_dac_clkdev, 0),
+ { }
+};
+
+static int dm355_psc_init(struct device *dev, void __iomem *base)
+{
+ return davinci_psc_register_clocks(base, dm355_psc_info, 42, base);
+}
+
+static struct clk_bulk_data dm355_psc_parent_clks[] = {
+ { .id = "pll1_sysclk1" },
+ { .id = "pll1_sysclk2" },
+ { .id = "pll1_sysclk3" },
+ { .id = "pll1_sysclk4" },
+ { .id = "pll1_auxclk" },
+};
+
+const struct davinci_psc_init_data dm355_psc_init_data = {
+ .parent_clks = dm355_psc_parent_clks,
+ .num_parent_clks = ARRAY_SIZE(dm355_psc_parent_clks),
+ .psc_init = &dm355_psc_init,
+};
diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
index fa39536..0825b62 100644
--- a/drivers/clk/davinci/psc.c
+++ b/drivers/clk/davinci/psc.c
@@ -492,6 +492,7 @@ static const struct platform_device_id davinci_psc_id_table[] = {
{ .name = "da830-psc1", .driver_data = (kernel_ulong_t)&da830_psc1_init_data },
{ .name = "da850-psc0", .driver_data = (kernel_ulong_t)&da850_psc0_init_data },
{ .name = "da850-psc1", .driver_data = (kernel_ulong_t)&da850_psc1_init_data },
+ { .name = "dm355-psc", .driver_data = (kernel_ulong_t)&dm355_psc_init_data },
{ }
};
diff --git a/drivers/clk/davinci/psc.h b/drivers/clk/davinci/psc.h
index 476bd74..d672e72 100644
--- a/drivers/clk/davinci/psc.h
+++ b/drivers/clk/davinci/psc.h
@@ -100,5 +100,6 @@ extern const struct davinci_psc_init_data da850_psc0_init_data;
extern const struct davinci_psc_init_data da850_psc1_init_data;
extern const struct davinci_psc_init_data of_da850_psc0_init_data;
extern const struct davinci_psc_init_data of_da850_psc1_init_data;
+extern const struct davinci_psc_init_data dm355_psc_init_data;
#endif /* __CLK_DAVINCI_PSC_H__ */
--
2.7.4
This changes davinci_timer_init() so that we pass the clock as a
parameter instead of using clk_get(). This is done in preparation
for converting to the common clock framework.
It removes the requirement that we have to have a clock with con_id
of "timer0", which will be good for DT bindings since clock-names =
"timer0" doesn't really make sense.
Additionally, when we convert to the common clock framework, most of
the clocks will be platform devices, which will not be available at
this point during the boot process, so we will need to pass a clock
that is available (i.e. ref_clk) instead of the "timer0" clock.
NB: The comment added in time.c is not entirely true when this patch
is applied, but it will be correct once the conversion to the common
clock framework is complete in subsequent patches.
Also, drop use of extern in header file since we are touching the
definition.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- none
v7 changes:
- new in v7
arch/arm/mach-davinci/da830.c | 2 +-
arch/arm/mach-davinci/da850.c | 2 +-
arch/arm/mach-davinci/dm355.c | 2 +-
arch/arm/mach-davinci/dm365.c | 2 +-
arch/arm/mach-davinci/dm644x.c | 2 +-
arch/arm/mach-davinci/dm646x.c | 2 +-
arch/arm/mach-davinci/include/mach/common.h | 3 ++-
arch/arm/mach-davinci/time.c | 13 +++++++++----
8 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 350d767..0b17e5a 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -1224,5 +1224,5 @@ void __init da830_init(void)
void __init da830_init_time(void)
{
davinci_clk_init(da830_clks);
- davinci_timer_init();
+ davinci_timer_init(&timerp64_0_clk);
}
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 34117e61..1dbf01c 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -1396,5 +1396,5 @@ void __init da850_init(void)
void __init da850_init_time(void)
{
davinci_clk_init(da850_clks);
- davinci_timer_init();
+ davinci_timer_init(&timerp64_0_clk);
}
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index f294804..0da7516 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -1047,7 +1047,7 @@ void __init dm355_init(void)
void __init dm355_init_time(void)
{
davinci_clk_init(dm355_clks);
- davinci_timer_init();
+ davinci_timer_init(&timer0_clk);
}
int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 1e3df9d..871372a 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -1172,7 +1172,7 @@ void __init dm365_init(void)
void __init dm365_init_time(void)
{
davinci_clk_init(dm365_clks);
- davinci_timer_init();
+ davinci_timer_init(&timer0_clk);
}
static struct resource dm365_vpss_resources[] = {
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index b409801..71a16fc 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -935,7 +935,7 @@ void __init dm644x_init(void)
void __init dm644x_init_time(void)
{
davinci_clk_init(dm644x_clks);
- davinci_timer_init();
+ davinci_timer_init(&timer0_clk);
}
int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 109ab1f..e1d6e92 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -956,7 +956,7 @@ void __init dm646x_init_time(unsigned long ref_clk_rate,
ref_clk.rate = ref_clk_rate;
aux_clkin.rate = aux_clkin_rate;
davinci_clk_init(dm646x_clks);
- davinci_timer_init();
+ davinci_timer_init(&timer0_clk);
}
static int __init dm646x_init_devices(void)
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index f0d5e858..5f45d0a 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -12,11 +12,12 @@
#ifndef __ARCH_ARM_MACH_DAVINCI_COMMON_H
#define __ARCH_ARM_MACH_DAVINCI_COMMON_H
+#include <linux/clk.h>
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/reboot.h>
-extern void davinci_timer_init(void);
+void davinci_timer_init(struct clk *clk);
extern void davinci_irq_init(void);
extern void __iomem *davinci_intc_base;
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 1bb991a..2521333 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -334,10 +334,8 @@ static struct clock_event_device clockevent_davinci = {
.set_state_oneshot = davinci_set_oneshot,
};
-
-void __init davinci_timer_init(void)
+void __init davinci_timer_init(struct clk *timer_clk)
{
- struct clk *timer_clk;
struct davinci_soc_info *soc_info = &davinci_soc_info;
unsigned int clockevent_id;
unsigned int clocksource_id;
@@ -373,7 +371,14 @@ void __init davinci_timer_init(void)
}
}
- timer_clk = clk_get(NULL, "timer0");
+ /*
+ * REVISIT: Currently, timer_clk will be "ref_clk". However, the actual
+ * clock for this device comes from a PLL AUXCLK or a PSC clock
+ * (depending on the SoC). The PLL and PSC clocks are not registered
+ * until later in boot because they are platform devices. We should try
+ * again later to get the real clock so that the real clock is not
+ * turned off when disabling unused clocks, which would stop the timer.
+ */
BUG_ON(IS_ERR(timer_clk));
clk_prepare_enable(timer_clk);
--
2.7.4
This adds the new board-specific clock init in mach-davinci/da830.c
using the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Also clean up the #includes since we are adding some here.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- none
v7 changes:
- add clock platform device declarations
- register platform devices instead of registering clocks directly
- clkdev lookup is moved to drivers/clk
- add davinci prefix to commit description
v6 changes:
- add blank lines between function calls
- include da8xx_register_cfgchip()
arch/arm/mach-davinci/board-da830-evm.c | 2 +
arch/arm/mach-davinci/da830.c | 77 +++++++++++++++++++++++++++---
arch/arm/mach-davinci/include/mach/da8xx.h | 1 +
3 files changed, 74 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index 004f9c8..3973124 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -551,6 +551,8 @@ static __init void da830_evm_init(void)
struct davinci_soc_info *soc_info = &davinci_soc_info;
int ret;
+ da830_register_clocks();
+
ret = da830_register_gpio();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 0b17e5a..c1c2604 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -8,23 +8,26 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
+#include <linux/clk-provider.h>
#include <linux/gpio.h>
#include <linux/init.h>
-#include <linux/clk.h>
#include <linux/platform_data/gpio-davinci.h>
#include <asm/mach/map.h>
-#include "psc.h"
-#include <mach/irqs.h>
-#include <mach/cputype.h>
#include <mach/common.h>
-#include <mach/time.h>
+#include <mach/cputype.h>
#include <mach/da8xx.h>
+#include <mach/irqs.h>
+#include <mach/time.h>
-#include "clock.h"
#include "mux.h"
+#ifndef CONFIG_COMMON_CLK
+#include "clock.h"
+#include "psc.h"
+#endif
+
/* Offsets of the 8 compare registers on the da830 */
#define DA830_CMP12_0 0x60
#define DA830_CMP12_1 0x64
@@ -37,6 +40,7 @@
#define DA830_REF_FREQ 24000000
+#ifndef CONFIG_COMMON_CLK
static struct pll_data pll0_data = {
.num = 1,
.phys_base = DA8XX_PLL0_BASE,
@@ -432,6 +436,7 @@ static struct clk_lookup da830_clks[] = {
CLK(NULL, "rmii", &rmii_clk),
CLK(NULL, NULL, NULL),
};
+#endif
/*
* Device specific mux setup
@@ -1223,6 +1228,66 @@ void __init da830_init(void)
void __init da830_init_time(void)
{
+#ifdef CONFIG_COMMON_CLK
+ struct clk *clk;
+
+ clk = clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DA830_REF_FREQ);
+
+ davinci_timer_init(clk);
+#else
davinci_clk_init(da830_clks);
davinci_timer_init(&timerp64_0_clk);
+#endif
+}
+
+static struct resource da830_pll_resources[] = {
+ {
+ .start = DA8XX_PLL0_BASE,
+ .end = DA8XX_PLL0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device da830_pll_device = {
+ .name = "da830-pll",
+ .id = -1,
+ .resource = da830_pll_resources,
+ .num_resources = ARRAY_SIZE(da830_pll_resources),
+};
+
+static struct resource da830_psc0_resources[] = {
+ {
+ .start = DA8XX_PSC0_BASE,
+ .end = DA8XX_PSC0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device da830_psc0_device = {
+ .name = "da830-psc0",
+ .id = -1,
+ .resource = da830_psc0_resources,
+ .num_resources = ARRAY_SIZE(da830_psc0_resources),
+};
+
+static struct resource da830_psc1_resources[] = {
+ {
+ .start = DA8XX_PSC1_BASE,
+ .end = DA8XX_PSC1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device da830_psc1_device = {
+ .name = "da830-psc1",
+ .id = -1,
+ .resource = da830_psc1_resources,
+ .num_resources = ARRAY_SIZE(da830_psc1_resources),
+};
+
+void __init da830_register_clocks(void)
+{
+ platform_device_register(&da830_pll_device);
+ platform_device_register(&da830_psc0_device);
+ platform_device_register(&da830_psc1_device);
}
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 9fd6d01..64861ac 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -89,6 +89,7 @@ extern unsigned int da850_max_speed;
void da830_init(void);
void da830_init_time(void);
+void da830_register_clocks(void);
void da850_init(void);
void da850_init_time(void);
--
2.7.4
This adds platform-specific declarations for the PSC clocks on TI
DM646x based systems.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- drop use of __init and __initconst attributes
- add parent clock mappings
v7 changes:
- add platform_device_id table
- don't wrap lines for readability
- add LPSC_ALWAYS_ENABLED flag to timer0 clock
v6 changes:
- change how clkdev lookups are declared
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-dm646x.c | 80 ++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/psc.c | 1 +
drivers/clk/davinci/psc.h | 1 +
4 files changed, 83 insertions(+)
create mode 100644 drivers/clk/davinci/psc-dm646x.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index a20e379..6c388d4 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -15,4 +15,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DA850) += psc-da850.o
obj-$(CONFIG_ARCH_DAVINCI_DM355) += psc-dm355.o
obj-$(CONFIG_ARCH_DAVINCI_DM365) += psc-dm365.o
obj-$(CONFIG_ARCH_DAVINCI_DM644x) += psc-dm644x.o
+obj-$(CONFIG_ARCH_DAVINCI_DM646x) += psc-dm646x.o
endif
diff --git a/drivers/clk/davinci/psc-dm646x.c b/drivers/clk/davinci/psc-dm646x.c
new file mode 100644
index 0000000..468ef86
--- /dev/null
+++ b/drivers/clk/davinci/psc-dm646x.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DaVinci DM646x
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+LPSC_CLKDEV1(ide_clkdev, NULL, "palm_bk3710");
+LPSC_CLKDEV2(emac_clkdev, NULL, "davinci_emac.1",
+ "fck", "davinci_mdio.0");
+LPSC_CLKDEV1(aemif_clkdev, "aemif", NULL);
+LPSC_CLKDEV1(mcasp0_clkdev, NULL, "davinci-mcasp.0");
+LPSC_CLKDEV1(mcasp1_clkdev, NULL, "davinci-mcasp.1");
+LPSC_CLKDEV1(uart0_clkdev, NULL, "serial8250.0");
+LPSC_CLKDEV1(uart1_clkdev, NULL, "serial8250.1");
+LPSC_CLKDEV1(uart2_clkdev, NULL, "serial8250.2");
+LPSC_CLKDEV1(i2c_clkdev, NULL, "i2c_davinci.1");
+/* REVISIT: gpio-davinci.c should be modified to drop con_id */
+LPSC_CLKDEV1(gpio_clkdev, "gpio", NULL);
+LPSC_CLKDEV1(timer0_clkdev, "timer0", NULL);
+
+static const struct davinci_lpsc_clk_info dm646x_psc_info[] = {
+ LPSC(0, 0, arm, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ /* REVISIT how to disable? */
+ LPSC(1, 0, dsp, pll1_sysclk1, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(4, 0, edma_cc, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(5, 0, edma_tc0, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(6, 0, edma_tc1, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(7, 0, edma_tc2, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(8, 0, edma_tc3, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(10, 0, ide, pll1_sysclk4, ide_clkdev, 0),
+ LPSC(14, 0, emac, pll1_sysclk3, emac_clkdev, 0),
+ LPSC(16, 0, vpif0, ref_clk, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(17, 0, vpif1, ref_clk, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(21, 0, aemif, pll1_sysclk3, aemif_clkdev, LPSC_ALWAYS_ENABLED),
+ LPSC(22, 0, mcasp0, pll1_sysclk3, mcasp0_clkdev, 0),
+ LPSC(23, 0, mcasp1, pll1_sysclk3, mcasp1_clkdev, 0),
+ LPSC(26, 0, uart0, aux_clkin, uart0_clkdev, 0),
+ LPSC(27, 0, uart1, aux_clkin, uart1_clkdev, 0),
+ LPSC(28, 0, uart2, aux_clkin, uart2_clkdev, 0),
+ /* REVIST: disabling hangs system */
+ LPSC(29, 0, pwm0, pll1_sysclk3, NULL, LPSC_ALWAYS_ENABLED),
+ /* REVIST: disabling hangs system */
+ LPSC(30, 0, pwm1, pll1_sysclk3, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(31, 0, i2c, pll1_sysclk3, i2c_clkdev, 0),
+ LPSC(33, 0, gpio, pll1_sysclk3, gpio_clkdev, 0),
+ LPSC(34, 0, timer0, pll1_sysclk3, timer0_clkdev, LPSC_ALWAYS_ENABLED),
+ LPSC(35, 0, timer1, pll1_sysclk3, NULL, 0),
+ { }
+};
+
+static int dm646x_psc_init(struct device *dev, void __iomem *base)
+{
+ return davinci_psc_register_clocks(dev, dm646x_psc_info, 46, base);
+}
+
+static struct clk_bulk_data dm646x_psc_parent_clks[] = {
+ { .id = "ref_clk" },
+ { .id = "aux_clkin" },
+ { .id = "pll1_sysclk1" },
+ { .id = "pll1_sysclk2" },
+ { .id = "pll1_sysclk3" },
+ { .id = "pll1_sysclk4" },
+ { .id = "pll1_sysclk5" },
+};
+
+const struct davinci_psc_init_data dm646x_psc_init_data = {
+ .parent_clks = dm646x_psc_parent_clks,
+ .num_parent_clks = ARRAY_SIZE(dm646x_psc_parent_clks),
+ .psc_init = &dm646x_psc_init,
+};
diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
index 6520938..3b0e59d 100644
--- a/drivers/clk/davinci/psc.c
+++ b/drivers/clk/davinci/psc.c
@@ -495,6 +495,7 @@ static const struct platform_device_id davinci_psc_id_table[] = {
{ .name = "dm355-psc", .driver_data = (kernel_ulong_t)&dm355_psc_init_data },
{ .name = "dm365-psc", .driver_data = (kernel_ulong_t)&dm365_psc_init_data },
{ .name = "dm644x-psc", .driver_data = (kernel_ulong_t)&dm644x_psc_init_data },
+ { .name = "dm646x-psc", .driver_data = (kernel_ulong_t)&dm646x_psc_init_data },
{ }
};
diff --git a/drivers/clk/davinci/psc.h b/drivers/clk/davinci/psc.h
index d665cb0..c2a7df6 100644
--- a/drivers/clk/davinci/psc.h
+++ b/drivers/clk/davinci/psc.h
@@ -103,5 +103,6 @@ extern const struct davinci_psc_init_data of_da850_psc1_init_data;
extern const struct davinci_psc_init_data dm355_psc_init_data;
extern const struct davinci_psc_init_data dm365_psc_init_data;
extern const struct davinci_psc_init_data dm644x_psc_init_data;
+extern const struct davinci_psc_init_data dm646x_psc_init_data;
#endif /* __CLK_DAVINCI_PSC_H__ */
--
2.7.4
This adds platform-specific declarations for the PSC clocks on TI
DM644x based systems.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- drop use of __init and __initconst attributes
- add parent clock mappings
v7 changes:
- add platform_device_id table
- don't wrap lines for readability
- add LPSC_ALWAYS_ENABLED flag to timer0 clock
v6 changes:
- change how clkdev lookups are declared
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-dm644x.c | 83 ++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/psc.c | 1 +
drivers/clk/davinci/psc.h | 1 +
4 files changed, 86 insertions(+)
create mode 100644 drivers/clk/davinci/psc-dm644x.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index 78dc1eb..a20e379 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -14,4 +14,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DA830) += psc-da830.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += psc-da850.o
obj-$(CONFIG_ARCH_DAVINCI_DM355) += psc-dm355.o
obj-$(CONFIG_ARCH_DAVINCI_DM365) += psc-dm365.o
+obj-$(CONFIG_ARCH_DAVINCI_DM644x) += psc-dm644x.o
endif
diff --git a/drivers/clk/davinci/psc-dm644x.c b/drivers/clk/davinci/psc-dm644x.c
new file mode 100644
index 0000000..c22367b
--- /dev/null
+++ b/drivers/clk/davinci/psc-dm644x.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DaVinci DM644x
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+LPSC_CLKDEV1(vpss_master_clkdev, "master", "vpss");
+LPSC_CLKDEV1(vpss_slave_clkdev, "slave", "vpss");
+LPSC_CLKDEV2(emac_clkdev, NULL, "davinci_emac.1",
+ "fck", "davinci_mdio.0");
+LPSC_CLKDEV1(usb_clkdev, "usb", NULL);
+LPSC_CLKDEV1(ide_clkdev, NULL, "palm_bk3710");
+LPSC_CLKDEV1(aemif_clkdev, "aemif", NULL);
+LPSC_CLKDEV1(mmcsd_clkdev, NULL, "dm6441-mmc.0");
+LPSC_CLKDEV1(asp0_clkdev, NULL, "davinci-mcbsp");
+LPSC_CLKDEV1(i2c_clkdev, NULL, "i2c_davinci.1");
+LPSC_CLKDEV1(uart0_clkdev, NULL, "serial8250.0");
+LPSC_CLKDEV1(uart1_clkdev, NULL, "serial8250.1");
+LPSC_CLKDEV1(uart2_clkdev, NULL, "serial8250.2");
+/* REVISIT: gpio-davinci.c should be modified to drop con_id */
+LPSC_CLKDEV1(gpio_clkdev, "gpio", NULL);
+LPSC_CLKDEV1(timer0_clkdev, "timer0", NULL);
+LPSC_CLKDEV1(timer2_clkdev, NULL, "davinci-wdt");
+
+static const struct davinci_lpsc_clk_info dm644x_psc_info[] = {
+ LPSC(0, 0, vpss_master, pll1_sysclk3, vpss_master_clkdev, 0),
+ LPSC(1, 0, vpss_slave, pll1_sysclk3, vpss_slave_clkdev, 0),
+ LPSC(6, 0, emac, pll1_sysclk5, emac_clkdev, 0),
+ LPSC(9, 0, usb, pll1_sysclk5, usb_clkdev, 0),
+ LPSC(10, 0, ide, pll1_sysclk5, ide_clkdev, 0),
+ LPSC(11, 0, vlynq, pll1_sysclk5, NULL, 0),
+ LPSC(14, 0, aemif, pll1_sysclk5, aemif_clkdev, 0),
+ LPSC(15, 0, mmcsd, pll1_sysclk5, mmcsd_clkdev, 0),
+ LPSC(17, 0, asp0, pll1_sysclk5, asp0_clkdev, 0),
+ LPSC(18, 0, i2c, pll1_auxclk, i2c_clkdev, 0),
+ LPSC(19, 0, uart0, pll1_auxclk, uart0_clkdev, 0),
+ LPSC(20, 0, uart1, pll1_auxclk, uart1_clkdev, 0),
+ LPSC(21, 0, uart2, pll1_auxclk, uart2_clkdev, 0),
+ LPSC(22, 0, spi, pll1_sysclk5, NULL, 0),
+ LPSC(23, 0, pwm0, pll1_auxclk, NULL, 0),
+ LPSC(24, 0, pwm1, pll1_auxclk, NULL, 0),
+ LPSC(25, 0, pwm2, pll1_auxclk, NULL, 0),
+ LPSC(26, 0, gpio, pll1_sysclk5, gpio_clkdev, 0),
+ LPSC(27, 0, timer0, pll1_auxclk, timer0_clkdev, LPSC_ALWAYS_ENABLED),
+ LPSC(28, 0, timer1, pll1_auxclk, NULL, 0),
+ /* REVISIT: why can't this be disabled? */
+ LPSC(29, 0, timer2, pll1_auxclk, timer2_clkdev, LPSC_ALWAYS_ENABLED),
+ LPSC(31, 0, arm, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ /* REVISIT how to disable? */
+ LPSC(39, 1, dsp, pll1_sysclk1, NULL, LPSC_ALWAYS_ENABLED),
+ /* REVISIT how to disable? */
+ LPSC(40, 1, vicp, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ { }
+};
+
+static int dm644x_psc_init(struct device *dev, void __iomem *base)
+{
+ return davinci_psc_register_clocks(dev, dm644x_psc_info, 41, base);
+}
+
+static struct clk_bulk_data dm644x_psc_parent_clks[] = {
+ { .id = "pll1_sysclk1" },
+ { .id = "pll1_sysclk2" },
+ { .id = "pll1_sysclk3" },
+ { .id = "pll1_sysclk5" },
+ { .id = "pll1_auxclk" },
+};
+
+const struct davinci_psc_init_data dm644x_psc_init_data = {
+ .parent_clks = dm644x_psc_parent_clks,
+ .num_parent_clks = ARRAY_SIZE(dm644x_psc_parent_clks),
+ .psc_init = &dm644x_psc_init,
+};
diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
index 7bcf316..6520938 100644
--- a/drivers/clk/davinci/psc.c
+++ b/drivers/clk/davinci/psc.c
@@ -494,6 +494,7 @@ static const struct platform_device_id davinci_psc_id_table[] = {
{ .name = "da850-psc1", .driver_data = (kernel_ulong_t)&da850_psc1_init_data },
{ .name = "dm355-psc", .driver_data = (kernel_ulong_t)&dm355_psc_init_data },
{ .name = "dm365-psc", .driver_data = (kernel_ulong_t)&dm365_psc_init_data },
+ { .name = "dm644x-psc", .driver_data = (kernel_ulong_t)&dm644x_psc_init_data },
{ }
};
diff --git a/drivers/clk/davinci/psc.h b/drivers/clk/davinci/psc.h
index 4f6210e..d665cb0 100644
--- a/drivers/clk/davinci/psc.h
+++ b/drivers/clk/davinci/psc.h
@@ -102,5 +102,6 @@ extern const struct davinci_psc_init_data of_da850_psc0_init_data;
extern const struct davinci_psc_init_data of_da850_psc1_init_data;
extern const struct davinci_psc_init_data dm355_psc_init_data;
extern const struct davinci_psc_init_data dm365_psc_init_data;
+extern const struct davinci_psc_init_data dm644x_psc_init_data;
#endif /* __CLK_DAVINCI_PSC_H__ */
--
2.7.4
This adds a new driver for mach-davinci PSC clocks. This is porting the
code from arch/arm/mach-davinci/psc.c to the common clock framework and
is converting it to use regmap to simplify the code. Additionally, it
adds device tree support for these clocks.
Note: although there are similar clocks for TI Keystone we are not able
to share the code for a few reasons. The keystone clocks are device tree
only and use legacy one-node-per-clock bindings. Also the keystone
driver makes the assumption that there is only one PSC per SoC and uses
global variables, but here we have two controllers per SoC.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- get parent clocks during probe to ensure proper load order of clock drivers
- fix genpd clock reference counting issue
v7 changes:
- convert to platform device
- rename lpsc field to md
- rename PSC to LPSC where appropriate
- rename LPSC_ARM_RATE to LPSC_SET_RATE_PARENT
- add genpd provider
- add reset provider
v6 changes:
- use GENMASK
- add quirk flag for FORCE bit
- add quirk flag for propagating set_rate
- fix writing to PDSTAT instead of PDCTL
- remove unused doc comment parameter
- change davinci_psc_register_clocks() to handle registering clkdev entries
drivers/clk/davinci/Makefile | 2 +
drivers/clk/davinci/psc.c | 542 +++++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/psc.h | 97 ++++++++
3 files changed, 641 insertions(+)
create mode 100644 drivers/clk/davinci/psc.c
create mode 100644 drivers/clk/davinci/psc.h
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index d471386..cd1bf2c 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -8,4 +8,6 @@ obj-$(CONFIG_ARCH_DAVINCI_DM355) += pll-dm355.o
obj-$(CONFIG_ARCH_DAVINCI_DM365) += pll-dm365.o
obj-$(CONFIG_ARCH_DAVINCI_DM644x) += pll-dm644x.o
obj-$(CONFIG_ARCH_DAVINCI_DM646x) += pll-dm646x.o
+
+obj-y += psc.o
endif
diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
new file mode 100644
index 0000000..5613607
--- /dev/null
+++ b/drivers/clk/davinci/psc.c
@@ -0,0 +1,542 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for TI Davinci PSC controllers
+ *
+ * Copyright (C) 2017 David Lechner <[email protected]>
+ *
+ * Based on: drivers/clk/keystone/gate.c
+ * Copyright (C) 2013 Texas Instruments.
+ * Murali Karicheri <[email protected]>
+ * Santosh Shilimkar <[email protected]>
+ *
+ * And: arch/arm/mach-davinci/psc.c
+ * Copyright (C) 2006 Texas Instruments.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_domain.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+/* PSC register offsets */
+#define EPCPR 0x070
+#define PTCMD 0x120
+#define PTSTAT 0x128
+#define PDSTAT(n) (0x200 + 4 * (n))
+#define PDCTL(n) (0x300 + 4 * (n))
+#define MDSTAT(n) (0x800 + 4 * (n))
+#define MDCTL(n) (0xa00 + 4 * (n))
+
+/* PSC module states */
+enum davinci_lpsc_state {
+ LPSC_STATE_SWRSTDISABLE = 0,
+ LPSC_STATE_SYNCRST = 1,
+ LPSC_STATE_DISABLE = 2,
+ LPSC_STATE_ENABLE = 3,
+};
+
+#define MDSTAT_STATE_MASK GENMASK(5, 0)
+#define MDSTAT_MCKOUT BIT(12)
+#define PDSTAT_STATE_MASK GENMASK(4, 0)
+#define MDCTL_FORCE BIT(31)
+#define MDCTL_LRESET BIT(8)
+#define PDCTL_EPCGOOD BIT(8)
+#define PDCTL_NEXT BIT(0)
+
+struct davinci_psc_data {
+ struct clk_onecell_data clk_data;
+ struct genpd_onecell_data pm_data;
+ struct reset_controller_dev rcdev;
+};
+
+/**
+ * struct davinci_lpsc_clk - LPSC clock structure
+ * @dev: the device that provides this LPSC
+ * @hw: clk_hw for the LPSC
+ * @pm_domain: power domain for the LPSC
+ * @genpd_clk: clock reference owned by @pm_domain
+ * @regmap: PSC MMIO region
+ * @md: Module domain (LPSC module id)
+ * @pd: Power domain
+ * @flags: LPSC_* quirk flags
+ */
+struct davinci_lpsc_clk {
+ struct device *dev;
+ struct clk_hw hw;
+ struct generic_pm_domain pm_domain;
+ struct clk *genpd_clk;
+ struct regmap *regmap;
+ u32 md;
+ u32 pd;
+ u32 flags;
+};
+
+#define to_davinci_psc_data(x) container_of(x, struct davinci_psc_data, x)
+#define to_davinci_lpsc_clk(x) container_of(x, struct davinci_lpsc_clk, x)
+
+/**
+ * best_dev_name - get the "best" device name.
+ * @dev: the device
+ *
+ * Returns the device tree compatible name if the device has a DT node,
+ * otherwise return the device name. This is mainly needed because clkdev
+ * lookups are limited to 20 chars for dev_id and when using device tree,
+ * dev_name(dev) is much longer than that.
+ */
+static inline const char *best_dev_name(struct device *dev)
+{
+ const char *compatible;
+
+ if (!of_property_read_string(dev->of_node, "compatible", &compatible))
+ return compatible;
+
+ return dev_name(dev);
+}
+
+static void davinci_lpsc_config(struct davinci_lpsc_clk *lpsc,
+ enum davinci_lpsc_state next_state)
+{
+ u32 epcpr, pdstat, mdstat, ptstat;
+
+ regmap_write_bits(lpsc->regmap, MDCTL(lpsc->md), MDSTAT_STATE_MASK,
+ next_state);
+
+ if (lpsc->flags & LPSC_FORCE)
+ regmap_write_bits(lpsc->regmap, MDCTL(lpsc->md), MDCTL_FORCE,
+ MDCTL_FORCE);
+
+ regmap_read(lpsc->regmap, PDSTAT(lpsc->pd), &pdstat);
+ if ((pdstat & PDSTAT_STATE_MASK) == 0) {
+ regmap_write_bits(lpsc->regmap, PDCTL(lpsc->pd), PDCTL_NEXT,
+ PDCTL_NEXT);
+
+ regmap_write(lpsc->regmap, PTCMD, BIT(lpsc->pd));
+
+ regmap_read_poll_timeout(lpsc->regmap, EPCPR, epcpr,
+ epcpr & BIT(lpsc->pd), 0, 0);
+
+ regmap_write_bits(lpsc->regmap, PDCTL(lpsc->pd), PDCTL_EPCGOOD,
+ PDCTL_EPCGOOD);
+ } else {
+ regmap_write(lpsc->regmap, PTCMD, BIT(lpsc->pd));
+ }
+
+ regmap_read_poll_timeout(lpsc->regmap, PTSTAT, ptstat,
+ !(ptstat & BIT(lpsc->pd)), 0, 0);
+
+ regmap_read_poll_timeout(lpsc->regmap, MDSTAT(lpsc->md), mdstat,
+ (mdstat & MDSTAT_STATE_MASK) == next_state,
+ 0, 0);
+}
+
+static int davinci_lpsc_clk_enable(struct clk_hw *hw)
+{
+ struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(hw);
+
+ davinci_lpsc_config(lpsc, LPSC_STATE_ENABLE);
+
+ return 0;
+}
+
+static void davinci_lpsc_clk_disable(struct clk_hw *hw)
+{
+ struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(hw);
+
+ davinci_lpsc_config(lpsc, LPSC_STATE_DISABLE);
+}
+
+static int davinci_lpsc_clk_is_enabled(struct clk_hw *hw)
+{
+ struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(hw);
+ u32 mdstat;
+
+ regmap_read(lpsc->regmap, MDSTAT(lpsc->md), &mdstat);
+
+ return (mdstat & MDSTAT_MCKOUT) ? 1 : 0;
+}
+
+static const struct clk_ops davinci_lpsc_clk_ops = {
+ .enable = davinci_lpsc_clk_enable,
+ .disable = davinci_lpsc_clk_disable,
+ .is_enabled = davinci_lpsc_clk_is_enabled,
+};
+
+static int davinci_psc_genpd_attach_dev(struct generic_pm_domain *pm_domain,
+ struct device *dev)
+{
+ struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(pm_domain);
+ struct clk *clk;
+ int ret;
+
+ /*
+ * pm_clk_remove_clk() will call clk_put(), so we have to use clk_get()
+ * to get the clock instead of using lpsc->hw.clk directly.
+ */
+ clk = clk_get_sys(best_dev_name(lpsc->dev), clk_hw_get_name(&lpsc->hw));
+ if (IS_ERR(clk))
+ return (PTR_ERR(clk));
+
+ ret = pm_clk_create(dev);
+ if (ret < 0)
+ goto fail_clk_put;
+
+ ret = pm_clk_add_clk(dev, clk);
+ if (ret < 0)
+ goto fail_pm_clk_destroy;
+
+ lpsc->genpd_clk = clk;
+
+ return 0;
+
+fail_pm_clk_destroy:
+ pm_clk_destroy(dev);
+fail_clk_put:
+ clk_put(clk);
+
+ return ret;
+}
+
+static void davinci_psc_genpd_detach_dev(struct generic_pm_domain *pm_domain,
+ struct device *dev)
+{
+ struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(pm_domain);
+
+ pm_clk_remove_clk(dev, lpsc->genpd_clk);
+ pm_clk_destroy(dev);
+
+ lpsc->genpd_clk = NULL;
+}
+
+/**
+ * davinci_lpsc_clk_register - register LPSC clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @regmap: PSC MMIO region
+ * @md: local PSC number
+ * @pd: power domain
+ * @flags: LPSC_* flags
+ */
+static struct davinci_lpsc_clk *
+davinci_lpsc_clk_register(struct device *dev, const char *name,
+ const char *parent_name, struct regmap *regmap,
+ u32 md, u32 pd, u32 flags)
+{
+ struct clk_init_data init;
+ struct davinci_lpsc_clk *lpsc;
+ int ret;
+ bool is_on;
+
+ lpsc = devm_kzalloc(dev, sizeof(*lpsc), GFP_KERNEL);
+ if (!lpsc)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &davinci_lpsc_clk_ops;
+ init.parent_names = (parent_name ? &parent_name : NULL);
+ init.num_parents = (parent_name ? 1 : 0);
+ init.flags = 0;
+
+ if (flags & LPSC_ALWAYS_ENABLED)
+ init.flags |= CLK_IS_CRITICAL;
+
+ if (flags & LPSC_SET_RATE_PARENT)
+ init.flags |= CLK_SET_RATE_PARENT;
+
+ lpsc->dev = dev;
+ lpsc->regmap = regmap;
+ lpsc->hw.init = &init;
+ lpsc->md = md;
+ lpsc->pd = pd;
+ lpsc->flags = flags;
+
+ ret = devm_clk_hw_register(dev, &lpsc->hw);
+ if (ret < 0)
+ return ERR_PTR(ret);
+
+ /* genpd attach needs a way to look up this clock */
+ ret = clk_hw_register_clkdev(&lpsc->hw, name, best_dev_name(dev));
+
+ lpsc->pm_domain.name = devm_kasprintf(dev, GFP_KERNEL, "%s: %s",
+ best_dev_name(dev), name);
+ lpsc->pm_domain.attach_dev = davinci_psc_genpd_attach_dev;
+ lpsc->pm_domain.detach_dev = davinci_psc_genpd_detach_dev;
+ lpsc->pm_domain.flags = GENPD_FLAG_PM_CLK;
+
+ is_on = davinci_lpsc_clk_is_enabled(&lpsc->hw);
+ pm_genpd_init(&lpsc->pm_domain, NULL, is_on);
+
+ return lpsc;
+}
+
+static int davinci_lpsc_clk_reset(struct clk *clk, bool reset)
+{
+ struct clk_hw *hw = __clk_get_hw(clk);
+ struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(hw);
+ u32 mdctl;
+
+ if (IS_ERR_OR_NULL(lpsc))
+ return -EINVAL;
+
+ mdctl = reset ? 0 : MDCTL_LRESET;
+ regmap_write_bits(lpsc->regmap, MDCTL(lpsc->md), MDCTL_LRESET, mdctl);
+
+ return 0;
+}
+
+/*
+ * REVISIT: These exported functions can be removed after a non-DT lookup is
+ * added to the reset controller framework and the davinci-rproc driver is
+ * updated to use the generic reset controller framework.
+ */
+
+int davinci_clk_reset_assert(struct clk *clk)
+{
+ return davinci_lpsc_clk_reset(clk, true);
+}
+EXPORT_SYMBOL(davinci_clk_reset_assert);
+
+int davinci_clk_reset_deassert(struct clk *clk)
+{
+ return davinci_lpsc_clk_reset(clk, false);
+}
+EXPORT_SYMBOL(davinci_clk_reset_deassert);
+
+static int davinci_psc_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct davinci_psc_data *psc = to_davinci_psc_data(rcdev);
+ struct clk *clk = psc->clk_data.clks[id];
+
+ return davinci_lpsc_clk_reset(clk, true);
+}
+
+static int davinci_psc_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct davinci_psc_data *psc = to_davinci_psc_data(rcdev);
+ struct clk *clk = psc->clk_data.clks[id];
+
+ return davinci_lpsc_clk_reset(clk, false);
+}
+
+static const struct reset_control_ops davinci_psc_reset_ops = {
+ .assert = davinci_psc_reset_assert,
+ .deassert = davinci_psc_reset_deassert,
+};
+
+static int davinci_psc_reset_of_xlate(struct reset_controller_dev *rcdev,
+ const struct of_phandle_args *reset_spec)
+{
+ struct of_phandle_args clkspec = *reset_spec; /* discard const qualifier */
+ struct clk *clk;
+ struct clk_hw *hw;
+ struct davinci_lpsc_clk *lpsc;
+
+ /* the clock node is the same as the reset node */
+ clk = of_clk_get_from_provider(&clkspec);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ hw = __clk_get_hw(clk);
+ lpsc = to_davinci_lpsc_clk(hw);
+ clk_put(clk);
+
+ /* not all modules support local reset */
+ if (!(lpsc->flags & LPSC_LOCAL_RESET))
+ return -EINVAL;
+
+ return lpsc->md;
+}
+
+static const struct regmap_config davinci_psc_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+};
+
+static struct davinci_psc_data *
+__davinci_psc_register_clocks(struct device *dev,
+ const struct davinci_lpsc_clk_info *info,
+ int num_clks,
+ void __iomem *base)
+{
+ struct davinci_psc_data *psc;
+ struct clk **clks;
+ struct generic_pm_domain **pm_domains;
+ struct regmap *regmap;
+ int i, ret;
+
+ psc = devm_kzalloc(dev, sizeof(*psc), GFP_KERNEL);
+ if (!psc)
+ return ERR_PTR(-ENOMEM);
+
+ clks = devm_kmalloc_array(dev, num_clks, sizeof(*clks), GFP_KERNEL);
+ if (!clks)
+ return ERR_PTR(-ENOMEM);
+
+ psc->clk_data.clks = clks;
+ psc->clk_data.clk_num = num_clks;
+
+ /*
+ * init array with error so that of_clk_src_onecell_get() doesn't
+ * return NULL for gaps in the sparse array
+ */
+ for (i = 0; i < num_clks; i++)
+ clks[i] = ERR_PTR(-ENOENT);
+
+ pm_domains = devm_kcalloc(dev, num_clks, sizeof(*pm_domains), GFP_KERNEL);
+ if (!pm_domains)
+ return ERR_PTR(-ENOMEM);
+
+ psc->pm_data.domains = pm_domains;
+ psc->pm_data.num_domains = num_clks;
+
+ regmap = devm_regmap_init_mmio(dev, base, &davinci_psc_regmap_config);
+ if (IS_ERR(regmap))
+ return ERR_CAST(regmap);
+
+ for (; info->name; info++) {
+ struct davinci_lpsc_clk *lpsc;
+
+ lpsc = davinci_lpsc_clk_register(dev, info->name, info->parent,
+ regmap, info->md, info->pd,
+ info->flags);
+ if (IS_ERR(lpsc)) {
+ dev_warn(dev, "Failed to register %s (%ld)\n",
+ info->name, PTR_ERR(lpsc));
+ continue;
+ }
+
+ clks[info->md] = lpsc->hw.clk;
+ pm_domains[info->md] = &lpsc->pm_domain;
+ }
+
+ psc->rcdev.ops = &davinci_psc_reset_ops;
+ psc->rcdev.owner = THIS_MODULE;
+ psc->rcdev.of_node = dev->of_node;
+ psc->rcdev.of_reset_n_cells = 1;
+ psc->rcdev.of_xlate = davinci_psc_reset_of_xlate;
+ psc->rcdev.nr_resets = num_clks;
+
+ ret = devm_reset_controller_register(dev, &psc->rcdev);
+ if (ret < 0)
+ dev_warn(dev, "Failed to register reset controller (%d)\n", ret);
+
+ return psc;
+}
+
+int davinci_psc_register_clocks(struct device *dev,
+ const struct davinci_lpsc_clk_info *info,
+ u8 num_clks,
+ void __iomem *base)
+{
+ struct davinci_psc_data *psc;
+
+ psc = __davinci_psc_register_clocks(dev, info, num_clks, base);
+ if (IS_ERR(psc))
+ return PTR_ERR(psc);
+
+ for (; info->name; info++) {
+ const struct davinci_lpsc_clkdev_info *cdevs = info->cdevs;
+ struct clk *clk = psc->clk_data.clks[info->md];
+
+ if (!cdevs || IS_ERR_OR_NULL(clk))
+ continue;
+
+ for (; cdevs->con_id || cdevs->dev_id; cdevs++)
+ clk_register_clkdev(clk, cdevs->con_id, cdevs->dev_id);
+ }
+
+ return 0;
+}
+
+int of_davinci_psc_clk_init(struct device *dev,
+ const struct davinci_lpsc_clk_info *info,
+ u8 num_clks,
+ void __iomem *base)
+{
+ struct device_node *node = dev->of_node;
+ struct davinci_psc_data *psc;
+
+ psc = __davinci_psc_register_clocks(dev, info, num_clks, base);
+ if (IS_ERR(psc))
+ return PTR_ERR(psc);
+
+ of_genpd_add_provider_onecell(node, &psc->pm_data);
+
+ of_clk_add_provider(node, of_clk_src_onecell_get, &psc->clk_data);
+
+ return 0;
+}
+
+static const struct of_device_id davinci_psc_of_match[] = {
+ { }
+};
+
+static const struct platform_device_id davinci_psc_id_table[] = {
+ { }
+};
+
+static int davinci_psc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const struct of_device_id *of_id;
+ const struct davinci_psc_init_data *init_data = NULL;
+ struct resource *res;
+ void __iomem *base;
+ int ret;
+
+ of_id = of_match_device(davinci_psc_of_match, dev);
+ if (of_id)
+ init_data = of_id->data;
+ else if (pdev->id_entry)
+ init_data = (void *)pdev->id_entry->driver_data;
+
+ if (!init_data) {
+ dev_err(dev, "unable to find driver init data\n");
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(base)) {
+ dev_err(dev, "ioremap failed\n");
+ return PTR_ERR(base);
+ }
+
+ ret = devm_clk_bulk_get(dev, init_data->num_parent_clks,
+ init_data->parent_clks);
+ if (ret < 0)
+ return ret;
+
+ return init_data->psc_init(dev, base);
+}
+
+static struct platform_driver davinci_psc_driver = {
+ .probe = davinci_psc_probe,
+ .driver = {
+ .name = "davinci-psc-clk",
+ .of_match_table = davinci_psc_of_match,
+ },
+ .id_table = davinci_psc_id_table,
+};
+
+static int __init davinci_psc_driver_init(void)
+{
+ return platform_driver_register(&davinci_psc_driver);
+}
+
+/* has to be postcore_initcall because davinci_gpio depend on PSC clocks */
+postcore_initcall(davinci_psc_driver_init);
diff --git a/drivers/clk/davinci/psc.h b/drivers/clk/davinci/psc.h
new file mode 100644
index 0000000..4240134
--- /dev/null
+++ b/drivers/clk/davinci/psc.h
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for TI Davinci PSC controllers
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#ifndef __CLK_DAVINCI_PSC_H__
+#define __CLK_DAVINCI_PSC_H__
+
+#include <linux/clk-provider.h>
+#include <linux/types.h>
+
+/* PSC quirk flags */
+#define LPSC_ALWAYS_ENABLED BIT(0) /* never disable this clock */
+#define LPSC_SET_RATE_PARENT BIT(1) /* propagate set_rate to parent clock */
+#define LPSC_FORCE BIT(2) /* requires MDCTL FORCE bit */
+#define LPSC_LOCAL_RESET BIT(3) /* acts as reset provider */
+
+struct davinci_lpsc_clkdev_info {
+ const char *con_id;
+ const char *dev_id;
+};
+
+#define LPSC_CLKDEV(c, d) { \
+ .con_id = (c), \
+ .dev_id = (d) \
+}
+
+#define LPSC_CLKDEV1(n, c, d) \
+static const struct davinci_lpsc_clkdev_info n[] __initconst = { \
+ LPSC_CLKDEV((c), (d)), \
+ { } \
+}
+
+#define LPSC_CLKDEV2(n, c1, d1, c2, d2) \
+static const struct davinci_lpsc_clkdev_info n[] __initconst = { \
+ LPSC_CLKDEV((c1), (d1)), \
+ LPSC_CLKDEV((c2), (d2)), \
+ { } \
+}
+
+#define LPSC_CLKDEV3(n, c1, d1, c2, d2, c3, d3) \
+static const struct davinci_lpsc_clkdev_info n[] __initconst = { \
+ LPSC_CLKDEV((c1), (d1)), \
+ LPSC_CLKDEV((c2), (d2)), \
+ LPSC_CLKDEV((c3), (d3)), \
+ { } \
+}
+
+/**
+ * davinci_lpsc_clk_info - LPSC module-specific clock information
+ * @name: the clock name
+ * @parent: the parent clock name
+ * @cdevs: optional array of clkdev lookup table info
+ * @md: the local module domain (LPSC id)
+ * @pd: the power domain id
+ * @flags: bitmask of LPSC_* flags
+ */
+struct davinci_lpsc_clk_info {
+ const char *name;
+ const char *parent;
+ const struct davinci_lpsc_clkdev_info *cdevs;
+ u32 md;
+ u32 pd;
+ unsigned long flags;
+};
+
+#define LPSC(m, d, n, p, c, f) \
+{ \
+ .name = #n, \
+ .parent = #p, \
+ .cdevs = (c), \
+ .md = (m), \
+ .pd = (d), \
+ .flags = (f), \
+}
+
+int davinci_psc_register_clocks(struct device *dev,
+ const struct davinci_lpsc_clk_info *info,
+ u8 num_clks,
+ void __iomem *base);
+
+int of_davinci_psc_clk_init(struct device *dev,
+ const struct davinci_lpsc_clk_info *info,
+ u8 num_clks,
+ void __iomem *base);
+
+/* Device-specific data */
+
+struct davinci_psc_init_data {
+ struct clk_bulk_data *parent_clks;
+ int num_parent_clks;
+ int (*psc_init)(struct device *dev, void __iomem *base);
+};
+
+#endif /* __CLK_DAVINCI_PSC_H__ */
--
2.7.4
On 03/15/2018 09:52 PM, David Lechner wrote:
> This series converts mach-davinci to use the common clock framework.
>
Hi Adam,
I think we are getting pretty close to the final product here. If you
have time to test the EVM(s) you have again, I think this is a good
time to do it.
This adds platform-specific declarations for the PLL clocks on TI
DM646x based systems.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- drop __init and __initconst attributes
- add a clkdev lookup for each SYSCLK
- drop fixed-factor clock for timer2
v7 changes:
- split registration functions for each PLL
- Add platform_device_id lookup
v6 changes:
- Added dm646x_pll{1,2}_info with controller-specific information
- Add empty lines between function calls
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-dm646x.c | 84 ++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/pll.c | 2 +
drivers/clk/davinci/pll.h | 3 ++
4 files changed, 90 insertions(+)
create mode 100644 drivers/clk/davinci/pll-dm646x.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index 59d8ab6..d471386 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -7,4 +7,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o
obj-$(CONFIG_ARCH_DAVINCI_DM355) += pll-dm355.o
obj-$(CONFIG_ARCH_DAVINCI_DM365) += pll-dm365.o
obj-$(CONFIG_ARCH_DAVINCI_DM644x) += pll-dm644x.o
+obj-$(CONFIG_ARCH_DAVINCI_DM646x) += pll-dm646x.o
endif
diff --git a/drivers/clk/davinci/pll-dm646x.c b/drivers/clk/davinci/pll-dm646x.c
new file mode 100644
index 0000000..a61cc32
--- /dev/null
+++ b/drivers/clk/davinci/pll-dm646x.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DM646X
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+static const struct davinci_pll_clk_info dm646x_pll1_info = {
+ .name = "pll1",
+ .pllm_mask = GENMASK(4, 0),
+ .pllm_min = 14,
+ .pllm_max = 32,
+ .flags = PLL_HAS_CLKMODE,
+};
+
+SYSCLK(1, pll1_sysclk1, pll1_pllen, 4, SYSCLK_FIXED_DIV);
+SYSCLK(2, pll1_sysclk2, pll1_pllen, 4, SYSCLK_FIXED_DIV);
+SYSCLK(3, pll1_sysclk3, pll1_pllen, 4, SYSCLK_FIXED_DIV);
+SYSCLK(4, pll1_sysclk4, pll1_pllen, 4, 0);
+SYSCLK(5, pll1_sysclk5, pll1_pllen, 4, 0);
+SYSCLK(6, pll1_sysclk6, pll1_pllen, 4, 0);
+SYSCLK(8, pll1_sysclk8, pll1_pllen, 4, 0);
+SYSCLK(9, pll1_sysclk9, pll1_pllen, 4, 0);
+
+int dm646x_pll1_init(struct device *dev, void __iomem *base)
+{
+ struct clk *clk;
+
+ davinci_pll_clk_register(dev, &dm646x_pll1_info, "ref_clk", base);
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk1, base);
+ clk_register_clkdev(clk, "pll1_sysclk1", "dm646x-psc");
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk2, base);
+ clk_register_clkdev(clk, "pll1_sysclk2", "dm646x-psc");
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk3, base);
+ clk_register_clkdev(clk, "pll1_sysclk3", "dm646x-psc");
+ clk_register_clkdev(clk, NULL, "davinci-wdt");
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk4, base);
+ clk_register_clkdev(clk, "pll1_sysclk4", "dm646x-psc");
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk5, base);
+ clk_register_clkdev(clk, "pll1_sysclk5", "dm646x-psc");
+
+ davinci_pll_sysclk_register(dev, &pll1_sysclk6, base);
+
+ davinci_pll_sysclk_register(dev, &pll1_sysclk8, base);
+
+ davinci_pll_sysclk_register(dev, &pll1_sysclk9, base);
+
+ davinci_pll_sysclkbp_clk_register(dev, "pll1_sysclkbp", base);
+
+ davinci_pll_auxclk_register(dev, "pll1_auxclk", base);
+
+ return 0;
+}
+
+static const struct davinci_pll_clk_info dm646x_pll2_info = {
+ .name = "pll2",
+ .pllm_mask = GENMASK(4, 0),
+ .pllm_min = 14,
+ .pllm_max = 32,
+ .flags = 0,
+};
+
+SYSCLK(1, pll2_sysclk1, pll2_pllen, 4, 0);
+
+int dm646x_pll2_init(struct device *dev, void __iomem *base)
+{
+ davinci_pll_clk_register(dev, &dm646x_pll2_info, "oscin", base);
+
+ davinci_pll_sysclk_register(dev, &pll2_sysclk1, base);
+
+ return 0;
+}
diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c
index 0a1e68f..588a489 100644
--- a/drivers/clk/davinci/pll.c
+++ b/drivers/clk/davinci/pll.c
@@ -786,6 +786,8 @@ static const struct platform_device_id davinci_pll_id_table[] = {
{ .name = "dm365-pll2", .driver_data = (kernel_ulong_t)dm365_pll2_init },
{ .name = "dm644x-pll1", .driver_data = (kernel_ulong_t)dm644x_pll1_init },
{ .name = "dm644x-pll2", .driver_data = (kernel_ulong_t)dm644x_pll2_init },
+ { .name = "dm646x-pll1", .driver_data = (kernel_ulong_t)dm646x_pll1_init },
+ { .name = "dm646x-pll2", .driver_data = (kernel_ulong_t)dm646x_pll2_init },
{ }
};
diff --git a/drivers/clk/davinci/pll.h b/drivers/clk/davinci/pll.h
index d8af4f5..b1b6fb2 100644
--- a/drivers/clk/davinci/pll.h
+++ b/drivers/clk/davinci/pll.h
@@ -135,4 +135,7 @@ int dm365_pll2_init(struct device *dev, void __iomem *base);
int dm644x_pll1_init(struct device *dev, void __iomem *base);
int dm644x_pll2_init(struct device *dev, void __iomem *base);
+int dm646x_pll1_init(struct device *dev, void __iomem *base);
+int dm646x_pll2_init(struct device *dev, void __iomem *base);
+
#endif /* __CLK_DAVINCI_PLL_H___ */
--
2.7.4
This adds platform-specific declarations for the PLL clocks on TI
DM355 based systems.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- drop __init and __initconst attributes
- add a clkdev lookup for each SYSCLK
v7 changes:
- split registration functions for each PLL
- Add platform_device_id lookup
v6 changes:
- Added dm355_pll{1,2}_info with controller-specific information
- Add empty lines between function calls
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-dm355.c | 79 +++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/pll.c | 2 ++
drivers/clk/davinci/pll.h | 3 ++
4 files changed, 85 insertions(+)
create mode 100644 drivers/clk/davinci/pll-dm355.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index 13049d4..6720bd0 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -4,4 +4,5 @@ ifeq ($(CONFIG_COMMON_CLK), y)
obj-y += pll.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += pll-da830.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o
+obj-$(CONFIG_ARCH_DAVINCI_DM355) += pll-dm355.o
endif
diff --git a/drivers/clk/davinci/pll-dm355.c b/drivers/clk/davinci/pll-dm355.c
new file mode 100644
index 0000000..5345f82
--- /dev/null
+++ b/drivers/clk/davinci/pll-dm355.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DM355
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/bitops.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+static const struct davinci_pll_clk_info dm355_pll1_info = {
+ .name = "pll1",
+ .pllm_mask = GENMASK(7, 0),
+ .pllm_min = 92,
+ .pllm_max = 184,
+ .flags = PLL_HAS_CLKMODE | PLL_HAS_PREDIV | PLL_PREDIV_ALWAYS_ENABLED |
+ PLL_PREDIV_FIXED8 | PLL_HAS_POSTDIV |
+ PLL_POSTDIV_ALWAYS_ENABLED | PLL_POSTDIV_FIXED_DIV,
+};
+
+SYSCLK(1, pll1_sysclk1, pll1, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED);
+SYSCLK(2, pll1_sysclk2, pll1, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED);
+SYSCLK(3, pll1_sysclk3, pll1, 5, SYSCLK_ALWAYS_ENABLED);
+SYSCLK(4, pll1_sysclk4, pll1, 5, SYSCLK_ALWAYS_ENABLED);
+
+int dm355_pll1_init(struct device *dev, void __iomem *base)
+{
+ struct clk *clk;
+
+ davinci_pll_clk_register(dev, &dm355_pll1_info, "ref_clk", base);
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk1, base);
+ clk_register_clkdev(clk, "pll1_sysclk1", "dm355-psc");
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk2, base);
+ clk_register_clkdev(clk, "pll1_sysclk2", "dm355-psc");
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk3, base);
+ clk_register_clkdev(clk, "pll1_sysclk3", "dm355-psc");
+
+ clk = davinci_pll_sysclk_register(dev, &pll1_sysclk4, base);
+ clk_register_clkdev(clk, "pll1_sysclk4", "dm355-psc");
+
+ clk = davinci_pll_auxclk_register(dev, "pll1_auxclk", base);
+ clk_register_clkdev(clk, "pll1_auxclk", "dm355-psc");
+
+ davinci_pll_sysclkbp_clk_register(dev, "pll1_sysclkbp", base);
+
+ return 0;
+}
+
+static const struct davinci_pll_clk_info dm355_pll2_info = {
+ .name = "pll2",
+ .pllm_mask = GENMASK(7, 0),
+ .pllm_min = 92,
+ .pllm_max = 184,
+ .flags = PLL_HAS_PREDIV | PLL_PREDIV_ALWAYS_ENABLED | PLL_HAS_POSTDIV |
+ PLL_POSTDIV_ALWAYS_ENABLED | PLL_POSTDIV_FIXED_DIV,
+};
+
+SYSCLK(1, pll2_sysclk1, pll2, 5, SYSCLK_FIXED_DIV);
+SYSCLK(2, pll2_sysclk2, pll2, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED);
+
+int dm355_pll2_init(struct device *dev, void __iomem *base)
+{
+ davinci_pll_clk_register(dev, &dm355_pll2_info, "oscin", base);
+
+ davinci_pll_sysclk_register(dev, &pll2_sysclk1, base);
+
+ davinci_pll_sysclk_register(dev, &pll2_sysclk2, base);
+
+ davinci_pll_sysclkbp_clk_register(dev, "pll2_sysclkbp", base);
+
+ return 0;
+}
diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c
index 535f725..305d2e9 100644
--- a/drivers/clk/davinci/pll.c
+++ b/drivers/clk/davinci/pll.c
@@ -780,6 +780,8 @@ static const struct platform_device_id davinci_pll_id_table[] = {
{ .name = "da830-pll", .driver_data = (kernel_ulong_t)da830_pll_init },
{ .name = "da850-pll0", .driver_data = (kernel_ulong_t)da850_pll0_init },
{ .name = "da850-pll1", .driver_data = (kernel_ulong_t)da850_pll1_init },
+ { .name = "dm355-pll1", .driver_data = (kernel_ulong_t)dm355_pll1_init },
+ { .name = "dm355-pll2", .driver_data = (kernel_ulong_t)dm355_pll2_init },
{ }
};
diff --git a/drivers/clk/davinci/pll.h b/drivers/clk/davinci/pll.h
index 53b8d51..d90d308 100644
--- a/drivers/clk/davinci/pll.h
+++ b/drivers/clk/davinci/pll.h
@@ -126,4 +126,7 @@ int da850_pll1_init(struct device *dev, void __iomem *base);
int of_da850_pll0_init(struct device *dev, void __iomem *base);
int of_da850_pll1_init(struct device *dev, void __iomem *base);
+int dm355_pll1_init(struct device *dev, void __iomem *base);
+int dm355_pll2_init(struct device *dev, void __iomem *base);
+
#endif /* __CLK_DAVINCI_PLL_H___ */
--
2.7.4
On 03/15/2018 09:52 PM, David Lechner wrote:
> This adds platform-specific declarations for the PSC clocks on TI DA850/
> OMAP-L138/AM18XX SoCs.
>
> Signed-off-by: David Lechner <[email protected]>
> Reviewed-by: Sekhar Nori <[email protected]>
> ---
>
This Reviewed-by: was supposed to be dropped. This file has had some significant
changes.
This removes the unused legacy clock init code from
arch/arm/mach-davinci/dm365.c.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
---
v8 changes:
- none
v7 changes:
- rebased
- add davinci prefix to commit message
v6 changes:
- rebased
arch/arm/mach-davinci/dm365.c | 449 ------------------------------------------
1 file changed, 449 deletions(-)
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 93067e1..aa458a9 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -37,11 +37,6 @@
#include "davinci.h"
#include "mux.h"
-#ifndef CONFIG_COMMON_CLK
-#include "clock.h"
-#include "psc.h"
-#endif
-
#define DM365_REF_FREQ 24000000 /* 24 MHz on the DM365 EVM */
#define DM365_RTC_BASE 0x01c69000
#define DM365_KEYSCAN_BASE 0x01c69400
@@ -57,441 +52,6 @@
#define DM365_EMAC_CNTRL_RAM_OFFSET 0x1000
#define DM365_EMAC_CNTRL_RAM_SIZE 0x2000
-#ifndef CONFIG_COMMON_CLK
-static struct pll_data pll1_data = {
- .num = 1,
- .phys_base = DAVINCI_PLL1_BASE,
- .flags = PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
-};
-
-static struct pll_data pll2_data = {
- .num = 2,
- .phys_base = DAVINCI_PLL2_BASE,
- .flags = PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
-};
-
-static struct clk ref_clk = {
- .name = "ref_clk",
- .rate = DM365_REF_FREQ,
-};
-
-static struct clk pll1_clk = {
- .name = "pll1",
- .parent = &ref_clk,
- .flags = CLK_PLL,
- .pll_data = &pll1_data,
-};
-
-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 clkout0_clk = {
- .name = "clkout0",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_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_sysclk4 = {
- .name = "pll1_sysclk4",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV4,
-};
-
-static struct clk pll1_sysclk5 = {
- .name = "pll1_sysclk5",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV5,
-};
-
-static struct clk pll1_sysclk6 = {
- .name = "pll1_sysclk6",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV6,
-};
-
-static struct clk pll1_sysclk7 = {
- .name = "pll1_sysclk7",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV7,
-};
-
-static struct clk pll1_sysclk8 = {
- .name = "pll1_sysclk8",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV8,
-};
-
-static struct clk pll1_sysclk9 = {
- .name = "pll1_sysclk9",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV9,
-};
-
-static struct clk pll2_clk = {
- .name = "pll2",
- .parent = &ref_clk,
- .flags = CLK_PLL,
- .pll_data = &pll2_data,
-};
-
-static struct clk pll2_aux_clk = {
- .name = "pll2_aux_clk",
- .parent = &pll2_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk clkout1_clk = {
- .name = "clkout1",
- .parent = &pll2_clk,
- .flags = CLK_PLL | PRE_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_sysclk3 = {
- .name = "pll2_sysclk3",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV3,
-};
-
-static struct clk pll2_sysclk4 = {
- .name = "pll2_sysclk4",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV4,
-};
-
-static struct clk pll2_sysclk5 = {
- .name = "pll2_sysclk5",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV5,
-};
-
-static struct clk pll2_sysclk6 = {
- .name = "pll2_sysclk6",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV6,
-};
-
-static struct clk pll2_sysclk7 = {
- .name = "pll2_sysclk7",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV7,
-};
-
-static struct clk pll2_sysclk8 = {
- .name = "pll2_sysclk8",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV8,
-};
-
-static struct clk pll2_sysclk9 = {
- .name = "pll2_sysclk9",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV9,
-};
-
-static struct clk vpss_dac_clk = {
- .name = "vpss_dac",
- .parent = &pll1_sysclk3,
- .lpsc = DM365_LPSC_DAC_CLK,
-};
-
-static struct clk vpss_master_clk = {
- .name = "vpss_master",
- .parent = &pll1_sysclk5,
- .lpsc = DM365_LPSC_VPSSMSTR,
- .flags = CLK_PSC,
-};
-
-static struct clk vpss_slave_clk = {
- .name = "vpss_slave",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_VPSSSLV,
-};
-
-static struct clk arm_clk = {
- .name = "arm_clk",
- .parent = &pll2_sysclk2,
- .lpsc = DAVINCI_LPSC_ARM,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk uart0_clk = {
- .name = "uart0",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_UART0,
-};
-
-static struct clk uart1_clk = {
- .name = "uart1",
- .parent = &pll1_sysclk4,
- .lpsc = DAVINCI_LPSC_UART1,
-};
-
-static struct clk i2c_clk = {
- .name = "i2c",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_I2C,
-};
-
-static struct clk mmcsd0_clk = {
- .name = "mmcsd0",
- .parent = &pll1_sysclk8,
- .lpsc = DAVINCI_LPSC_MMC_SD,
-};
-
-static struct clk mmcsd1_clk = {
- .name = "mmcsd1",
- .parent = &pll1_sysclk4,
- .lpsc = DM365_LPSC_MMC_SD1,
-};
-
-static struct clk spi0_clk = {
- .name = "spi0",
- .parent = &pll1_sysclk4,
- .lpsc = DAVINCI_LPSC_SPI,
-};
-
-static struct clk spi1_clk = {
- .name = "spi1",
- .parent = &pll1_sysclk4,
- .lpsc = DM365_LPSC_SPI1,
-};
-
-static struct clk spi2_clk = {
- .name = "spi2",
- .parent = &pll1_sysclk4,
- .lpsc = DM365_LPSC_SPI2,
-};
-
-static struct clk spi3_clk = {
- .name = "spi3",
- .parent = &pll1_sysclk4,
- .lpsc = DM365_LPSC_SPI3,
-};
-
-static struct clk spi4_clk = {
- .name = "spi4",
- .parent = &pll1_aux_clk,
- .lpsc = DM365_LPSC_SPI4,
-};
-
-static struct clk gpio_clk = {
- .name = "gpio",
- .parent = &pll1_sysclk4,
- .lpsc = DAVINCI_LPSC_GPIO,
-};
-
-static struct clk aemif_clk = {
- .name = "aemif",
- .parent = &pll1_sysclk4,
- .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 pwm3_clk = {
- .name = "pwm3",
- .parent = &ref_clk,
- .lpsc = DM365_LPSC_PWM3,
-};
-
-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,
-};
-
-static struct clk timer3_clk = {
- .name = "timer3",
- .parent = &pll1_aux_clk,
- .lpsc = DM365_LPSC_TIMER3,
-};
-
-static struct clk usb_clk = {
- .name = "usb",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_USB,
-};
-
-static struct clk emac_clk = {
- .name = "emac",
- .parent = &pll1_sysclk4,
- .lpsc = DM365_LPSC_EMAC,
-};
-
-static struct clk voicecodec_clk = {
- .name = "voice_codec",
- .parent = &pll2_sysclk4,
- .lpsc = DM365_LPSC_VOICE_CODEC,
-};
-
-static struct clk asp0_clk = {
- .name = "asp0",
- .parent = &pll1_sysclk4,
- .lpsc = DM365_LPSC_McBSP1,
-};
-
-static struct clk rto_clk = {
- .name = "rto",
- .parent = &pll1_sysclk4,
- .lpsc = DM365_LPSC_RTO,
-};
-
-static struct clk mjcp_clk = {
- .name = "mjcp",
- .parent = &pll1_sysclk3,
- .lpsc = DM365_LPSC_MJCP,
-};
-
-static struct clk_lookup dm365_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "pll1", &pll1_clk),
- CLK(NULL, "pll1_aux", &pll1_aux_clk),
- CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
- CLK(NULL, "clkout0", &clkout0_clk),
- CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
- CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
- CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
- CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
- CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
- CLK(NULL, "pll1_sysclk6", &pll1_sysclk6),
- CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
- CLK(NULL, "pll1_sysclk8", &pll1_sysclk8),
- CLK(NULL, "pll1_sysclk9", &pll1_sysclk9),
- CLK(NULL, "pll2", &pll2_clk),
- CLK(NULL, "pll2_aux", &pll2_aux_clk),
- CLK(NULL, "clkout1", &clkout1_clk),
- CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
- CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
- CLK(NULL, "pll2_sysclk3", &pll2_sysclk3),
- CLK(NULL, "pll2_sysclk4", &pll2_sysclk4),
- CLK(NULL, "pll2_sysclk5", &pll2_sysclk5),
- CLK(NULL, "pll2_sysclk6", &pll2_sysclk6),
- CLK(NULL, "pll2_sysclk7", &pll2_sysclk7),
- CLK(NULL, "pll2_sysclk8", &pll2_sysclk8),
- CLK(NULL, "pll2_sysclk9", &pll2_sysclk9),
- CLK(NULL, "vpss_dac", &vpss_dac_clk),
- CLK("vpss", "master", &vpss_master_clk),
- CLK("vpss", "slave", &vpss_slave_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("i2c_davinci.1", NULL, &i2c_clk),
- CLK("da830-mmc.0", NULL, &mmcsd0_clk),
- CLK("da830-mmc.1", NULL, &mmcsd1_clk),
- CLK("spi_davinci.0", NULL, &spi0_clk),
- CLK("spi_davinci.1", NULL, &spi1_clk),
- CLK("spi_davinci.2", NULL, &spi2_clk),
- CLK("spi_davinci.3", NULL, &spi3_clk),
- CLK("spi_davinci.4", NULL, &spi4_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK(NULL, "aemif", &aemif_clk),
- CLK(NULL, "pwm0", &pwm0_clk),
- CLK(NULL, "pwm1", &pwm1_clk),
- CLK(NULL, "pwm2", &pwm2_clk),
- CLK(NULL, "pwm3", &pwm3_clk),
- CLK(NULL, "timer0", &timer0_clk),
- CLK(NULL, "timer1", &timer1_clk),
- CLK("davinci-wdt", NULL, &timer2_clk),
- CLK(NULL, "timer3", &timer3_clk),
- CLK(NULL, "usb", &usb_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &emac_clk),
- CLK("davinci_voicecodec", NULL, &voicecodec_clk),
- CLK("davinci-mcbsp", NULL, &asp0_clk),
- CLK(NULL, "rto", &rto_clk),
- CLK(NULL, "mjcp", &mjcp_clk),
- CLK(NULL, NULL, NULL),
-};
-#endif
-/*----------------------------------------------------------------------*/
-
#define INTMUX 0x18
#define EVTMUX 0x1c
@@ -1058,8 +618,6 @@ static struct davinci_id dm365_ids[] = {
},
};
-static u32 dm365_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
static struct davinci_timer_info dm365_timer_info = {
.timers = davinci_timer_instance,
.clockevent_id = T0_BOT,
@@ -1120,8 +678,6 @@ static const struct davinci_soc_info davinci_soc_info_dm365 = {
.jtag_id_reg = 0x01c40028,
.ids = dm365_ids,
.ids_num = ARRAY_SIZE(dm365_ids),
- .psc_bases = dm365_psc_bases,
- .psc_bases_num = ARRAY_SIZE(dm365_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
.pinmux_pins = dm365_pins,
.pinmux_pins_num = ARRAY_SIZE(dm365_pins),
@@ -1175,16 +731,11 @@ void __init dm365_init(void)
void __init dm365_init_time(void)
{
-#ifdef CONFIG_COMMON_CLK
struct clk *clk;
clk = clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM365_REF_FREQ);
davinci_timer_init(clk);
-#else
- davinci_clk_init(dm365_clks);
- davinci_timer_init(&timer0_clk);
-#endif
}
static struct resource dm365_pll1_resources[] = {
--
2.7.4
This removes the unused legacy clock init code from
arch/arm/mach-davinci/da830.c.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
---
v8 changes:
- none
v7 changes:
- rebased
- add davinci prefix to commit message
v6 changes:
- rebased
arch/arm/mach-davinci/board-da830-evm.c | 12 -
arch/arm/mach-davinci/da830.c | 412 --------------------------------
2 files changed, 424 deletions(-)
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index 6e77c45..d283fae 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -110,23 +110,11 @@ static __init void da830_evm_usb_init(void)
{
int ret;
-#ifdef CONFIG_COMMON_CLK
ret = da8xx_register_usb_phy_clocks();
if (ret)
pr_warn("%s: USB PHY CLK registration failed: %d\n",
__func__, ret);
-#else
- /* USB_REFCLKIN is not used. */
- ret = da8xx_register_usb20_phy_clk(false);
- if (ret)
- pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n",
- __func__, ret);
- ret = da8xx_register_usb11_phy_clk(false);
- if (ret)
- pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n",
- __func__, ret);
-#endif
ret = da8xx_register_usb_phy();
if (ret)
pr_warn("%s: USB PHY registration failed: %d\n",
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index c1c2604..470ae48 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -23,11 +23,6 @@
#include "mux.h"
-#ifndef CONFIG_COMMON_CLK
-#include "clock.h"
-#include "psc.h"
-#endif
-
/* Offsets of the 8 compare registers on the da830 */
#define DA830_CMP12_0 0x60
#define DA830_CMP12_1 0x64
@@ -40,404 +35,6 @@
#define DA830_REF_FREQ 24000000
-#ifndef CONFIG_COMMON_CLK
-static struct pll_data pll0_data = {
- .num = 1,
- .phys_base = DA8XX_PLL0_BASE,
- .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
-};
-
-static struct clk ref_clk = {
- .name = "ref_clk",
- .rate = DA830_REF_FREQ,
-};
-
-static struct clk pll0_clk = {
- .name = "pll0",
- .parent = &ref_clk,
- .pll_data = &pll0_data,
- .flags = CLK_PLL,
-};
-
-static struct clk pll0_aux_clk = {
- .name = "pll0_aux_clk",
- .parent = &pll0_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll0_sysclk2 = {
- .name = "pll0_sysclk2",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV2,
-};
-
-static struct clk pll0_sysclk3 = {
- .name = "pll0_sysclk3",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV3,
-};
-
-static struct clk pll0_sysclk4 = {
- .name = "pll0_sysclk4",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV4,
-};
-
-static struct clk pll0_sysclk5 = {
- .name = "pll0_sysclk5",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV5,
-};
-
-static struct clk pll0_sysclk6 = {
- .name = "pll0_sysclk6",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV6,
-};
-
-static struct clk pll0_sysclk7 = {
- .name = "pll0_sysclk7",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV7,
-};
-
-static struct clk i2c0_clk = {
- .name = "i2c0",
- .parent = &pll0_aux_clk,
-};
-
-static struct clk timerp64_0_clk = {
- .name = "timer0",
- .parent = &pll0_aux_clk,
-};
-
-static struct clk timerp64_1_clk = {
- .name = "timer1",
- .parent = &pll0_aux_clk,
-};
-
-static struct clk arm_rom_clk = {
- .name = "arm_rom",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_ARM_RAM_ROM,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk scr0_ss_clk = {
- .name = "scr0_ss",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_SCR0_SS,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk scr1_ss_clk = {
- .name = "scr1_ss",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_SCR1_SS,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk scr2_ss_clk = {
- .name = "scr2_ss",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_SCR2_SS,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk dmax_clk = {
- .name = "dmax",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_PRUSS,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk tpcc_clk = {
- .name = "tpcc",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_TPCC,
- .flags = ALWAYS_ENABLED | CLK_PSC,
-};
-
-static struct clk tptc0_clk = {
- .name = "tptc0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_TPTC0,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk tptc1_clk = {
- .name = "tptc1",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_TPTC1,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk mmcsd_clk = {
- .name = "mmcsd",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_MMC_SD,
-};
-
-static struct clk uart0_clk = {
- .name = "uart0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_UART0,
-};
-
-static struct clk uart1_clk = {
- .name = "uart1",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_UART1,
- .gpsc = 1,
-};
-
-static struct clk uart2_clk = {
- .name = "uart2",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_UART2,
- .gpsc = 1,
-};
-
-static struct clk spi0_clk = {
- .name = "spi0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_SPI0,
-};
-
-static struct clk spi1_clk = {
- .name = "spi1",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_SPI1,
- .gpsc = 1,
-};
-
-static struct clk ecap0_clk = {
- .name = "ecap0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_ECAP,
- .gpsc = 1,
-};
-
-static struct clk ecap1_clk = {
- .name = "ecap1",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_ECAP,
- .gpsc = 1,
-};
-
-static struct clk ecap2_clk = {
- .name = "ecap2",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_ECAP,
- .gpsc = 1,
-};
-
-static struct clk pwm0_clk = {
- .name = "pwm0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_PWM,
- .gpsc = 1,
-};
-
-static struct clk pwm1_clk = {
- .name = "pwm1",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_PWM,
- .gpsc = 1,
-};
-
-static struct clk pwm2_clk = {
- .name = "pwm2",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_PWM,
- .gpsc = 1,
-};
-
-static struct clk eqep0_clk = {
- .name = "eqep0",
- .parent = &pll0_sysclk2,
- .lpsc = DA830_LPSC1_EQEP,
- .gpsc = 1,
-};
-
-static struct clk eqep1_clk = {
- .name = "eqep1",
- .parent = &pll0_sysclk2,
- .lpsc = DA830_LPSC1_EQEP,
- .gpsc = 1,
-};
-
-static struct clk lcdc_clk = {
- .name = "lcdc",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_LCDC,
- .gpsc = 1,
-};
-
-static struct clk mcasp0_clk = {
- .name = "mcasp0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_McASP0,
- .gpsc = 1,
-};
-
-static struct clk mcasp1_clk = {
- .name = "mcasp1",
- .parent = &pll0_sysclk2,
- .lpsc = DA830_LPSC1_McASP1,
- .gpsc = 1,
-};
-
-static struct clk mcasp2_clk = {
- .name = "mcasp2",
- .parent = &pll0_sysclk2,
- .lpsc = DA830_LPSC1_McASP2,
- .gpsc = 1,
-};
-
-static struct clk usb20_clk = {
- .name = "usb20",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_USB20,
- .gpsc = 1,
-};
-
-static struct clk cppi41_clk = {
- .name = "cppi41",
- .parent = &usb20_clk,
-};
-
-static struct clk aemif_clk = {
- .name = "aemif",
- .parent = &pll0_sysclk3,
- .lpsc = DA8XX_LPSC0_EMIF25,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk aintc_clk = {
- .name = "aintc",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC0_AINTC,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk secu_mgr_clk = {
- .name = "secu_mgr",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC0_SECU_MGR,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk emac_clk = {
- .name = "emac",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC1_CPGMAC,
- .gpsc = 1,
-};
-
-static struct clk gpio_clk = {
- .name = "gpio",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC1_GPIO,
- .gpsc = 1,
-};
-
-static struct clk i2c1_clk = {
- .name = "i2c1",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC1_I2C,
- .gpsc = 1,
-};
-
-static struct clk usb11_clk = {
- .name = "usb11",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC1_USB11,
- .gpsc = 1,
-};
-
-static struct clk emif3_clk = {
- .name = "emif3",
- .parent = &pll0_sysclk5,
- .lpsc = DA8XX_LPSC1_EMIF3C,
- .gpsc = 1,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk arm_clk = {
- .name = "arm",
- .parent = &pll0_sysclk6,
- .lpsc = DA8XX_LPSC0_ARM,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk rmii_clk = {
- .name = "rmii",
- .parent = &pll0_sysclk7,
-};
-
-static struct clk_lookup da830_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "pll0", &pll0_clk),
- CLK(NULL, "pll0_aux", &pll0_aux_clk),
- CLK(NULL, "pll0_sysclk2", &pll0_sysclk2),
- CLK(NULL, "pll0_sysclk3", &pll0_sysclk3),
- CLK(NULL, "pll0_sysclk4", &pll0_sysclk4),
- CLK(NULL, "pll0_sysclk5", &pll0_sysclk5),
- CLK(NULL, "pll0_sysclk6", &pll0_sysclk6),
- CLK(NULL, "pll0_sysclk7", &pll0_sysclk7),
- CLK("i2c_davinci.1", NULL, &i2c0_clk),
- CLK(NULL, "timer0", &timerp64_0_clk),
- CLK("davinci-wdt", NULL, &timerp64_1_clk),
- CLK(NULL, "arm_rom", &arm_rom_clk),
- CLK(NULL, "scr0_ss", &scr0_ss_clk),
- CLK(NULL, "scr1_ss", &scr1_ss_clk),
- CLK(NULL, "scr2_ss", &scr2_ss_clk),
- CLK(NULL, "dmax", &dmax_clk),
- CLK(NULL, "tpcc", &tpcc_clk),
- CLK(NULL, "tptc0", &tptc0_clk),
- CLK(NULL, "tptc1", &tptc1_clk),
- CLK("da830-mmc.0", NULL, &mmcsd_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("serial8250.2", NULL, &uart2_clk),
- CLK("spi_davinci.0", NULL, &spi0_clk),
- CLK("spi_davinci.1", NULL, &spi1_clk),
- CLK(NULL, "ecap0", &ecap0_clk),
- CLK(NULL, "ecap1", &ecap1_clk),
- CLK(NULL, "ecap2", &ecap2_clk),
- CLK(NULL, "pwm0", &pwm0_clk),
- CLK(NULL, "pwm1", &pwm1_clk),
- CLK(NULL, "pwm2", &pwm2_clk),
- CLK("eqep.0", NULL, &eqep0_clk),
- CLK("eqep.1", NULL, &eqep1_clk),
- CLK("da8xx_lcdc.0", "fck", &lcdc_clk),
- CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
- CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
- CLK("davinci-mcasp.2", NULL, &mcasp2_clk),
- CLK("musb-da8xx", NULL, &usb20_clk),
- CLK("cppi41-dmaengine", NULL, &cppi41_clk),
- CLK(NULL, "aemif", &aemif_clk),
- CLK(NULL, "aintc", &aintc_clk),
- CLK(NULL, "secu_mgr", &secu_mgr_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &emac_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK("i2c_davinci.2", NULL, &i2c1_clk),
- CLK("ohci-da8xx", NULL, &usb11_clk),
- CLK(NULL, "emif3", &emif3_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "rmii", &rmii_clk),
- CLK(NULL, NULL, NULL),
-};
-#endif
-
/*
* Device specific mux setup
*
@@ -1135,8 +732,6 @@ static struct map_desc da830_io_desc[] = {
},
};
-static u32 da830_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
-
/* Contents of JTAG ID register used to identify exact cpu type */
static struct davinci_id da830_ids[] = {
{
@@ -1205,8 +800,6 @@ static const struct davinci_soc_info davinci_soc_info_da830 = {
.jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
.ids = da830_ids,
.ids_num = ARRAY_SIZE(da830_ids),
- .psc_bases = da830_psc_bases,
- .psc_bases_num = ARRAY_SIZE(da830_psc_bases),
.pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
.pinmux_pins = da830_pins,
.pinmux_pins_num = ARRAY_SIZE(da830_pins),
@@ -1228,16 +821,11 @@ void __init da830_init(void)
void __init da830_init_time(void)
{
-#ifdef CONFIG_COMMON_CLK
struct clk *clk;
clk = clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DA830_REF_FREQ);
davinci_timer_init(clk);
-#else
- davinci_clk_init(da830_clks);
- davinci_timer_init(&timerp64_0_clk);
-#endif
}
static struct resource da830_pll_resources[] = {
--
2.7.4
This removes the unused legacy clock init code from
arch/arm/mach-davinci/da850.c.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
---
v8 changes:
- rebased
v7 changes:
- rebased
- add davinci prefix to commit message
v6 changes:
- rebased
arch/arm/mach-davinci/board-omapl138-hawk.c | 12 +-
arch/arm/mach-davinci/da850.c | 653 +---------------------------
arch/arm/mach-davinci/da8xx-dt.c | 12 +-
3 files changed, 3 insertions(+), 674 deletions(-)
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index 6a866d2..6c997c5 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -231,22 +231,12 @@ static __init void omapl138_hawk_usb_init(void)
pr_warn("%s: USB 1.1 PinMux setup failed: %d\n", __func__, ret);
return;
}
-#ifdef CONFIG_COMMON_CLK
+
ret = da8xx_register_usb_phy_clocks();
if (ret)
pr_warn("%s: USB PHY CLK registration failed: %d\n",
__func__, ret);
-#else
- ret = da8xx_register_usb20_phy_clk(false);
- if (ret)
- pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n",
- __func__, ret);
- ret = da8xx_register_usb11_phy_clk(false);
- if (ret)
- pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n",
- __func__, ret);
-#endif
ret = da8xx_register_usb_phy();
if (ret)
pr_warn("%s: USB PHY registration failed: %d\n",
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index ae7c429..3f27d46 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -37,559 +37,12 @@
#include "mux.h"
-#ifndef CONFIG_COMMON_CLK
-#include "clock.h"
-#include "psc.h"
-#endif
-
#define DA850_PLL1_BASE 0x01e1a000
#define DA850_TIMER64P2_BASE 0x01f0c000
#define DA850_TIMER64P3_BASE 0x01f0d000
#define DA850_REF_FREQ 24000000
-#ifndef CONFIG_COMMON_CLK
-static int da850_set_armrate(struct clk *clk, unsigned long rate);
-static int da850_round_armrate(struct clk *clk, unsigned long rate);
-static int da850_set_pll0rate(struct clk *clk, unsigned long armrate);
-
-static struct pll_data pll0_data = {
- .num = 1,
- .phys_base = DA8XX_PLL0_BASE,
- .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
-};
-
-static struct clk ref_clk = {
- .name = "ref_clk",
- .rate = DA850_REF_FREQ,
- .set_rate = davinci_simple_set_rate,
-};
-
-static struct clk pll0_clk = {
- .name = "pll0",
- .parent = &ref_clk,
- .pll_data = &pll0_data,
- .flags = CLK_PLL,
- .set_rate = da850_set_pll0rate,
-};
-
-static struct clk pll0_aux_clk = {
- .name = "pll0_aux_clk",
- .parent = &pll0_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll0_sysclk1 = {
- .name = "pll0_sysclk1",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV1,
-};
-
-static struct clk pll0_sysclk2 = {
- .name = "pll0_sysclk2",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV2,
-};
-
-static struct clk pll0_sysclk3 = {
- .name = "pll0_sysclk3",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV3,
- .set_rate = davinci_set_sysclk_rate,
- .maxrate = 100000000,
-};
-
-static struct clk pll0_sysclk4 = {
- .name = "pll0_sysclk4",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV4,
-};
-
-static struct clk pll0_sysclk5 = {
- .name = "pll0_sysclk5",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV5,
-};
-
-static struct clk pll0_sysclk6 = {
- .name = "pll0_sysclk6",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV6,
-};
-
-static struct clk pll0_sysclk7 = {
- .name = "pll0_sysclk7",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV7,
-};
-
-static struct pll_data pll1_data = {
- .num = 2,
- .phys_base = DA850_PLL1_BASE,
- .flags = PLL_HAS_POSTDIV,
-};
-
-static struct clk pll1_clk = {
- .name = "pll1",
- .parent = &ref_clk,
- .pll_data = &pll1_data,
- .flags = CLK_PLL,
-};
-
-static struct clk pll1_aux_clk = {
- .name = "pll1_aux_clk",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-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 int da850_async3_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 val;
-
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
-
- if (parent == &pll0_sysclk2) {
- val &= ~CFGCHIP3_ASYNC3_CLKSRC;
- } else if (parent == &pll1_sysclk2) {
- val |= CFGCHIP3_ASYNC3_CLKSRC;
- } else {
- pr_err("Bad parent on async3 clock mux\n");
- return -EINVAL;
- }
-
- writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
-
- return 0;
-}
-
-static struct clk async3_clk = {
- .name = "async3",
- .parent = &pll1_sysclk2,
- .set_parent = da850_async3_set_parent,
-};
-
-static struct clk i2c0_clk = {
- .name = "i2c0",
- .parent = &pll0_aux_clk,
-};
-
-static struct clk timerp64_0_clk = {
- .name = "timer0",
- .parent = &pll0_aux_clk,
-};
-
-static struct clk timerp64_1_clk = {
- .name = "timer1",
- .parent = &pll0_aux_clk,
-};
-
-static struct clk arm_rom_clk = {
- .name = "arm_rom",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_ARM_RAM_ROM,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk tpcc0_clk = {
- .name = "tpcc0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_TPCC,
- .flags = ALWAYS_ENABLED | CLK_PSC,
-};
-
-static struct clk tptc0_clk = {
- .name = "tptc0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_TPTC0,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk tptc1_clk = {
- .name = "tptc1",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_TPTC1,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk tpcc1_clk = {
- .name = "tpcc1",
- .parent = &pll0_sysclk2,
- .lpsc = DA850_LPSC1_TPCC1,
- .gpsc = 1,
- .flags = CLK_PSC | ALWAYS_ENABLED,
-};
-
-static struct clk tptc2_clk = {
- .name = "tptc2",
- .parent = &pll0_sysclk2,
- .lpsc = DA850_LPSC1_TPTC2,
- .gpsc = 1,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk pruss_clk = {
- .name = "pruss",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_PRUSS,
-};
-
-static struct clk uart0_clk = {
- .name = "uart0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_UART0,
-};
-
-static struct clk uart1_clk = {
- .name = "uart1",
- .parent = &async3_clk,
- .lpsc = DA8XX_LPSC1_UART1,
- .gpsc = 1,
-};
-
-static struct clk uart2_clk = {
- .name = "uart2",
- .parent = &async3_clk,
- .lpsc = DA8XX_LPSC1_UART2,
- .gpsc = 1,
-};
-
-static struct clk aintc_clk = {
- .name = "aintc",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC0_AINTC,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk gpio_clk = {
- .name = "gpio",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC1_GPIO,
- .gpsc = 1,
-};
-
-static struct clk i2c1_clk = {
- .name = "i2c1",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC1_I2C,
- .gpsc = 1,
-};
-
-static struct clk emif3_clk = {
- .name = "emif3",
- .parent = &pll0_sysclk5,
- .lpsc = DA8XX_LPSC1_EMIF3C,
- .gpsc = 1,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk arm_clk = {
- .name = "arm",
- .parent = &pll0_sysclk6,
- .lpsc = DA8XX_LPSC0_ARM,
- .flags = ALWAYS_ENABLED,
- .set_rate = da850_set_armrate,
- .round_rate = da850_round_armrate,
-};
-
-static struct clk rmii_clk = {
- .name = "rmii",
- .parent = &pll0_sysclk7,
-};
-
-static struct clk emac_clk = {
- .name = "emac",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC1_CPGMAC,
- .gpsc = 1,
-};
-
-/*
- * In order to avoid adding the emac_clk to the clock lookup table twice (and
- * screwing up the linked list in the process) create a separate clock for
- * mdio inheriting the rate from emac_clk.
- */
-static struct clk mdio_clk = {
- .name = "mdio",
- .parent = &emac_clk,
-};
-
-static struct clk mcasp_clk = {
- .name = "mcasp",
- .parent = &async3_clk,
- .lpsc = DA8XX_LPSC1_McASP0,
- .gpsc = 1,
-};
-
-static struct clk mcbsp0_clk = {
- .name = "mcbsp0",
- .parent = &async3_clk,
- .lpsc = DA850_LPSC1_McBSP0,
- .gpsc = 1,
-};
-
-static struct clk mcbsp1_clk = {
- .name = "mcbsp1",
- .parent = &async3_clk,
- .lpsc = DA850_LPSC1_McBSP1,
- .gpsc = 1,
-};
-
-static struct clk lcdc_clk = {
- .name = "lcdc",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_LCDC,
- .gpsc = 1,
-};
-
-static struct clk mmcsd0_clk = {
- .name = "mmcsd0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_MMC_SD,
-};
-
-static struct clk mmcsd1_clk = {
- .name = "mmcsd1",
- .parent = &pll0_sysclk2,
- .lpsc = DA850_LPSC1_MMC_SD1,
- .gpsc = 1,
-};
-
-static struct clk aemif_clk = {
- .name = "aemif",
- .parent = &pll0_sysclk3,
- .lpsc = DA8XX_LPSC0_EMIF25,
- .flags = ALWAYS_ENABLED,
-};
-
-/*
- * In order to avoid adding the aemif_clk to the clock lookup table twice (and
- * screwing up the linked list in the process) create a separate clock for
- * nand inheriting the rate from aemif_clk.
- */
-static struct clk aemif_nand_clk = {
- .name = "nand",
- .parent = &aemif_clk,
-};
-
-static struct clk usb11_clk = {
- .name = "usb11",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC1_USB11,
- .gpsc = 1,
-};
-
-static struct clk usb20_clk = {
- .name = "usb20",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_USB20,
- .gpsc = 1,
-};
-
-static struct clk cppi41_clk = {
- .name = "cppi41",
- .parent = &usb20_clk,
-};
-
-static struct clk spi0_clk = {
- .name = "spi0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_SPI0,
-};
-
-static struct clk spi1_clk = {
- .name = "spi1",
- .parent = &async3_clk,
- .lpsc = DA8XX_LPSC1_SPI1,
- .gpsc = 1,
-};
-
-static struct clk vpif_clk = {
- .name = "vpif",
- .parent = &pll0_sysclk2,
- .lpsc = DA850_LPSC1_VPIF,
- .gpsc = 1,
-};
-
-static struct clk sata_clk = {
- .name = "sata",
- .parent = &pll0_sysclk2,
- .lpsc = DA850_LPSC1_SATA,
- .gpsc = 1,
- .flags = PSC_FORCE,
-};
-
-static struct clk dsp_clk = {
- .name = "dsp",
- .parent = &pll0_sysclk1,
- .domain = DAVINCI_GPSC_DSPDOMAIN,
- .lpsc = DA8XX_LPSC0_GEM,
- .flags = PSC_LRST | PSC_FORCE,
-};
-
-static struct clk ehrpwm_clk = {
- .name = "ehrpwm",
- .parent = &async3_clk,
- .lpsc = DA8XX_LPSC1_PWM,
- .gpsc = 1,
-};
-
-static struct clk ehrpwm0_clk = {
- .name = "ehrpwm0",
- .parent = &ehrpwm_clk,
-};
-
-static struct clk ehrpwm1_clk = {
- .name = "ehrpwm1",
- .parent = &ehrpwm_clk,
-};
-
-#define DA8XX_EHRPWM_TBCLKSYNC BIT(12)
-
-static void ehrpwm_tblck_enable(struct clk *clk)
-{
- u32 val;
-
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
- val |= DA8XX_EHRPWM_TBCLKSYNC;
- writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
-}
-
-static void ehrpwm_tblck_disable(struct clk *clk)
-{
- u32 val;
-
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
- val &= ~DA8XX_EHRPWM_TBCLKSYNC;
- writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
-}
-
-static struct clk ehrpwm_tbclk = {
- .name = "ehrpwm_tbclk",
- .parent = &ehrpwm_clk,
- .clk_enable = ehrpwm_tblck_enable,
- .clk_disable = ehrpwm_tblck_disable,
-};
-
-static struct clk ehrpwm0_tbclk = {
- .name = "ehrpwm0_tbclk",
- .parent = &ehrpwm_tbclk,
-};
-
-static struct clk ehrpwm1_tbclk = {
- .name = "ehrpwm1_tbclk",
- .parent = &ehrpwm_tbclk,
-};
-
-static struct clk ecap_clk = {
- .name = "ecap",
- .parent = &async3_clk,
- .lpsc = DA8XX_LPSC1_ECAP,
- .gpsc = 1,
-};
-
-static struct clk ecap0_clk = {
- .name = "ecap0_clk",
- .parent = &ecap_clk,
-};
-
-static struct clk ecap1_clk = {
- .name = "ecap1_clk",
- .parent = &ecap_clk,
-};
-
-static struct clk ecap2_clk = {
- .name = "ecap2_clk",
- .parent = &ecap_clk,
-};
-
-static struct clk_lookup da850_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "pll0", &pll0_clk),
- CLK(NULL, "pll0_aux", &pll0_aux_clk),
- CLK(NULL, "pll0_sysclk1", &pll0_sysclk1),
- CLK(NULL, "pll0_sysclk2", &pll0_sysclk2),
- CLK(NULL, "pll0_sysclk3", &pll0_sysclk3),
- CLK(NULL, "pll0_sysclk4", &pll0_sysclk4),
- CLK(NULL, "pll0_sysclk5", &pll0_sysclk5),
- CLK(NULL, "pll0_sysclk6", &pll0_sysclk6),
- CLK(NULL, "pll0_sysclk7", &pll0_sysclk7),
- CLK(NULL, "pll1", &pll1_clk),
- CLK(NULL, "pll1_aux", &pll1_aux_clk),
- CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
- CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
- CLK(NULL, "async3", &async3_clk),
- CLK("i2c_davinci.1", NULL, &i2c0_clk),
- CLK(NULL, "timer0", &timerp64_0_clk),
- CLK("davinci-wdt", NULL, &timerp64_1_clk),
- CLK(NULL, "arm_rom", &arm_rom_clk),
- CLK(NULL, "tpcc0", &tpcc0_clk),
- CLK(NULL, "tptc0", &tptc0_clk),
- CLK(NULL, "tptc1", &tptc1_clk),
- CLK(NULL, "tpcc1", &tpcc1_clk),
- CLK(NULL, "tptc2", &tptc2_clk),
- CLK("pruss_uio", "pruss", &pruss_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("serial8250.2", NULL, &uart2_clk),
- CLK(NULL, "aintc", &aintc_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK("i2c_davinci.2", NULL, &i2c1_clk),
- CLK(NULL, "emif3", &emif3_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "rmii", &rmii_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &mdio_clk),
- CLK("davinci-mcasp.0", NULL, &mcasp_clk),
- CLK("davinci-mcbsp.0", NULL, &mcbsp0_clk),
- CLK("davinci-mcbsp.1", NULL, &mcbsp1_clk),
- CLK("da8xx_lcdc.0", "fck", &lcdc_clk),
- CLK("da830-mmc.0", NULL, &mmcsd0_clk),
- CLK("da830-mmc.1", NULL, &mmcsd1_clk),
- CLK("ti-aemif", NULL, &aemif_clk),
- CLK("davinci-nand.0", "aemif", &aemif_nand_clk),
- CLK("ohci-da8xx", NULL, &usb11_clk),
- CLK("musb-da8xx", NULL, &usb20_clk),
- CLK("cppi41-dmaengine", NULL, &cppi41_clk),
- CLK("spi_davinci.0", NULL, &spi0_clk),
- CLK("spi_davinci.1", NULL, &spi1_clk),
- CLK("vpif", NULL, &vpif_clk),
- CLK("ahci_da850", "fck", &sata_clk),
- CLK("davinci-rproc.0", NULL, &dsp_clk),
- CLK(NULL, NULL, &ehrpwm_clk),
- CLK("ehrpwm.0", "fck", &ehrpwm0_clk),
- CLK("ehrpwm.1", "fck", &ehrpwm1_clk),
- CLK(NULL, NULL, &ehrpwm_tbclk),
- CLK("ehrpwm.0", "tbclk", &ehrpwm0_tbclk),
- CLK("ehrpwm.1", "tbclk", &ehrpwm1_tbclk),
- CLK(NULL, NULL, &ecap_clk),
- CLK("ecap.0", "fck", &ecap0_clk),
- CLK("ecap.1", "fck", &ecap1_clk),
- CLK("ecap.2", "fck", &ecap2_clk),
- CLK(NULL, NULL, NULL),
-};
-#endif
-
/*
* Device specific mux setup
*
@@ -964,8 +417,6 @@ static struct map_desc da850_io_desc[] = {
},
};
-static u32 da850_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
-
/* Contents of JTAG ID register used to identify exact cpu type */
static struct davinci_id da850_ids[] = {
{
@@ -1175,93 +626,11 @@ int da850_register_cpufreq(char *async_clk)
return platform_device_register(&da850_cpufreq_device);
}
-
-#ifndef CONFIG_COMMON_CLK
-static int da850_round_armrate(struct clk *clk, unsigned long rate)
-{
- int ret = 0, diff;
- unsigned int best = (unsigned int) -1;
- struct cpufreq_frequency_table *table = cpufreq_info.freq_table;
- struct cpufreq_frequency_table *pos;
-
- rate /= 1000; /* convert to kHz */
-
- cpufreq_for_each_entry(pos, table) {
- diff = pos->frequency - rate;
- if (diff < 0)
- diff = -diff;
-
- if (diff < best) {
- best = diff;
- ret = pos->frequency;
- }
- }
-
- return ret * 1000;
-}
-
-static int da850_set_armrate(struct clk *clk, unsigned long index)
-{
- struct clk *pllclk = &pll0_clk;
-
- return clk_set_rate(pllclk, index);
-}
-
-static int da850_set_pll0rate(struct clk *clk, unsigned long rate)
-{
- struct pll_data *pll = clk->pll_data;
- struct cpufreq_frequency_table *freq;
- unsigned int prediv, mult, postdiv;
- struct da850_opp *opp = NULL;
- int ret;
-
- rate /= 1000;
-
- for (freq = da850_freq_table;
- freq->frequency != CPUFREQ_TABLE_END; freq++) {
- /* rate is in Hz, freq->frequency is in KHz */
- if (freq->frequency == rate) {
- opp = (struct da850_opp *)freq->driver_data;
- break;
- }
- }
-
- if (!opp)
- return -EINVAL;
-
- prediv = opp->prediv;
- mult = opp->mult;
- postdiv = opp->postdiv;
-
- ret = davinci_set_pllrate(pll, prediv, mult, postdiv);
- if (WARN_ON(ret))
- return ret;
-
- return 0;
-}
-#endif /* CONFIG_COMMON_CLK */
#else
int __init da850_register_cpufreq(char *async_clk)
{
return 0;
}
-
-#ifndef CONFIG_COMMON_CLK
-static int da850_set_armrate(struct clk *clk, unsigned long rate)
-{
- return -EINVAL;
-}
-
-static int da850_set_pll0rate(struct clk *clk, unsigned long armrate)
-{
- return -EINVAL;
-}
-
-static int da850_round_armrate(struct clk *clk, unsigned long rate)
-{
- return clk->rate;
-}
-#endif /* CONFIG_COMMON_CLK */
#endif
/* VPIF resource, platform data */
@@ -1363,8 +732,6 @@ static const struct davinci_soc_info davinci_soc_info_da850 = {
.jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
.ids = da850_ids,
.ids_num = ARRAY_SIZE(da850_ids),
- .psc_bases = da850_psc_bases,
- .psc_bases_num = ARRAY_SIZE(da850_psc_bases),
.pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
.pinmux_pins = da850_pins,
.pinmux_pins_num = ARRAY_SIZE(da850_pins),
@@ -1380,8 +747,6 @@ static const struct davinci_soc_info davinci_soc_info_da850 = {
void __init da850_init(void)
{
- unsigned int v;
-
davinci_common_init(&davinci_soc_info_da850);
da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
@@ -1389,32 +754,16 @@ void __init da850_init(void)
return;
da8xx_syscfg1_base = ioremap(DA8XX_SYSCFG1_BASE, SZ_4K);
- if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module"))
- return;
-
- /* Unlock writing to PLL0 registers */
- v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG));
- v &= ~CFGCHIP0_PLL_MASTER_LOCK;
- __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG));
-
- /* Unlock writing to PLL1 registers */
- v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
- v &= ~CFGCHIP3_PLL1_MASTER_LOCK;
- __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
+ WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module");
}
void __init da850_init_time(void)
{
-#ifdef CONFIG_COMMON_CLK
struct clk *clk;
clk = clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DA850_REF_FREQ);
davinci_timer_init(clk);
-#else
- davinci_clk_init(da850_clks);
- davinci_timer_init(&timerp64_0_clk);
-#endif
}
static struct resource da850_pll0_resources[] = {
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index c4edf05..088bc5c 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -69,21 +69,11 @@ static void __init da850_init_machine(void)
da850_register_clocks();
-#ifdef CONFIG_COMMON_CLK
ret = da8xx_register_usb_phy_clocks();
if (ret)
pr_warn("%s: USB PHY CLK registration failed: %d\n",
__func__, ret);
-#else
- ret = da8xx_register_usb20_phy_clk(false);
- if (ret)
- pr_warn("%s: registering USB 2.0 PHY clock failed: %d",
- __func__, ret);
- ret = da8xx_register_usb11_phy_clk(false);
- if (ret)
- pr_warn("%s: registering USB 1.1 PHY clock failed: %d",
- __func__, ret);
-#endif
+
ret = da850_register_sata_refclk(sata_refclkpn);
if (ret)
pr_warn("%s: registering SATA REFCLK failed: %d",
--
2.7.4
This removes all of the clock init code from da8xx-dt.c. This includes
all of the OF_DEV_AUXDATA that was just used for looking up clocks.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- none
v7 changes:
- rebased
- drop of_platform_default_populate(NULL, NULL, NULL)
- add change in pm_domain.c
Note: I didn't see this until it was too late, but Bartosz has an interesting
alternative for the legacy PM domain stuff at
https://github.com/brgl/linux/commit/0197b11512e44206708f4bd320c369a2a163e82d
v6 changes:
- removed misleading statement from commit message
arch/arm/mach-davinci/da8xx-dt.c | 58 ---------------------------------------
arch/arm/mach-davinci/pm_domain.c | 5 ++++
2 files changed, 5 insertions(+), 58 deletions(-)
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index 088bc5c..23ac410 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -19,67 +19,10 @@
#include "cp_intc.h"
#include <mach/da8xx.h>
-static struct of_dev_auxdata da850_aemif_auxdata_lookup[] = {
- OF_DEV_AUXDATA("ti,davinci-nand", 0x62000000, "davinci-nand.0", NULL),
- {}
-};
-
-static struct aemif_platform_data aemif_data = {
- .dev_lookup = da850_aemif_auxdata_lookup,
-};
-
-static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
- OF_DEV_AUXDATA("ti,davinci-i2c", 0x01c22000, "i2c_davinci.1", NULL),
- OF_DEV_AUXDATA("ti,davinci-i2c", 0x01e28000, "i2c_davinci.2", NULL),
- OF_DEV_AUXDATA("ti,davinci-wdt", 0x01c21000, "davinci-wdt", NULL),
- OF_DEV_AUXDATA("ti,da830-mmc", 0x01c40000, "da830-mmc.0", NULL),
- OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f00000, "ehrpwm.0", NULL),
- OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f02000, "ehrpwm.1", NULL),
- OF_DEV_AUXDATA("ti,da850-ecap", 0x01f06000, "ecap.0", NULL),
- OF_DEV_AUXDATA("ti,da850-ecap", 0x01f07000, "ecap.1", NULL),
- OF_DEV_AUXDATA("ti,da850-ecap", 0x01f08000, "ecap.2", NULL),
- OF_DEV_AUXDATA("ti,da830-spi", 0x01c41000, "spi_davinci.0", NULL),
- OF_DEV_AUXDATA("ti,da830-spi", 0x01f0e000, "spi_davinci.1", NULL),
- OF_DEV_AUXDATA("ns16550a", 0x01c42000, "serial8250.0", NULL),
- OF_DEV_AUXDATA("ns16550a", 0x01d0c000, "serial8250.1", NULL),
- OF_DEV_AUXDATA("ns16550a", 0x01d0d000, "serial8250.2", NULL),
- OF_DEV_AUXDATA("ti,davinci_mdio", 0x01e24000, "davinci_mdio.0", NULL),
- OF_DEV_AUXDATA("ti,davinci-dm6467-emac", 0x01e20000, "davinci_emac.1",
- NULL),
- OF_DEV_AUXDATA("ti,da830-mcasp-audio", 0x01d00000, "davinci-mcasp.0", NULL),
- OF_DEV_AUXDATA("ti,da850-aemif", 0x68000000, "ti-aemif", &aemif_data),
- OF_DEV_AUXDATA("ti,da850-tilcdc", 0x01e13000, "da8xx_lcdc.0", NULL),
- OF_DEV_AUXDATA("ti,da830-ohci", 0x01e25000, "ohci-da8xx", NULL),
- OF_DEV_AUXDATA("ti,da830-musb", 0x01e00000, "musb-da8xx", NULL),
- OF_DEV_AUXDATA("ti,da830-usb-phy", 0x01c1417c, "da8xx-usb-phy", NULL),
- OF_DEV_AUXDATA("ti,da850-ahci", 0x01e18000, "ahci_da850", NULL),
- OF_DEV_AUXDATA("ti,da850-vpif", 0x01e17000, "vpif", NULL),
- OF_DEV_AUXDATA("ti,da850-dsp", 0x11800000, "davinci-rproc.0", NULL),
- {}
-};
-
#ifdef CONFIG_ARCH_DAVINCI_DA850
static void __init da850_init_machine(void)
{
- /* All existing boards use 100MHz SATA refclkpn */
- static const unsigned long sata_refclkpn = 100 * 1000 * 1000;
-
- int ret;
-
- da850_register_clocks();
-
- ret = da8xx_register_usb_phy_clocks();
- if (ret)
- pr_warn("%s: USB PHY CLK registration failed: %d\n",
- __func__, ret);
-
- ret = da850_register_sata_refclk(sata_refclkpn);
- if (ret)
- pr_warn("%s: registering SATA REFCLK failed: %d",
- __func__, ret);
-
- of_platform_default_populate(NULL, da850_auxdata_lookup, NULL);
davinci_pm_init();
pdata_quirks_init();
}
@@ -94,7 +37,6 @@ static const char *const da850_boards_compat[] __initconst = {
DT_MACHINE_START(DA850_DT, "Generic DA850/OMAP-L138/AM18x")
.map_io = da850_init,
- .init_time = da850_init_time,
.init_machine = da850_init_machine,
.dt_compat = da850_boards_compat,
.init_late = davinci_init_late,
diff --git a/arch/arm/mach-davinci/pm_domain.c b/arch/arm/mach-davinci/pm_domain.c
index 78eac2c..e251fd5 100644
--- a/arch/arm/mach-davinci/pm_domain.c
+++ b/arch/arm/mach-davinci/pm_domain.c
@@ -13,6 +13,7 @@
#include <linux/pm_runtime.h>
#include <linux/pm_clock.h>
#include <linux/platform_device.h>
+#include <linux/of.h>
static struct dev_pm_domain davinci_pm_domain = {
.ops = {
@@ -28,6 +29,10 @@ static struct pm_clk_notifier_block platform_bus_notifier = {
static int __init davinci_pm_runtime_init(void)
{
+ if (of_have_populated_dt())
+ return 0;
+
+ /* Use pm_clk as fallback if we're not using genpd. */
pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
return 0;
--
2.7.4
This switches ARCH_DAVINCI to use the common clock framework. The legacy
clock code in arch/arm/mach-davinci/ is no longer used. New drivers in
drivers/clk/davinci/ are used instead.
A few macros had to be moved to prevent compilation errors.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- none
v7 changes:
- s/compile/compilation and space instead of tab
- add PM_GENERIC_DOMAINS dependencies
v6 changes:
- clean up indent on Common objects section
arch/arm/Kconfig | 5 ++++-
arch/arm/mach-davinci/Makefile | 4 ++--
arch/arm/mach-davinci/clock.h | 4 ----
arch/arm/mach-davinci/davinci.h | 4 ++++
arch/arm/mach-davinci/psc.h | 2 --
5 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7e3d535..563fade 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -608,13 +608,16 @@ config ARCH_S3C24XX
config ARCH_DAVINCI
bool "TI DaVinci"
select ARCH_HAS_HOLES_MEMORYMODEL
- select CLKDEV_LOOKUP
+ select COMMON_CLK
select CPU_ARM926T
select GENERIC_ALLOCATOR
select GENERIC_CLOCKEVENTS
select GENERIC_IRQ_CHIP
select GPIOLIB
select HAVE_IDE
+ select PM_GENERIC_DOMAINS if PM
+ select PM_GENERIC_DOMAINS_OF if PM && OF
+ select RESET_CONTROLLER
select USE_OF
select ZONE_DMA
help
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index 4e81780..8725d8b 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -5,8 +5,8 @@
#
# Common objects
-obj-y := time.o clock.o serial.o psc.o \
- usb.o common.o sram.o aemif.o
+obj-y := time.o serial.o usb.o \
+ common.o sram.o aemif.o
obj-$(CONFIG_DAVINCI_MUX) += mux.o
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index d7894d5..2d05856 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -12,10 +12,6 @@
#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)
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index a200977..a227f80 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -35,6 +35,10 @@
#include <media/davinci/vpbe.h>
#include <media/davinci/vpbe_osd.h>
+#define DAVINCI_PLL1_BASE 0x01c40800
+#define DAVINCI_PLL2_BASE 0x01c40c00
+#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01c41000
+
#define DAVINCI_SYSTEM_MODULE_BASE 0x01c40000
#define SYSMOD_VDAC_CONFIG 0x2c
#define SYSMOD_VIDCLKCTL 0x38
diff --git a/arch/arm/mach-davinci/psc.h b/arch/arm/mach-davinci/psc.h
index 8af9f09..b58707c 100644
--- a/arch/arm/mach-davinci/psc.h
+++ b/arch/arm/mach-davinci/psc.h
@@ -27,8 +27,6 @@
#ifndef __ASM_ARCH_PSC_H
#define __ASM_ARCH_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
--
2.7.4
This removes CONFIG_DAVINCI_RESET_CLOCKS. The option has been removed from
the kernel.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
---
v8 changes:
- none
v7 changes:
- none
v6 changes:
- none
arch/arm/configs/davinci_all_defconfig | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index c302a04..0f4d20b 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -31,7 +31,6 @@ CONFIG_MACH_MITYOMAPL138=y
CONFIG_MACH_OMAPL138_HAWKBOARD=y
CONFIG_DAVINCI_MUX_DEBUG=y
CONFIG_DAVINCI_MUX_WARNINGS=y
-CONFIG_DAVINCI_RESET_CLOCKS=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_CMA=y
--
2.7.4
This adds clock provider nodes for da850 and wires them up to all of the
devices.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- fix typo in clock-names property of psc0
- added power-domains properties to nodes that define that property in their
device tree bindings
v7 changes:
- move ref_clk frequency to board-specific DT files
- enable sata_refclk in da850-lcdk.dts
- drop async2 fixed factor clock
- add power-domains for devices that use them
- fix USB PHY clock-names property
- move assigned-clocks to PSC device node
- drop clocks property from devices that don't use it (e.g. EDMA)
- add clock to RTC node
- add clock-ranges to usb0 and aemif nodes
- add clock-names property to aemif node
- fix typo in psc1 clock-names
v6 changes:
- updated for device tree bindings changes earlier in this series
- use single async2 clock instead of duplicate fixed factor clocks
- add clock-names property to mdio node
arch/arm/boot/dts/da850-enbw-cmc.dts | 4 +
arch/arm/boot/dts/da850-evm.dts | 4 +
arch/arm/boot/dts/da850-lcdk.dts | 9 ++
arch/arm/boot/dts/da850-lego-ev3.dts | 4 +
arch/arm/boot/dts/da850.dtsi | 167 +++++++++++++++++++++++++++++++++++
5 files changed, 188 insertions(+)
diff --git a/arch/arm/boot/dts/da850-enbw-cmc.dts b/arch/arm/boot/dts/da850-enbw-cmc.dts
index 14dff3e..0102ffc 100644
--- a/arch/arm/boot/dts/da850-enbw-cmc.dts
+++ b/arch/arm/boot/dts/da850-enbw-cmc.dts
@@ -35,6 +35,10 @@
};
};
+&ref_clk {
+ clock-frequency = <24000000>;
+};
+
&edma0 {
ti,edma-reserved-slot-ranges = <32 50>;
};
diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts
index c82368c..38a53dd 100644
--- a/arch/arm/boot/dts/da850-evm.dts
+++ b/arch/arm/boot/dts/da850-evm.dts
@@ -200,6 +200,10 @@
};
};
+&ref_clk {
+ clock-frequency = <24000000>;
+};
+
/include/ "tps6507x.dtsi"
&tps {
diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
index a1f4d6d..90b917c 100644
--- a/arch/arm/boot/dts/da850-lcdk.dts
+++ b/arch/arm/boot/dts/da850-lcdk.dts
@@ -123,6 +123,10 @@
};
};
+&ref_clk {
+ clock-frequency = <24000000>;
+};
+
&pmx_core {
status = "okay";
@@ -175,6 +179,11 @@
status = "okay";
};
+&sata_refclk {
+ status = "okay";
+ clock-frequency = <100000000>;
+};
+
&sata {
status = "okay";
};
diff --git a/arch/arm/boot/dts/da850-lego-ev3.dts b/arch/arm/boot/dts/da850-lego-ev3.dts
index 1ffd877..4425cb4 100644
--- a/arch/arm/boot/dts/da850-lego-ev3.dts
+++ b/arch/arm/boot/dts/da850-lego-ev3.dts
@@ -203,6 +203,10 @@
};
};
+&ref_clk {
+ clock-frequency = <24000000>;
+};
+
&pmx_core {
status = "okay";
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index c66cf78..e8117c7 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -21,6 +21,26 @@
#interrupt-cells = <1>;
ti,intc-size = <101>;
reg = <0xfffee000 0x2000>;
+ clocks = <&psc0 6>;
+ };
+ };
+ clocks: clocks {
+ ref_clk: ref_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-output-names = "ref_clk";
+ };
+ sata_refclk: sata_refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-output-names = "sata_refclk";
+ status = "disabled";
+ };
+ usb_refclkin: usb_refclkin {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-output-names = "usb_refclkin";
+ status = "disabled";
};
};
dsp: dsp@11800000 {
@@ -33,6 +53,7 @@
reg-names = "l2sram", "l1pram", "l1dram", "host1cfg", "chipsig";
interrupt-parent = <&intc>;
interrupts = <28>;
+ clocks = <&psc0 15>;
status = "disabled";
};
soc@1c00000 {
@@ -43,6 +64,37 @@
ranges = <0x0 0x01c00000 0x400000>;
interrupt-parent = <&intc>;
+ psc0: clock-controller@10000 {
+ compatible = "ti,da850-psc0";
+ reg = <0x10000 0x1000>;
+ #clock-cells = <1>;
+ #power-domain-cells = <1>;
+ clocks = <&pll0_sysclk 1>, <&pll0_sysclk 2>,
+ <&pll0_sysclk 4>, <&pll0_sysclk 6>,
+ <&async1_clk>;
+ clock-names = "pll0_sysclk1", "pll0_sysclk2",
+ "pll0_sysclk4", "pll0_sysclk6",
+ "async1";
+ };
+ pll0: clock-controller@11000 {
+ compatible = "ti,da850-pll0";
+ reg = <0x11000 0x1000>;
+ clocks = <&ref_clk>, <&pll1_sysclk 3>;
+ clock-names = "clksrc", "extclksrc";
+
+ pll0_pllout: pllout {
+ #clock-cells = <0>;
+ };
+ pll0_sysclk: sysclk {
+ #clock-cells = <1>;
+ };
+ pll0_auxclk: auxclk {
+ #clock-cells = <0>;
+ };
+ pll0_obsclk: obsclk {
+ #clock-cells = <0>;
+ };
+ };
pmx_core: pinmux@14120 {
compatible = "pinctrl-single";
reg = <0x14120 0x50>;
@@ -264,8 +316,41 @@
usb_phy: usb-phy {
compatible = "ti,da830-usb-phy";
#phy-cells = <1>;
+ clocks = <&usb_phy_clk 0>, <&usb_phy_clk 1>;
+ clock-names = "usb0_clk48", "usb1_clk48";
status = "disabled";
};
+ usb_phy_clk: usb-phy-clocks {
+ compatible = "ti,da830-usb-phy-clocks";
+ #clock-cells = <1>;
+ clocks = <&psc1 1>, <&usb_refclkin>,
+ <&pll0_auxclk>;
+ clock-names = "fck", "usb_refclkin", "auxclk";
+ };
+ ehrpwm_tbclk: ehrpwm_tbclk {
+ compatible = "ti,da830-tbclksync";
+ #clock-cells = <0>;
+ clocks = <&psc1 17>;
+ clock-names = "fck";
+ };
+ div4p5_clk: div4.5 {
+ compatible = "ti,da830-div4p5ena";
+ #clock-cells = <0>;
+ clocks = <&pll0_pllout>;
+ clock-names = "pll0_pllout";
+ };
+ async1_clk: async1 {
+ compatible = "ti,da850-async1-clksrc";
+ #clock-cells = <0>;
+ clocks = <&pll0_sysclk 3>, <&div4p5_clk>;
+ clock-names = "pll0_sysclk3", "div4.5";
+ };
+ async3_clk: async3 {
+ compatible = "ti,da850-async3-clksrc";
+ #clock-cells = <0>;
+ clocks = <&pll0_sysclk 2>, <&pll1_sysclk 2>;
+ clock-names = "pll0_sysclk2", "pll1_sysclk2";
+ };
};
edma0: edma@0 {
compatible = "ti,edma3-tpcc";
@@ -277,18 +362,21 @@
#dma-cells = <2>;
ti,tptcs = <&edma0_tptc0 7>, <&edma0_tptc1 0>;
+ power-domains = <&psc0 0>;
};
edma0_tptc0: tptc@8000 {
compatible = "ti,edma3-tptc";
reg = <0x8000 0x400>;
interrupts = <13>;
interrupt-names = "edm3_tcerrint";
+ power-domains = <&psc0 1>;
};
edma0_tptc1: tptc@8400 {
compatible = "ti,edma3-tptc";
reg = <0x8400 0x400>;
interrupts = <32>;
interrupt-names = "edm3_tcerrint";
+ power-domains = <&psc0 2>;
};
edma1: edma@230000 {
compatible = "ti,edma3-tpcc";
@@ -300,12 +388,14 @@
#dma-cells = <2>;
ti,tptcs = <&edma1_tptc0 7>;
+ power-domains = <&psc1 0>;
};
edma1_tptc0: tptc@238000 {
compatible = "ti,edma3-tptc";
reg = <0x238000 0x400>;
interrupts = <95>;
interrupt-names = "edm3_tcerrint";
+ power-domains = <&psc1 21>;
};
serial0: serial@42000 {
compatible = "ti,da830-uart", "ns16550a";
@@ -313,6 +403,8 @@
reg-io-width = <4>;
reg-shift = <2>;
interrupts = <25>;
+ clocks = <&psc0 9>;
+ power-domains = <&psc0 9>;
status = "disabled";
};
serial1: serial@10c000 {
@@ -321,6 +413,8 @@
reg-io-width = <4>;
reg-shift = <2>;
interrupts = <53>;
+ clocks = <&psc1 12>;
+ power-domains = <&psc1 12>;
status = "disabled";
};
serial2: serial@10d000 {
@@ -329,6 +423,8 @@
reg-io-width = <4>;
reg-shift = <2>;
interrupts = <61>;
+ clocks = <&psc1 13>;
+ power-domains = <&psc1 13>;
status = "disabled";
};
rtc0: rtc@23000 {
@@ -336,6 +432,8 @@
reg = <0x23000 0x1000>;
interrupts = <19
19>;
+ clocks = <&pll0_auxclk>;
+ clock-names = "int-clk";
status = "disabled";
};
i2c0: i2c@22000 {
@@ -344,6 +442,7 @@
interrupts = <15>;
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&pll0_auxclk>;
status = "disabled";
};
i2c1: i2c@228000 {
@@ -352,11 +451,19 @@
interrupts = <51>;
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&psc1 11>;
+ power-domains = <&psc1 11>;
status = "disabled";
};
+ clocksource: timer@20000 {
+ compatible = "ti,davinci-timer";
+ reg = <0x20000 0x1000>;
+ clocks = <&pll0_auxclk>;
+ };
wdt: wdt@21000 {
compatible = "ti,davinci-wdt";
reg = <0x21000 0x1000>;
+ clocks = <&pll0_auxclk>;
status = "disabled";
};
mmc0: mmc@40000 {
@@ -367,12 +474,14 @@
interrupts = <16>;
dmas = <&edma0 16 0>, <&edma0 17 0>;
dma-names = "rx", "tx";
+ clocks = <&psc0 5>;
status = "disabled";
};
vpif: video@217000 {
compatible = "ti,da850-vpif";
reg = <0x217000 0x1000>;
interrupts = <92>;
+ clocks = <&psc1 9>;
status = "disabled";
/* VPIF capture port */
@@ -395,6 +504,7 @@
interrupts = <72>;
dmas = <&edma1 28 0>, <&edma1 29 0>;
dma-names = "rx", "tx";
+ clocks = <&psc1 18>;
status = "disabled";
};
ehrpwm0: pwm@300000 {
@@ -402,6 +512,8 @@
"ti,am33xx-ehrpwm";
#pwm-cells = <3>;
reg = <0x300000 0x2000>;
+ clocks = <&psc1 17>, <&ehrpwm_tbclk>;
+ clock-names = "fck", "tbclk";
status = "disabled";
};
ehrpwm1: pwm@302000 {
@@ -409,6 +521,8 @@
"ti,am33xx-ehrpwm";
#pwm-cells = <3>;
reg = <0x302000 0x2000>;
+ clocks = <&psc1 17>, <&ehrpwm_tbclk>;
+ clock-names = "fck", "tbclk";
status = "disabled";
};
ecap0: ecap@306000 {
@@ -416,6 +530,8 @@
"ti,am33xx-ecap";
#pwm-cells = <3>;
reg = <0x306000 0x80>;
+ clocks = <&psc1 20>;
+ clock-names = "fck";
status = "disabled";
};
ecap1: ecap@307000 {
@@ -423,6 +539,8 @@
"ti,am33xx-ecap";
#pwm-cells = <3>;
reg = <0x307000 0x80>;
+ clocks = <&psc1 20>;
+ clock-names = "fck";
status = "disabled";
};
ecap2: ecap@308000 {
@@ -430,6 +548,8 @@
"ti,am33xx-ecap";
#pwm-cells = <3>;
reg = <0x308000 0x80>;
+ clocks = <&psc1 20>;
+ clock-names = "fck";
status = "disabled";
};
spi0: spi@41000 {
@@ -442,6 +562,8 @@
interrupts = <20>;
dmas = <&edma0 14 0>, <&edma0 15 0>;
dma-names = "rx", "tx";
+ clocks = <&psc0 4>;
+ power-domains = <&psc0 4>;
status = "disabled";
};
spi1: spi@30e000 {
@@ -454,6 +576,8 @@
interrupts = <56>;
dmas = <&edma0 18 0>, <&edma0 19 0>;
dma-names = "rx", "tx";
+ clocks = <&psc1 10>;
+ power-domains = <&psc1 10>;
status = "disabled";
};
usb0: usb@200000 {
@@ -465,6 +589,8 @@
dr_mode = "otg";
phys = <&usb_phy 0>;
phy-names = "usb-phy";
+ clocks = <&psc1 1>;
+ clock-ranges;
status = "disabled";
#address-cells = <1>;
@@ -495,13 +621,31 @@
compatible = "ti,da850-ahci";
reg = <0x218000 0x2000>, <0x22c018 0x4>;
interrupts = <67>;
+ clocks = <&psc1 8>, <&sata_refclk>;
+ clock-names = "fck", "refclk";
status = "disabled";
};
+ pll1: clock-controller@21a000 {
+ compatible = "ti,da850-pll1";
+ reg = <0x21a000 0x1000>;
+ clocks = <&ref_clk>;
+ clock-names = "clksrc";
+
+ pll1_sysclk: sysclk {
+ #clock-cells = <1>;
+ };
+ pll1_obsclk: obsclk {
+ #clock-cells = <0>;
+ };
+ };
mdio: mdio@224000 {
compatible = "ti,davinci_mdio";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x224000 0x1000>;
+ clocks = <&psc1 5>;
+ clock-names = "fck";
+ power-domains = <&psc1 5>;
status = "disabled";
};
eth0: ethernet@220000 {
@@ -517,6 +661,8 @@
35
36
>;
+ clocks = <&psc1 5>;
+ power-domains = <&psc1 5>;
status = "disabled";
};
usb1: usb@225000 {
@@ -525,6 +671,7 @@
interrupts = <59>;
phys = <&usb_phy 1>;
phy-names = "usb-phy";
+ clocks = <&psc1 2>;
status = "disabled";
};
gpio: gpio@226000 {
@@ -542,6 +689,19 @@
status = "disabled";
interrupt-controller;
#interrupt-cells = <2>;
+ clocks = <&psc1 3>;
+ clock-names = "gpio";
+ };
+ psc1: clock-controller@227000 {
+ compatible = "ti,da850-psc1";
+ reg = <0x227000 0x1000>;
+ #clock-cells = <1>;
+ #power-domain-cells = <1>;
+ clocks = <&pll0_sysclk 2>, <&pll0_sysclk 4>,
+ <&async3_clk>;
+ clock-names = "pll0_sysclk2", "pll0_sysclk4", "async3";
+ assigned-clocks = <&async3_clk>;
+ assigned-clock-parents = <&pll1_sysclk 2>;
};
pinconf: pin-controller@22c00c {
compatible = "ti,da850-pupd";
@@ -560,6 +720,7 @@
dmas = <&edma0 1 1>,
<&edma0 0 1>;
dma-names = "tx", "rx";
+ clocks = <&psc1 7>;
};
lcdc: display@213000 {
@@ -567,6 +728,9 @@
reg = <0x213000 0x1000>;
interrupts = <52>;
max-pixelclock = <37500>;
+ clocks = <&psc1 16>;
+ clock-names = "fck";
+ power-domains = <&psc1 16>;
status = "disabled";
};
};
@@ -578,6 +742,9 @@
reg = <0x68000000 0x00008000>;
ranges = <0 0 0x60000000 0x08000000
1 0 0x68000000 0x00008000>;
+ clocks = <&psc0 3>;
+ clock-names = "aemif";
+ clock-ranges;
status = "disabled";
};
memctrl: memory-controller@b0000000 {
--
2.7.4
This removes the unused legacy clock init code from
arch/arm/mach-davinci/dm644x.c.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
---
v8 changes:
- none
v7 changes:
- rebased
- add davinci prefix to commit message
v6 changes:
- rebased
arch/arm/mach-davinci/dm644x.c | 300 -----------------------------------------
1 file changed, 300 deletions(-)
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 64f5193..6d3a0e8 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -29,11 +29,6 @@
#include "davinci.h"
#include "mux.h"
-#ifndef CONFIG_COMMON_CLK
-#include "clock.h"
-#include "psc.h"
-#endif
-
/*
* Device specific clocks
*/
@@ -46,292 +41,6 @@
#define DM644X_EMAC_CNTRL_RAM_OFFSET 0x2000
#define DM644X_EMAC_CNTRL_RAM_SIZE 0x2000
-#ifndef CONFIG_COMMON_CLK
-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("vpss", "master", &vpss_master_clk),
- CLK("vpss", "slave", &vpss_slave_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("serial8250.2", NULL, &uart2_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &emac_clk),
- CLK("i2c_davinci.1", NULL, &i2c_clk),
- CLK("palm_bk3710", NULL, &ide_clk),
- CLK("davinci-mcbsp", NULL, &asp_clk),
- CLK("dm6441-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("davinci-wdt", 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,
@@ -824,8 +533,6 @@ static struct davinci_id dm644x_ids[] = {
},
};
-static u32 dm644x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
/*
* T0_BOT: Timer 0, bottom: clockevent source for hrtimers
* T0_TOP: Timer 0, top : clocksource for generic timekeeping
@@ -910,8 +617,6 @@ static const struct davinci_soc_info davinci_soc_info_dm644x = {
.jtag_id_reg = 0x01c40028,
.ids = dm644x_ids,
.ids_num = ARRAY_SIZE(dm644x_ids),
- .psc_bases = dm644x_psc_bases,
- .psc_bases_num = ARRAY_SIZE(dm644x_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
.pinmux_pins = dm644x_pins,
.pinmux_pins_num = ARRAY_SIZE(dm644x_pins),
@@ -939,16 +644,11 @@ void __init dm644x_init(void)
void __init dm644x_init_time(void)
{
-#ifdef CONFIG_COMMON_CLK
struct clk *clk;
clk = clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM644X_REF_FREQ);
davinci_timer_init(clk);
-#else
- davinci_clk_init(dm644x_clks);
- davinci_timer_init(&timer0_clk);
-#endif
}
static struct resource dm644x_pll1_resources[] = {
--
2.7.4
This removes the unused legacy USB and SATA clock init code from
arch/arm/mach-davinci/{devices,usb}-da8xx}.c.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
---
v8 changes:
- none
v7 changes:
- rebased
- add davinci prefix to commit message
- mention SATA and USB in commit message
v6 changes:
- rebased
arch/arm/mach-davinci/devices-da8xx.c | 29 ----
arch/arm/mach-davinci/include/mach/da8xx.h | 3 -
arch/arm/mach-davinci/usb-da8xx.c | 238 -----------------------------
3 files changed, 270 deletions(-)
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 73de449..1fd3619 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -30,11 +30,6 @@
#include "cpuidle.h"
#include "sram.h"
-#ifndef CONFIG_COMMON_CLK
-#include <mach/clock.h>
-#include "clock.h"
-#endif
-
#define DA8XX_TPCC_BASE 0x01c00000
#define DA8XX_TPTC0_BASE 0x01c08000
#define DA8XX_TPTC1_BASE 0x01c08400
@@ -1045,29 +1040,6 @@ int __init da8xx_register_spi_bus(int instance, unsigned num_chipselect)
}
#ifdef CONFIG_ARCH_DAVINCI_DA850
-#ifndef CONFIG_COMMON_CLK
-static struct clk sata_refclk = {
- .name = "sata_refclk",
- .set_rate = davinci_simple_set_rate,
-};
-
-static struct clk_lookup sata_refclk_lookup =
- CLK("ahci_da850", "refclk", &sata_refclk);
-
-int __init da850_register_sata_refclk(int rate)
-{
- int ret;
-
- sata_refclk.rate = rate;
- ret = clk_register(&sata_refclk);
- if (ret)
- return ret;
-
- clkdev_add(&sata_refclk_lookup);
-
- return 0;
-}
-#else
int __init da850_register_sata_refclk(int rate)
{
struct clk *clk;
@@ -1078,7 +1050,6 @@ int __init da850_register_sata_refclk(int rate)
return clk_register_clkdev(clk, "refclk", "ahci_da850");
}
-#endif
static struct resource da850_sata_resources[] = {
{
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 5d7b1de..ab4a57f 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -103,9 +103,6 @@ int da8xx_register_watchdog(void);
int da8xx_register_usb_phy(void);
int da8xx_register_usb20(unsigned mA, unsigned potpgt);
int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
-int da8xx_register_usb_refclkin(int rate);
-int da8xx_register_usb20_phy_clk(bool use_usb_refclkin);
-int da8xx_register_usb11_phy_clk(bool use_usb_refclkin);
int da8xx_register_usb_phy_clocks(void);
int da850_register_sata_refclk(int rate);
int da8xx_register_emac(void);
diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
index d0ba725..b17253f 100644
--- a/arch/arm/mach-davinci/usb-da8xx.c
+++ b/arch/arm/mach-davinci/usb-da8xx.c
@@ -20,11 +20,6 @@
#include <mach/da8xx.h>
#include <mach/irqs.h>
-#ifndef CONFIG_COMMON_CLK
-#include <mach/clock.h>
-#include "clock.h"
-#endif
-
#define DA8XX_USB0_BASE 0x01e00000
#define DA8XX_USB1_BASE 0x01e25000
@@ -89,11 +84,6 @@ static struct platform_device da8xx_usb20_dev = {
.name = "musb-da8xx",
.id = -1,
.dev = {
- /*
- * Setting init_name so that clock lookup will work in
- * usb20_phy_clk_enable() even if this device is not registered.
- */
- .init_name = "musb-da8xx",
.platform_data = &usb_data,
.dma_mask = &usb_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
@@ -142,234 +132,6 @@ int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata)
return platform_device_register(&da8xx_usb11_device);
}
-#ifndef CONFIG_COMMON_CLK
-static struct clk usb_refclkin = {
- .name = "usb_refclkin",
- .set_rate = davinci_simple_set_rate,
-};
-
-static struct clk_lookup usb_refclkin_lookup =
- CLK(NULL, "usb_refclkin", &usb_refclkin);
-
-/**
- * da8xx_register_usb_refclkin - register USB_REFCLKIN clock
- *
- * @rate: The clock rate in Hz
- *
- * This clock is only needed if the board provides an external USB_REFCLKIN
- * signal, in which case it will be used as the parent of usb20_phy_clk and/or
- * usb11_phy_clk.
- */
-int __init da8xx_register_usb_refclkin(int rate)
-{
- int ret;
-
- usb_refclkin.rate = rate;
- ret = clk_register(&usb_refclkin);
- if (ret)
- return ret;
-
- clkdev_add(&usb_refclkin_lookup);
-
- return 0;
-}
-
-static void usb20_phy_clk_enable(struct clk *clk)
-{
- u32 val;
- u32 timeout = 500000; /* 500 msec */
-
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
- /* The USB 2.O PLL requires that the USB 2.O PSC is enabled as well. */
- davinci_clk_enable(usb20_clk);
-
- /*
- * Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
- * host may use the PLL clock without USB 2.0 OTG being used.
- */
- val &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN);
- val |= CFGCHIP2_PHY_PLLON;
-
- writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
- while (--timeout) {
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
- if (val & CFGCHIP2_PHYCLKGD)
- goto done;
- udelay(1);
- }
-
- pr_err("Timeout waiting for USB 2.0 PHY clock good\n");
-done:
- davinci_clk_disable(usb20_clk);
-}
-
-static void usb20_phy_clk_disable(struct clk *clk)
-{
- u32 val;
-
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
- val |= CFGCHIP2_PHYPWRDN;
- writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-}
-
-static int usb20_phy_clk_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 val;
-
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
- /* Set the mux depending on the parent clock. */
- if (parent == &usb_refclkin) {
- val &= ~CFGCHIP2_USB2PHYCLKMUX;
- } else if (strcmp(parent->name, "pll0_aux_clk") == 0) {
- val |= CFGCHIP2_USB2PHYCLKMUX;
- } else {
- pr_err("Bad parent on USB 2.0 PHY clock\n");
- return -EINVAL;
- }
-
- /* reference frequency also comes from parent clock */
- val &= ~CFGCHIP2_REFFREQ_MASK;
- switch (clk_get_rate(parent)) {
- case 12000000:
- val |= CFGCHIP2_REFFREQ_12MHZ;
- break;
- case 13000000:
- val |= CFGCHIP2_REFFREQ_13MHZ;
- break;
- case 19200000:
- val |= CFGCHIP2_REFFREQ_19_2MHZ;
- break;
- case 20000000:
- val |= CFGCHIP2_REFFREQ_20MHZ;
- break;
- case 24000000:
- val |= CFGCHIP2_REFFREQ_24MHZ;
- break;
- case 26000000:
- val |= CFGCHIP2_REFFREQ_26MHZ;
- break;
- case 38400000:
- val |= CFGCHIP2_REFFREQ_38_4MHZ;
- break;
- case 40000000:
- val |= CFGCHIP2_REFFREQ_40MHZ;
- break;
- case 48000000:
- val |= CFGCHIP2_REFFREQ_48MHZ;
- break;
- default:
- pr_err("Bad parent clock rate on USB 2.0 PHY clock\n");
- return -EINVAL;
- }
-
- writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
- return 0;
-}
-
-static struct clk usb20_phy_clk = {
- .name = "usb0_clk48",
- .clk_enable = usb20_phy_clk_enable,
- .clk_disable = usb20_phy_clk_disable,
- .set_parent = usb20_phy_clk_set_parent,
-};
-
-static struct clk_lookup usb20_phy_clk_lookup =
- CLK("da8xx-usb-phy", "usb0_clk48", &usb20_phy_clk);
-
-/**
- * da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
- *
- * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
- * or "pll0_aux" if false.
- */
-int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
-{
- struct clk *parent;
- int ret;
-
- usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
- ret = PTR_ERR_OR_ZERO(usb20_clk);
- if (ret)
- return ret;
-
- parent = clk_get(NULL, use_usb_refclkin ? "usb_refclkin" : "pll0_aux");
- ret = PTR_ERR_OR_ZERO(parent);
- if (ret) {
- clk_put(usb20_clk);
- return ret;
- }
-
- usb20_phy_clk.parent = parent;
- ret = clk_register(&usb20_phy_clk);
- if (!ret)
- clkdev_add(&usb20_phy_clk_lookup);
-
- clk_put(parent);
-
- return ret;
-}
-
-static int usb11_phy_clk_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 val;
-
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
- /* Set the USB 1.1 PHY clock mux based on the parent clock. */
- if (parent == &usb20_phy_clk) {
- val &= ~CFGCHIP2_USB1PHYCLKMUX;
- } else if (parent == &usb_refclkin) {
- val |= CFGCHIP2_USB1PHYCLKMUX;
- } else {
- pr_err("Bad parent on USB 1.1 PHY clock\n");
- return -EINVAL;
- }
-
- writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
- return 0;
-}
-
-static struct clk usb11_phy_clk = {
- .name = "usb1_clk48",
- .set_parent = usb11_phy_clk_set_parent,
-};
-
-static struct clk_lookup usb11_phy_clk_lookup =
- CLK("da8xx-usb-phy", "usb1_clk48", &usb11_phy_clk);
-
-/**
- * da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock
- *
- * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
- * or "usb0_clk48" if false.
- */
-int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
-{
- struct clk *parent;
- int ret = 0;
-
- if (use_usb_refclkin)
- parent = clk_get(NULL, "usb_refclkin");
- else
- parent = clk_get(&da8xx_usb_phy.dev, "usb0_clk48");
- if (IS_ERR(parent))
- return PTR_ERR(parent);
-
- usb11_phy_clk.parent = parent;
- ret = clk_register(&usb11_phy_clk);
- if (!ret)
- clkdev_add(&usb11_phy_clk_lookup);
-
- clk_put(parent);
-
- return ret;
-}
-#endif
static struct platform_device da8xx_usb_phy_clks_device = {
.name = "da830-usb-phy-clks",
.id = -1,
--
2.7.4
This removes the unused legacy clock init code from
arch/arm/mach-davinci/dm646x.c.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
---
v8 changes:
- rebased
v7 changes:
- rebased
- add davinci prefix to commit message
v6 changes:
- rebased
arch/arm/mach-davinci/dm646x.c | 329 -----------------------------------------
1 file changed, 329 deletions(-)
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 553782f..d14ffd6 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -31,11 +31,6 @@
#include "davinci.h"
#include "mux.h"
-#ifndef CONFIG_COMMON_CLK
-#include "clock.h"
-#include "psc.h"
-#endif
-
#define DAVINCI_VPIF_BASE (0x01C12000)
#define VDD3P3V_VID_MASK (BIT_MASK(3) | BIT_MASK(2) | BIT_MASK(1) |\
@@ -50,319 +45,6 @@
#define DM646X_EMAC_CNTRL_RAM_OFFSET 0x2000
#define DM646X_EMAC_CNTRL_RAM_SIZE 0x2000
-#ifndef CONFIG_COMMON_CLK
-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 is initialized in dm646x_init_time() */
-};
-
-static struct clk aux_clkin = {
- .name = "aux_clkin",
- /* rate is initialized in dm646x_init_time() */
-};
-
-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_sysclk4 = {
- .name = "pll1_sysclk4",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV4,
-};
-
-static struct clk pll1_sysclk5 = {
- .name = "pll1_sysclk5",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV5,
-};
-
-static struct clk pll1_sysclk6 = {
- .name = "pll1_sysclk6",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV6,
-};
-
-static struct clk pll1_sysclk8 = {
- .name = "pll1_sysclk8",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV8,
-};
-
-static struct clk pll1_sysclk9 = {
- .name = "pll1_sysclk9",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV9,
-};
-
-static struct clk pll1_sysclkbp = {
- .name = "pll1_sysclkbp",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
- .div_reg = BPDIV,
-};
-
-static struct clk pll1_aux_clk = {
- .name = "pll1_aux_clk",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll2_clk = {
- .name = "pll2_clk",
- .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 dsp_clk = {
- .name = "dsp",
- .parent = &pll1_sysclk1,
- .lpsc = DM646X_LPSC_C64X_CPU,
- .usecount = 1, /* REVISIT how to disable? */
-};
-
-static struct clk arm_clk = {
- .name = "arm",
- .parent = &pll1_sysclk2,
- .lpsc = DM646X_LPSC_ARM,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_cc_clk = {
- .name = "edma_cc",
- .parent = &pll1_sysclk2,
- .lpsc = DM646X_LPSC_TPCC,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc0_clk = {
- .name = "edma_tc0",
- .parent = &pll1_sysclk2,
- .lpsc = DM646X_LPSC_TPTC0,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc1_clk = {
- .name = "edma_tc1",
- .parent = &pll1_sysclk2,
- .lpsc = DM646X_LPSC_TPTC1,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc2_clk = {
- .name = "edma_tc2",
- .parent = &pll1_sysclk2,
- .lpsc = DM646X_LPSC_TPTC2,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc3_clk = {
- .name = "edma_tc3",
- .parent = &pll1_sysclk2,
- .lpsc = DM646X_LPSC_TPTC3,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk uart0_clk = {
- .name = "uart0",
- .parent = &aux_clkin,
- .lpsc = DM646X_LPSC_UART0,
-};
-
-static struct clk uart1_clk = {
- .name = "uart1",
- .parent = &aux_clkin,
- .lpsc = DM646X_LPSC_UART1,
-};
-
-static struct clk uart2_clk = {
- .name = "uart2",
- .parent = &aux_clkin,
- .lpsc = DM646X_LPSC_UART2,
-};
-
-static struct clk i2c_clk = {
- .name = "I2CCLK",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_I2C,
-};
-
-static struct clk gpio_clk = {
- .name = "gpio",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_GPIO,
-};
-
-static struct clk mcasp0_clk = {
- .name = "mcasp0",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_McASP0,
-};
-
-static struct clk mcasp1_clk = {
- .name = "mcasp1",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_McASP1,
-};
-
-static struct clk aemif_clk = {
- .name = "aemif",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_AEMIF,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk emac_clk = {
- .name = "emac",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_EMAC,
-};
-
-static struct clk pwm0_clk = {
- .name = "pwm0",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_PWM0,
- .usecount = 1, /* REVIST: disabling hangs system */
-};
-
-static struct clk pwm1_clk = {
- .name = "pwm1",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_PWM1,
- .usecount = 1, /* REVIST: disabling hangs system */
-};
-
-static struct clk timer0_clk = {
- .name = "timer0",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_TIMER0,
-};
-
-static struct clk timer1_clk = {
- .name = "timer1",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_TIMER1,
-};
-
-static struct clk timer2_clk = {
- .name = "timer2",
- .parent = &pll1_sysclk3,
- .flags = ALWAYS_ENABLED, /* no LPSC, always enabled; c.f. spruep9a */
-};
-
-
-static struct clk ide_clk = {
- .name = "ide",
- .parent = &pll1_sysclk4,
- .lpsc = DAVINCI_LPSC_ATA,
-};
-
-static struct clk vpif0_clk = {
- .name = "vpif0",
- .parent = &ref_clk,
- .lpsc = DM646X_LPSC_VPSSMSTR,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk vpif1_clk = {
- .name = "vpif1",
- .parent = &ref_clk,
- .lpsc = DM646X_LPSC_VPSSSLV,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk_lookup dm646x_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "aux", &aux_clkin),
- CLK(NULL, "pll1", &pll1_clk),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk1),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk2),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk3),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk4),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk5),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk6),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk8),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk9),
- CLK(NULL, "pll1_sysclk", &pll1_sysclkbp),
- CLK(NULL, "pll1_aux", &pll1_aux_clk),
- CLK(NULL, "pll2", &pll2_clk),
- CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
- CLK(NULL, "dsp", &dsp_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "edma_cc", &edma_cc_clk),
- CLK(NULL, "edma_tc0", &edma_tc0_clk),
- CLK(NULL, "edma_tc1", &edma_tc1_clk),
- CLK(NULL, "edma_tc2", &edma_tc2_clk),
- CLK(NULL, "edma_tc3", &edma_tc3_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("serial8250.2", NULL, &uart2_clk),
- CLK("i2c_davinci.1", NULL, &i2c_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
- CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
- CLK(NULL, "aemif", &aemif_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &emac_clk),
- CLK(NULL, "pwm0", &pwm0_clk),
- CLK(NULL, "pwm1", &pwm1_clk),
- CLK(NULL, "timer0", &timer0_clk),
- CLK(NULL, "timer1", &timer1_clk),
- CLK("davinci-wdt", NULL, &timer2_clk),
- CLK("palm_bk3710", NULL, &ide_clk),
- CLK(NULL, "vpif0", &vpif0_clk),
- CLK(NULL, "vpif1", &vpif1_clk),
- CLK(NULL, NULL, NULL),
-};
-#endif
-
static struct emac_platform_data dm646x_emac_pdata = {
.ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET,
.ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET,
@@ -801,8 +483,6 @@ static struct davinci_id dm646x_ids[] = {
},
};
-static u32 dm646x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
/*
* T0_BOT: Timer 0, bottom: clockevent source for hrtimers
* T0_TOP: Timer 0, top : clocksource for generic timekeeping
@@ -887,8 +567,6 @@ static const struct davinci_soc_info davinci_soc_info_dm646x = {
.jtag_id_reg = 0x01c40028,
.ids = dm646x_ids,
.ids_num = ARRAY_SIZE(dm646x_ids),
- .psc_bases = dm646x_psc_bases,
- .psc_bases_num = ARRAY_SIZE(dm646x_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
.pinmux_pins = dm646x_pins,
.pinmux_pins_num = ARRAY_SIZE(dm646x_pins),
@@ -959,7 +637,6 @@ void __init dm646x_init(void)
void __init dm646x_init_time(unsigned long ref_clk_rate,
unsigned long aux_clkin_rate)
{
-#ifdef CONFIG_COMMON_CLK
struct clk *clk;
clk = clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, ref_clk_rate);
@@ -968,12 +645,6 @@ void __init dm646x_init_time(unsigned long ref_clk_rate,
clk = clk_register_fixed_rate(NULL, "aux_clkin", NULL, 0, aux_clkin_rate);
clk_register_clkdev(clk, "aux_clkin", "dm646x-psc");
-#else
- ref_clk.rate = ref_clk_rate;
- aux_clkin.rate = aux_clkin_rate;
- davinci_clk_init(dm646x_clks);
- davinci_timer_init(&timer0_clk);
-#endif
}
static struct resource dm646x_pll1_resources[] = {
--
2.7.4
This adds device tree support to the davinci timer so that when clocks
are moved to device tree, the timer will still work.
Signed-off-by: David Lechner <[email protected]>
---
v8 changes:
- none
v7 changes:
- add workaround for platform devices not available in early boot
v6 changes:
- none
arch/arm/mach-davinci/Kconfig | 1 +
arch/arm/mach-davinci/time.c | 31 +++++++++++++++++++++++++++++++
2 files changed, 32 insertions(+)
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index ba9912b..da8a039 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -59,6 +59,7 @@ config MACH_DA8XX_DT
default y
depends on ARCH_DAVINCI_DA850
select PINCTRL
+ select TIMER_OF
help
Say y here to include support for TI DaVinci DA850 based using
Flattened Device Tree. More information at Documentation/devicetree
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index d6a78f7..590b118 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -17,6 +17,7 @@
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/sched_clock.h>
@@ -405,3 +406,33 @@ void __init davinci_timer_init(struct clk *timer_clk)
for (i=0; i< ARRAY_SIZE(timers); i++)
timer32_config(&timers[i]);
}
+
+static int __init of_davinci_timer_init(struct device_node *np)
+{
+ struct clk *clk;
+
+ clk = of_clk_get(np, 0);
+ if (IS_ERR(clk)) {
+ struct of_phandle_args clkspec;
+
+ /*
+ * Fall back to using ref_clk if the actual clock is not
+ * available. This currently always happens because platform
+ * clocks (i.e PLLs and PSCs) are registered as platform
+ * devices and therefore are not available at this point in
+ * the boot process.
+ */
+ clkspec.np = of_find_node_by_name(NULL, "ref_clk");
+ if (IS_ERR(clkspec.np)) {
+ pr_err("%s: No clock available for timer!\n", __func__);
+ return PTR_ERR(clkspec.np);
+ }
+ clk = of_clk_get_from_provider(&clkspec);
+ of_node_put(clkspec.np);
+ }
+
+ davinci_timer_init(clk);
+
+ return 0;
+}
+TIMER_OF_DECLARE(davinci_timer, "ti,davinci-timer", of_davinci_timer_init);
--
2.7.4
This removes the unused legacy clock init code from
arch/arm/mach-davinci/dm355.c.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
---
v8 changes:
- none
v7 changes:
- rebased
- add davinci prefix to commit message
v6 changes:
- rebased
arch/arm/mach-davinci/dm355.c | 357 ------------------------------------------
1 file changed, 357 deletions(-)
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index f53e07a..a2d1246 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -32,11 +32,6 @@
#include "davinci.h"
#include "mux.h"
-#ifndef CONFIG_COMMON_CLK
-#include "clock.h"
-#include "psc.h"
-#endif
-
#define DM355_UART2_BASE (IO_PHYS + 0x206000)
#define DM355_OSD_BASE (IO_PHYS + 0x70200)
#define DM355_VENC_BASE (IO_PHYS + 0x70400)
@@ -46,349 +41,6 @@
*/
#define DM355_REF_FREQ 24000000 /* 24 or 36 MHz */
-#ifndef CONFIG_COMMON_CLK
-static struct pll_data pll1_data = {
- .num = 1,
- .phys_base = DAVINCI_PLL1_BASE,
- .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
-};
-
-static struct pll_data pll2_data = {
- .num = 2,
- .phys_base = DAVINCI_PLL2_BASE,
- .flags = PLL_HAS_PREDIV,
-};
-
-static struct clk ref_clk = {
- .name = "ref_clk",
- /* FIXME -- crystal rate is board-specific */
- .rate = DM355_REF_FREQ,
-};
-
-static struct clk pll1_clk = {
- .name = "pll1",
- .parent = &ref_clk,
- .flags = CLK_PLL,
- .pll_data = &pll1_data,
-};
-
-static struct clk pll1_aux_clk = {
- .name = "pll1_aux_clk",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_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_sysclk4 = {
- .name = "pll1_sysclk4",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV4,
-};
-
-static struct clk pll1_sysclkbp = {
- .name = "pll1_sysclkbp",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
- .div_reg = BPDIV
-};
-
-static struct clk vpss_dac_clk = {
- .name = "vpss_dac",
- .parent = &pll1_sysclk3,
- .lpsc = DM355_LPSC_VPSS_DAC,
-};
-
-static struct clk vpss_master_clk = {
- .name = "vpss_master",
- .parent = &pll1_sysclk4,
- .lpsc = DAVINCI_LPSC_VPSSMSTR,
- .flags = CLK_PSC,
-};
-
-static struct clk vpss_slave_clk = {
- .name = "vpss_slave",
- .parent = &pll1_sysclk4,
- .lpsc = DAVINCI_LPSC_VPSSSLV,
-};
-
-static struct clk clkout1_clk = {
- .name = "clkout1",
- .parent = &pll1_aux_clk,
- /* NOTE: clkout1 can be externally gated by muxing GPIO-18 */
-};
-
-static struct clk clkout2_clk = {
- .name = "clkout2",
- .parent = &pll1_sysclkbp,
-};
-
-static struct clk pll2_clk = {
- .name = "pll2",
- .parent = &ref_clk,
- .flags = CLK_PLL,
- .pll_data = &pll2_data,
-};
-
-static struct clk pll2_sysclk1 = {
- .name = "pll2_sysclk1",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV1,
-};
-
-static struct clk pll2_sysclkbp = {
- .name = "pll2_sysclkbp",
- .parent = &pll2_clk,
- .flags = CLK_PLL | PRE_PLL,
- .div_reg = BPDIV
-};
-
-static struct clk clkout3_clk = {
- .name = "clkout3",
- .parent = &pll2_sysclkbp,
- /* NOTE: clkout3 can be externally gated by muxing GPIO-16 */
-};
-
-static struct clk arm_clk = {
- .name = "arm_clk",
- .parent = &pll1_sysclk1,
- .lpsc = DAVINCI_LPSC_ARM,
- .flags = ALWAYS_ENABLED,
-};
-
-/*
- * NOT LISTED below, and not touched by Linux
- * - in SyncReset state by default
- * .lpsc = DAVINCI_LPSC_TPCC,
- * .lpsc = DAVINCI_LPSC_TPTC0,
- * .lpsc = DAVINCI_LPSC_TPTC1,
- * .lpsc = DAVINCI_LPSC_DDR_EMIF, .parent = &sysclk2_clk,
- * .lpsc = DAVINCI_LPSC_MEMSTICK,
- * - in Enabled state by default
- * .lpsc = DAVINCI_LPSC_SYSTEM_SUBSYS,
- * .lpsc = DAVINCI_LPSC_SCR2, // "bus"
- * .lpsc = DAVINCI_LPSC_SCR3, // "bus"
- * .lpsc = DAVINCI_LPSC_SCR4, // "bus"
- * .lpsc = DAVINCI_LPSC_CROSSBAR, // "emulation"
- * .lpsc = DAVINCI_LPSC_CFG27, // "test"
- * .lpsc = DAVINCI_LPSC_CFG3, // "test"
- * .lpsc = DAVINCI_LPSC_CFG5, // "test"
- */
-
-static struct clk mjcp_clk = {
- .name = "mjcp",
- .parent = &pll1_sysclk1,
- .lpsc = DAVINCI_LPSC_IMCOP,
-};
-
-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_sysclk2,
- .lpsc = DAVINCI_LPSC_UART2,
-};
-
-static struct clk i2c_clk = {
- .name = "i2c",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_I2C,
-};
-
-static struct clk asp0_clk = {
- .name = "asp0",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_McBSP,
-};
-
-static struct clk asp1_clk = {
- .name = "asp1",
- .parent = &pll1_sysclk2,
- .lpsc = DM355_LPSC_McBSP1,
-};
-
-static struct clk mmcsd0_clk = {
- .name = "mmcsd0",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_MMC_SD,
-};
-
-static struct clk mmcsd1_clk = {
- .name = "mmcsd1",
- .parent = &pll1_sysclk2,
- .lpsc = DM355_LPSC_MMC_SD1,
-};
-
-static struct clk spi0_clk = {
- .name = "spi0",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_SPI,
-};
-
-static struct clk spi1_clk = {
- .name = "spi1",
- .parent = &pll1_sysclk2,
- .lpsc = DM355_LPSC_SPI1,
-};
-
-static struct clk spi2_clk = {
- .name = "spi2",
- .parent = &pll1_sysclk2,
- .lpsc = DM355_LPSC_SPI2,
-};
-
-static struct clk gpio_clk = {
- .name = "gpio",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_GPIO,
-};
-
-static struct clk aemif_clk = {
- .name = "aemif",
- .parent = &pll1_sysclk2,
- .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 pwm3_clk = {
- .name = "pwm3",
- .parent = &pll1_aux_clk,
- .lpsc = DM355_LPSC_PWM3,
-};
-
-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 timer3_clk = {
- .name = "timer3",
- .parent = &pll1_aux_clk,
- .lpsc = DM355_LPSC_TIMER3,
-};
-
-static struct clk rto_clk = {
- .name = "rto",
- .parent = &pll1_aux_clk,
- .lpsc = DM355_LPSC_RTO,
-};
-
-static struct clk usb_clk = {
- .name = "usb",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_USB,
-};
-
-static struct clk_lookup dm355_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_sysclk4", &pll1_sysclk4),
- CLK(NULL, "pll1_aux", &pll1_aux_clk),
- CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
- CLK(NULL, "vpss_dac", &vpss_dac_clk),
- CLK("vpss", "master", &vpss_master_clk),
- CLK("vpss", "slave", &vpss_slave_clk),
- CLK(NULL, "clkout1", &clkout1_clk),
- CLK(NULL, "clkout2", &clkout2_clk),
- CLK(NULL, "pll2", &pll2_clk),
- CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
- CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
- CLK(NULL, "clkout3", &clkout3_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "mjcp", &mjcp_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("serial8250.2", NULL, &uart2_clk),
- CLK("i2c_davinci.1", NULL, &i2c_clk),
- CLK("davinci-mcbsp.0", NULL, &asp0_clk),
- CLK("davinci-mcbsp.1", NULL, &asp1_clk),
- CLK("dm6441-mmc.0", NULL, &mmcsd0_clk),
- CLK("dm6441-mmc.1", NULL, &mmcsd1_clk),
- CLK("spi_davinci.0", NULL, &spi0_clk),
- CLK("spi_davinci.1", NULL, &spi1_clk),
- CLK("spi_davinci.2", NULL, &spi2_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK(NULL, "aemif", &aemif_clk),
- CLK(NULL, "pwm0", &pwm0_clk),
- CLK(NULL, "pwm1", &pwm1_clk),
- CLK(NULL, "pwm2", &pwm2_clk),
- CLK(NULL, "pwm3", &pwm3_clk),
- CLK(NULL, "timer0", &timer0_clk),
- CLK(NULL, "timer1", &timer1_clk),
- CLK("davinci-wdt", NULL, &timer2_clk),
- CLK(NULL, "timer3", &timer3_clk),
- CLK(NULL, "rto", &rto_clk),
- CLK(NULL, "usb", &usb_clk),
- CLK(NULL, NULL, NULL),
-};
-#endif
-/*----------------------------------------------------------------------*/
-
static u64 dm355_spi0_dma_mask = DMA_BIT_MASK(32);
static struct resource dm355_spi0_resources[] = {
@@ -930,8 +582,6 @@ static struct davinci_id dm355_ids[] = {
},
};
-static u32 dm355_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
/*
* T0_BOT: Timer 0, bottom: clockevent source for hrtimers
* T0_TOP: Timer 0, top : clocksource for generic timekeeping
@@ -1016,8 +666,6 @@ static const struct davinci_soc_info davinci_soc_info_dm355 = {
.jtag_id_reg = 0x01c40028,
.ids = dm355_ids,
.ids_num = ARRAY_SIZE(dm355_ids),
- .psc_bases = dm355_psc_bases,
- .psc_bases_num = ARRAY_SIZE(dm355_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
.pinmux_pins = dm355_pins,
.pinmux_pins_num = ARRAY_SIZE(dm355_pins),
@@ -1050,16 +698,11 @@ void __init dm355_init(void)
void __init dm355_init_time(void)
{
-#ifdef CONFIG_COMMON_CLK
struct clk *clk;
clk = clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM355_REF_FREQ);
davinci_timer_init(clk);
-#else
- davinci_clk_init(dm355_clks);
- davinci_timer_init(&timer0_clk);
-#endif
}
static struct resource dm355_pll1_resources[] = {
--
2.7.4
This removes the unused legacy clock code from arch/arm/mach-davinci/.
Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
---
v8 changes:
- none
v7 changes:
- none
v6 changes:
- none
arch/arm/mach-davinci/clock.c | 745 ----------------------------
arch/arm/mach-davinci/clock.h | 72 ---
arch/arm/mach-davinci/common.c | 2 -
arch/arm/mach-davinci/devices.c | 1 -
arch/arm/mach-davinci/include/mach/clock.h | 3 -
arch/arm/mach-davinci/include/mach/common.h | 2 -
arch/arm/mach-davinci/psc.c | 137 -----
arch/arm/mach-davinci/psc.h | 10 -
arch/arm/mach-davinci/time.c | 2 -
9 files changed, 974 deletions(-)
delete mode 100644 arch/arm/mach-davinci/clock.c
delete mode 100644 arch/arm/mach-davinci/psc.c
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
deleted file mode 100644
index f77a4f7..0000000
--- a/arch/arm/mach-davinci/clock.c
+++ /dev/null
@@ -1,745 +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 "psc.h"
-#include <mach/cputype.h>
-#include "clock.h"
-
-static LIST_HEAD(clocks);
-static DEFINE_MUTEX(clocks_mutex);
-static DEFINE_SPINLOCK(clockfw_lock);
-
-void davinci_clk_enable(struct clk *clk)
-{
- if (clk->parent)
- davinci_clk_enable(clk->parent);
- if (clk->usecount++ == 0) {
- if (clk->flags & CLK_PSC)
- davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
- true, clk->flags);
- else if (clk->clk_enable)
- clk->clk_enable(clk);
- }
-}
-
-void davinci_clk_disable(struct clk *clk)
-{
- if (WARN_ON(clk->usecount == 0))
- return;
- if (--clk->usecount == 0) {
- if (!(clk->flags & CLK_PLL) && (clk->flags & CLK_PSC))
- davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
- false, clk->flags);
- else if (clk->clk_disable)
- clk->clk_disable(clk);
- }
- if (clk->parent)
- davinci_clk_disable(clk->parent);
-}
-
-int davinci_clk_reset(struct clk *clk, bool reset)
-{
- unsigned long flags;
-
- if (clk == NULL || IS_ERR(clk))
- return -EINVAL;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- if (clk->flags & CLK_PSC)
- davinci_psc_reset(clk->gpsc, clk->lpsc, reset);
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL(davinci_clk_reset);
-
-int davinci_clk_reset_assert(struct clk *clk)
-{
- if (clk == NULL || IS_ERR(clk) || !clk->reset)
- return -EINVAL;
-
- return clk->reset(clk, true);
-}
-EXPORT_SYMBOL(davinci_clk_reset_assert);
-
-int davinci_clk_reset_deassert(struct clk *clk)
-{
- if (clk == NULL || IS_ERR(clk) || !clk->reset)
- return -EINVAL;
-
- return clk->reset(clk, false);
-}
-EXPORT_SYMBOL(davinci_clk_reset_deassert);
-
-int clk_enable(struct clk *clk)
-{
- unsigned long flags;
-
- if (!clk)
- return 0;
- else if (IS_ERR(clk))
- return -EINVAL;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- davinci_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);
- davinci_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 0;
-
- 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 0;
-
- 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)
- return 0;
- else if (IS_ERR(clk))
- return -EINVAL;
-
- 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)
- return 0;
- else if (IS_ERR(clk))
- return -EINVAL;
-
- /* Cannot change parent on enabled clock */
- if (WARN_ON(clk->usecount))
- return -EINVAL;
-
- mutex_lock(&clocks_mutex);
- if (clk->set_parent) {
- int ret = clk->set_parent(clk, parent);
-
- if (ret) {
- mutex_unlock(&clocks_mutex);
- return ret;
- }
- }
- 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);
-
-struct clk *clk_get_parent(struct clk *clk)
-{
- if (!clk)
- return NULL;
-
- return clk->parent;
-}
-EXPORT_SYMBOL(clk_get_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) {
- if (clk->set_parent) {
- int ret = clk->set_parent(clk, clk->parent);
-
- if (ret) {
- mutex_unlock(&clocks_mutex);
- return ret;
- }
- }
- 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_clk_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;
-
- if (clk->flags & PSC_LRST)
- clk->reset = davinci_clk_reset;
-
- 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
index 2d05856..3073834 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -61,76 +61,4 @@
*/
#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);
- int (*reset) (struct clk *clk, bool reset);
- void (*clk_enable) (struct clk *clk);
- void (*clk_disable) (struct clk *clk);
- int (*set_parent) (struct clk *clk, struct clk *parent);
-};
-
-/* 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 PSC_LRST BIT(8) /* Use local reset on enable/disable */
-
-#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);
-int davinci_clk_reset(struct clk *clk, bool reset);
-void davinci_clk_enable(struct clk *clk);
-void davinci_clk_disable(struct clk *clk);
-
-#endif
-
#endif
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
index e03f95c..e1d0f0d 100644
--- a/arch/arm/mach-davinci/common.c
+++ b/arch/arm/mach-davinci/common.c
@@ -20,8 +20,6 @@
#include <mach/common.h>
#include <mach/cputype.h>
-#include "clock.h"
-
struct davinci_soc_info davinci_soc_info;
EXPORT_SYMBOL(davinci_soc_info);
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index 0edda40..e8dbbb7 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -26,7 +26,6 @@
#include "davinci.h"
-#include "clock.h"
#define DAVINCI_I2C_BASE 0x01C21000
#define DAVINCI_ATA_BASE 0x01C66000
diff --git a/arch/arm/mach-davinci/include/mach/clock.h b/arch/arm/mach-davinci/include/mach/clock.h
index 3e8af6a..42ed4f2 100644
--- a/arch/arm/mach-davinci/include/mach/clock.h
+++ b/arch/arm/mach-davinci/include/mach/clock.h
@@ -15,9 +15,6 @@
struct clk;
-extern int clk_register(struct clk *clk);
-extern void clk_unregister(struct clk *clk);
-
int davinci_clk_reset_assert(struct clk *c);
int davinci_clk_reset_deassert(struct clk *c);
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index ded8f5f..b577e13 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -54,8 +54,6 @@ struct davinci_soc_info {
u32 jtag_id_reg;
struct davinci_id *ids;
unsigned long ids_num;
- u32 *psc_bases;
- unsigned long psc_bases_num;
u32 pinmux_base;
const struct mux_config *pinmux_pins;
unsigned long pinmux_pins_num;
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
deleted file mode 100644
index e5dc6bf..0000000
--- a/arch/arm/mach-davinci/psc.c
+++ /dev/null
@@ -1,137 +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 "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_warn("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);
-}
-
-/* Control "reset" line associated with PSC domain */
-void davinci_psc_reset(unsigned int ctlr, unsigned int id, bool reset)
-{
- u32 mdctl;
- void __iomem *psc_base;
- struct davinci_soc_info *soc_info = &davinci_soc_info;
-
- if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
- pr_warn("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);
-
- mdctl = readl(psc_base + MDCTL + 4 * id);
- if (reset)
- mdctl &= ~MDCTL_LRST;
- else
- mdctl |= MDCTL_LRST;
- writel(mdctl, psc_base + MDCTL + 4 * id);
-
- iounmap(psc_base);
-}
-
-/* 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_warn("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/psc.h b/arch/arm/mach-davinci/psc.h
index b58707c..68cd9d3 100644
--- a/arch/arm/mach-davinci/psc.h
+++ b/arch/arm/mach-davinci/psc.h
@@ -204,14 +204,4 @@
#define PDCTL_NEXT BIT(0)
#define PDCTL_EPCGOOD BIT(8)
-#ifndef __ASSEMBLER__
-
-extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
-extern void davinci_psc_reset(unsigned int ctlr, unsigned int id,
- bool reset);
-extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
- unsigned int id, bool enable, u32 flags);
-
-#endif
-
#endif /* __ASM_ARCH_PSC_H */
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 2521333..d6a78f7 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -27,8 +27,6 @@
#include <mach/hardware.h>
#include <mach/time.h>
-#include "clock.h"
-
static struct clock_event_device clockevent_davinci;
static unsigned int davinci_clock_tick_rate;
--
2.7.4
On 03/15/2018 09:52 PM, David Lechner wrote:
> This adds clock provider nodes for da850 and wires them up to all of the
> devices.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
...
This is the mcasp0: mcasp@100000 node...
> @@ -560,6 +720,7 @@
> dmas = <&edma0 1 1>,
> <&edma0 0 1>;
> dma-names = "tx", "rx";
> + clocks = <&psc1 7>;
After some testing, it looks like it needs to be:
+ power-domains = <&psc1 7>;
instead of
+ clocks = <&psc1 7>;
> };
>
> lcdc: display@213000 {
2018-03-16 3:52 GMT+01:00 David Lechner <[email protected]>:
> This series converts mach-davinci to use the common clock framework.
>
> The series works like this, the first 19 patches create new clock drivers
> using the common clock framework. There are basically 3 groups of clocks -
> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each have
> unique init data, which is the reason for so many patches.
>
> Then, starting with "ARM: davinci: pass clock as parameter to
> davinci_timer_init()", we get the mach code ready for the switch by adding the
> code needed for the new clock drivers and adding #ifndef CONFIG_COMMON_CLK
> around the legacy clocks so that we can switch easily between the old and the
> new.
>
> "ARM: davinci: switch to common clock framework" actually flips the switch
> to start using the new clock drivers. Then the next 8 patches remove all
> of the old clock code.
>
> The final three patches add device tree clock support to the one SoC that
> supports it.
>
> This series has been tested on LEGO MINDSTORMS EV3 (device tree) and TI
> OMAP-L138 LCDK (both device tree and legacy board file).
>
Hi David,
thanks, with the u-boot fix everything seems to work fine. I tested
da850-lcdk and da850-evm boards in DT and board file modes.
I'll be working with this series in the following days and will do
some thorough testing and rebase my aemif series on top of it. I'll
also use the recently merged reset support for board files to get rid
of the exported reset functions.
Thanks for your work!
Best regards,
Bartosz Golaszewski
2018-03-19 17:14 GMT+01:00 Bartosz Golaszewski <[email protected]>:
> 2018-03-19 17:11 GMT+01:00 Adam Ford <[email protected]>:
>> On Mon, Mar 19, 2018 at 10:59 AM, David Lechner <[email protected]> wrote:
>>> On 03/19/2018 08:17 AM, Bartosz Golaszewski wrote:
>>>>
>>>> 2018-03-16 3:52 GMT+01:00 David Lechner <[email protected]>:
>>>>>
>>>>> This series converts mach-davinci to use the common clock framework.
>>>>>
>>>>> The series works like this, the first 19 patches create new clock drivers
>>>>> using the common clock framework. There are basically 3 groups of clocks
>>>>> -
>>>>> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each
>>>>> have
>>>>> unique init data, which is the reason for so many patches.
>>>>>
>>>>> Then, starting with "ARM: davinci: pass clock as parameter to
>>>>> davinci_timer_init()", we get the mach code ready for the switch by
>>>>> adding the
>>>>> code needed for the new clock drivers and adding #ifndef
>>>>> CONFIG_COMMON_CLK
>>>>> around the legacy clocks so that we can switch easily between the old and
>>>>> the
>>>>> new.
>>>>>
>>>>> "ARM: davinci: switch to common clock framework" actually flips the
>>>>> switch
>>>>> to start using the new clock drivers. Then the next 8 patches remove all
>>>>> of the old clock code.
>>>>>
>>>>> The final three patches add device tree clock support to the one SoC that
>>>>> supports it.
>>>>>
>>>>> This series has been tested on LEGO MINDSTORMS EV3 (device tree) and TI
>>>>> OMAP-L138 LCDK (both device tree and legacy board file).
>>>>>
>>>>
>>>> Hi David,
>>>>
>>>> thanks, with the u-boot fix everything seems to work fine. I tested
>>>> da850-lcdk and da850-evm boards in DT and board file modes.
>>>>
>>
>> I tested MMC and Ethernet. Both appear to be operating normally, but
>> I have having USB issues.
>>
>> Should I be testing cpufreq? I noticed that when changing the
>> frequencies, the USB appears to stop recognizing connections and
>> disconnections.
>>
>> I did some testing on the DA850-EVM with USB from your repo, and I'm
>> getting some crashing on MUSB unplug that do not appear in the
>> 4.16-RC6 from linux-stable:
>>
>>
>> ------------[ cut here ]------------
>> WARNING: CPU: 0 PID: 13 at drivers/dma/cppi41.c:694
>> cppi41_stop_chan+0x1f4/0x378 [cppi41]
>> Modules linked in: evbug evdev mousedev hid_generic usbhid hid
>> usb_f_ss_lb g_zero libcomposite configfs ofpart cmdlinepart m25p80
>> spi_nor cppi41 adv7343 tvp514x vpif_display vpif_capture
>> videobuf2_dma_con
>> tig videobuf2_memops videobuf2_v4l2 videobuf2_common v4l2_fwnode
>> v4l2_common snd_soc_simple_card tilcdc spi_davinci
>> snd_soc_simple_card_utils videodev pwm_tiecap spi_bitbang da8xx
>> drm_kms_helper phy_gener
>> ic syscopyarea ohci_da8xx musb_hdrc sysfillrect sysimgblt fb_sys_fops
>> ohci_hcd udc_core drm usbcore drm_panel_orientation_quirks usb_common
>> snd_soc_tlv320aic3x vpif snd_soc_davinci_mcasp snd_soc_edma snd_
>> soc_core snd_pcm_dmaengine snd_pcm rtc_omap snd_timer snd soundcore
>> phy_da8xx_usb davinci_nand nand nand_ecc mtd pwm_bl backlight
>> cpufreq_dt ti_aemif
>> CPU: 0 PID: 13 Comm: kworker/0:1 Not tainted 4.16.0-rc5-g291ba8b-dirty #3
>> Hardware name: Generic DA850/OMAP-L138/AM18x
>> Workqueue: usb_hub_wq hub_event [usbcore]
>> Backtrace:
>> [<c000df94>] (dump_backtrace) from [<c000e264>] (show_stack+0x18/0x1c)
>> r7:00000009 r6:00000000 r5:bf339ad0 r4:00000000
>> [<c000e24c>] (show_stack) from [<c04864c0>] (dump_stack+0x20/0x28)
>> [<c04864a0>] (dump_stack) from [<c001ac38>] (__warn+0xd4/0xfc)
>> [<c001ab64>] (__warn) from [<c001ad7c>] (warn_slowpath_null+0x44/0x50)
>> r8:c6c43080 r7:c05f1008 r6:bf338744 r5:000002b6 r4:bf339ad0
>> [<c001ad38>] (warn_slowpath_null) from [<bf338744>]
>> (cppi41_stop_chan+0x1f4/0x378 [cppi41])
>> r6:c5e59410 r5:c5e59420 r4:c5feca50
>> [<bf338550>] (cppi41_stop_chan [cppi41]) from [<bf213dac>]
>> (cppi41_dma_channel_abort+0xe0/0x2a8 [musb_hdrc])
>> r8:c6929180 r7:00000000 r6:c5c67290 r5:bf2175a0 r4:00000008
>> [<bf213ccc>] (cppi41_dma_channel_abort [musb_hdrc]) from [<bf20c4bc>]
>> (musb_cleanup_urb+0x60/0x210 [musb_hdrc])
>> r10:00000001 r9:c5fca010 r8:c5c67290 r7:a0000093 r6:00000080 r5:c55b5100
>> r4:c5fca5a8
>> [<bf20c45c>] (musb_cleanup_urb [musb_hdrc]) from [<bf20ca8c>]
>> (musb_urb_dequeue+0xfc/0x164 [musb_hdrc])
>> r10:00000001 r9:40408280 r8:c5fca010 r7:a0000093 r6:00000000 r5:c55b5380
>> r4:c55b5100
>> [<bf20c990>] (musb_urb_dequeue [musb_hdrc]) from [<bf10fd7c>]
>> (unlink1+0x34/0x13c [usbcore])
>> r10:00000100 r9:c5cb2a00 r8:c55b5100 r7:ffffff94 r6:c5c6c000 r5:c5dd2380
>> r4:c55b5100 r3:bf20c990
>> [<bf10fd48>] (unlink1 [usbcore]) from [<bf112424>]
>> (usb_hcd_flush_endpoint+0x164/0x1a4 [usbcore])
>> r9:c5cb2a00 r8:c55b5100 r7:c5c6c000 r6:c5dd2398 r5:c5dd2380 r4:ffffe000
>> [<bf1122c0>] (usb_hcd_flush_endpoint [usbcore]) from [<bf11563c>]
>> (usb_disable_endpoint+0x50/0x94 [usbcore])
>> r9:c5cb2a00 r8:bf39e898 r7:00000000 r6:c5c43000 r5:c5c43000 r4:c5dd2380
>> [<bf1155ec>] (usb_disable_endpoint [usbcore]) from [<bf1156c4>]
>> (usb_disable_interface+0x44/0x58 [usbcore])
>> r5:c5dd2348 r4:00000000
>> [<bf115680>] (usb_disable_interface [usbcore]) from [<bf118044>]
>> (usb_unbind_interface+0x1c0/0x268 [usbcore])
>> r7:c5cb2c00 r6:bf39e898 r5:c5cb2c20 r4:c5cb2c20
>> [<bf117e84>] (usb_unbind_interface [usbcore]) from [<c02ce180>]
>> (device_release_driver_internal+0x160/0x208)
>> r10:00000100 r9:c5cb2a00 r8:00000034 r7:00000000 r6:bf39e898 r5:c5cb2c54
>> r4:c5cb2c20
>> [<c02ce020>] (device_release_driver_internal) from [<c02ce240>]
>> (device_release_driver+0x18/0x1c)
>> r9:c5cb2a00 r8:c05f1008 r7:c5c43070 r6:bf12895c r5:c5cb2c20 r4:c5dc91ac
>> [<c02ce228>] (device_release_driver) from [<c02ccf70>]
>> (bus_remove_device+0xd0/0x100)
>> [<c02ccea0>] (bus_remove_device) from [<c02c9c60>] (device_del+0x120/0x378)
>> r7:c5c43070 r6:c5cb2c28 r5:00000000 r4:c5cb2c20
>> [<c02c9b40>] (device_del) from [<bf11576c>]
>> (usb_disable_device+0x94/0x1d8 [usbcore])
>> r10:00000100 r9:c5cb2a00 r8:c5cb2c00 r7:c5c6c000 r6:00000001 r5:00000000
>> r4:c5c43000
>> [<bf1156d8>] (usb_disable_device [usbcore]) from [<bf10bccc>]
>> (usb_disconnect+0xb4/0x244 [usbcore])
>> r9:c5cb2a00 r8:c5c2d600 r7:c5c430a4 r6:c5c43070 r5:c5c43000 r4:00000000
>> [<bf10bc18>] (usb_disconnect [usbcore]) from [<bf10d788>]
>> (hub_event+0x678/0x11dc [usbcore])
>> r10:00000100 r9:c05f1008 r8:c5c2dcf8 r7:c68fc400 r6:00000001 r5:40000000
>> r4:00000000
>> [<bf10d110>] (hub_event [usbcore]) from [<c0031db0>]
>> (process_one_work+0x1d8/0x41c)
>> r10:00000008 r9:00000000 r8:c060b1d0 r7:00000000 r6:c7ede200 r5:c6882480
>> r4:c5c2dcf8
>> [<c0031bd8>] (process_one_work) from [<c0032030>] (worker_thread+0x3c/0x670)
>> r10:00000008 r9:c060b1e4 r8:c061ab60 r7:c6882498 r6:ffffe000 r5:c060b1d0
>> r4:c6882480
>> [<c0031ff4>] (worker_thread) from [<c0038270>] (kthread+0x134/0x14c)
>> r10:c683fe90 r9:c0031ff4 r8:c6882480 r7:c6896000 r6:00000000 r5:c687bd80
>> r4:c6803e80
>> [<c003813c>] (kthread) from [<c00090e0>] (ret_from_fork+0x14/0x34)
>> Exception stack(0xc6897fb0 to 0xc6897ff8)
>> 7fa0: 00000000 00000000 00000000 00000000
>> 7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
>> 7fe0: 00000000 00000000 00000000 00000000 00000013 00000000
>> r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c003813c
>> r4:c687bd80
>> ---[ end trace cb9c7f93aaa3ed36 ]---
>> ------------[ cut here ]------------
>>
>>
>> adam
>>
>
> Hi Adam,
>
> this is a known issue and it's present in mainline and even in TI BSP.
> It's been deprioritized for now, but I'll return to debugging it once
> the common clock conversion is complete.
>
> Thanks,
> Bartosz
Ugh, -ETOOEARLY
I meant the ohci dying during cpufreq bug, not the crash you posted.
Bart
2018-03-19 17:11 GMT+01:00 Adam Ford <[email protected]>:
> On Mon, Mar 19, 2018 at 10:59 AM, David Lechner <[email protected]> wrote:
>> On 03/19/2018 08:17 AM, Bartosz Golaszewski wrote:
>>>
>>> 2018-03-16 3:52 GMT+01:00 David Lechner <[email protected]>:
>>>>
>>>> This series converts mach-davinci to use the common clock framework.
>>>>
>>>> The series works like this, the first 19 patches create new clock drivers
>>>> using the common clock framework. There are basically 3 groups of clocks
>>>> -
>>>> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each
>>>> have
>>>> unique init data, which is the reason for so many patches.
>>>>
>>>> Then, starting with "ARM: davinci: pass clock as parameter to
>>>> davinci_timer_init()", we get the mach code ready for the switch by
>>>> adding the
>>>> code needed for the new clock drivers and adding #ifndef
>>>> CONFIG_COMMON_CLK
>>>> around the legacy clocks so that we can switch easily between the old and
>>>> the
>>>> new.
>>>>
>>>> "ARM: davinci: switch to common clock framework" actually flips the
>>>> switch
>>>> to start using the new clock drivers. Then the next 8 patches remove all
>>>> of the old clock code.
>>>>
>>>> The final three patches add device tree clock support to the one SoC that
>>>> supports it.
>>>>
>>>> This series has been tested on LEGO MINDSTORMS EV3 (device tree) and TI
>>>> OMAP-L138 LCDK (both device tree and legacy board file).
>>>>
>>>
>>> Hi David,
>>>
>>> thanks, with the u-boot fix everything seems to work fine. I tested
>>> da850-lcdk and da850-evm boards in DT and board file modes.
>>>
>
> I tested MMC and Ethernet. Both appear to be operating normally, but
> I have having USB issues.
>
> Should I be testing cpufreq? I noticed that when changing the
> frequencies, the USB appears to stop recognizing connections and
> disconnections.
>
> I did some testing on the DA850-EVM with USB from your repo, and I'm
> getting some crashing on MUSB unplug that do not appear in the
> 4.16-RC6 from linux-stable:
>
>
> ------------[ cut here ]------------
> WARNING: CPU: 0 PID: 13 at drivers/dma/cppi41.c:694
> cppi41_stop_chan+0x1f4/0x378 [cppi41]
> Modules linked in: evbug evdev mousedev hid_generic usbhid hid
> usb_f_ss_lb g_zero libcomposite configfs ofpart cmdlinepart m25p80
> spi_nor cppi41 adv7343 tvp514x vpif_display vpif_capture
> videobuf2_dma_con
> tig videobuf2_memops videobuf2_v4l2 videobuf2_common v4l2_fwnode
> v4l2_common snd_soc_simple_card tilcdc spi_davinci
> snd_soc_simple_card_utils videodev pwm_tiecap spi_bitbang da8xx
> drm_kms_helper phy_gener
> ic syscopyarea ohci_da8xx musb_hdrc sysfillrect sysimgblt fb_sys_fops
> ohci_hcd udc_core drm usbcore drm_panel_orientation_quirks usb_common
> snd_soc_tlv320aic3x vpif snd_soc_davinci_mcasp snd_soc_edma snd_
> soc_core snd_pcm_dmaengine snd_pcm rtc_omap snd_timer snd soundcore
> phy_da8xx_usb davinci_nand nand nand_ecc mtd pwm_bl backlight
> cpufreq_dt ti_aemif
> CPU: 0 PID: 13 Comm: kworker/0:1 Not tainted 4.16.0-rc5-g291ba8b-dirty #3
> Hardware name: Generic DA850/OMAP-L138/AM18x
> Workqueue: usb_hub_wq hub_event [usbcore]
> Backtrace:
> [<c000df94>] (dump_backtrace) from [<c000e264>] (show_stack+0x18/0x1c)
> r7:00000009 r6:00000000 r5:bf339ad0 r4:00000000
> [<c000e24c>] (show_stack) from [<c04864c0>] (dump_stack+0x20/0x28)
> [<c04864a0>] (dump_stack) from [<c001ac38>] (__warn+0xd4/0xfc)
> [<c001ab64>] (__warn) from [<c001ad7c>] (warn_slowpath_null+0x44/0x50)
> r8:c6c43080 r7:c05f1008 r6:bf338744 r5:000002b6 r4:bf339ad0
> [<c001ad38>] (warn_slowpath_null) from [<bf338744>]
> (cppi41_stop_chan+0x1f4/0x378 [cppi41])
> r6:c5e59410 r5:c5e59420 r4:c5feca50
> [<bf338550>] (cppi41_stop_chan [cppi41]) from [<bf213dac>]
> (cppi41_dma_channel_abort+0xe0/0x2a8 [musb_hdrc])
> r8:c6929180 r7:00000000 r6:c5c67290 r5:bf2175a0 r4:00000008
> [<bf213ccc>] (cppi41_dma_channel_abort [musb_hdrc]) from [<bf20c4bc>]
> (musb_cleanup_urb+0x60/0x210 [musb_hdrc])
> r10:00000001 r9:c5fca010 r8:c5c67290 r7:a0000093 r6:00000080 r5:c55b5100
> r4:c5fca5a8
> [<bf20c45c>] (musb_cleanup_urb [musb_hdrc]) from [<bf20ca8c>]
> (musb_urb_dequeue+0xfc/0x164 [musb_hdrc])
> r10:00000001 r9:40408280 r8:c5fca010 r7:a0000093 r6:00000000 r5:c55b5380
> r4:c55b5100
> [<bf20c990>] (musb_urb_dequeue [musb_hdrc]) from [<bf10fd7c>]
> (unlink1+0x34/0x13c [usbcore])
> r10:00000100 r9:c5cb2a00 r8:c55b5100 r7:ffffff94 r6:c5c6c000 r5:c5dd2380
> r4:c55b5100 r3:bf20c990
> [<bf10fd48>] (unlink1 [usbcore]) from [<bf112424>]
> (usb_hcd_flush_endpoint+0x164/0x1a4 [usbcore])
> r9:c5cb2a00 r8:c55b5100 r7:c5c6c000 r6:c5dd2398 r5:c5dd2380 r4:ffffe000
> [<bf1122c0>] (usb_hcd_flush_endpoint [usbcore]) from [<bf11563c>]
> (usb_disable_endpoint+0x50/0x94 [usbcore])
> r9:c5cb2a00 r8:bf39e898 r7:00000000 r6:c5c43000 r5:c5c43000 r4:c5dd2380
> [<bf1155ec>] (usb_disable_endpoint [usbcore]) from [<bf1156c4>]
> (usb_disable_interface+0x44/0x58 [usbcore])
> r5:c5dd2348 r4:00000000
> [<bf115680>] (usb_disable_interface [usbcore]) from [<bf118044>]
> (usb_unbind_interface+0x1c0/0x268 [usbcore])
> r7:c5cb2c00 r6:bf39e898 r5:c5cb2c20 r4:c5cb2c20
> [<bf117e84>] (usb_unbind_interface [usbcore]) from [<c02ce180>]
> (device_release_driver_internal+0x160/0x208)
> r10:00000100 r9:c5cb2a00 r8:00000034 r7:00000000 r6:bf39e898 r5:c5cb2c54
> r4:c5cb2c20
> [<c02ce020>] (device_release_driver_internal) from [<c02ce240>]
> (device_release_driver+0x18/0x1c)
> r9:c5cb2a00 r8:c05f1008 r7:c5c43070 r6:bf12895c r5:c5cb2c20 r4:c5dc91ac
> [<c02ce228>] (device_release_driver) from [<c02ccf70>]
> (bus_remove_device+0xd0/0x100)
> [<c02ccea0>] (bus_remove_device) from [<c02c9c60>] (device_del+0x120/0x378)
> r7:c5c43070 r6:c5cb2c28 r5:00000000 r4:c5cb2c20
> [<c02c9b40>] (device_del) from [<bf11576c>]
> (usb_disable_device+0x94/0x1d8 [usbcore])
> r10:00000100 r9:c5cb2a00 r8:c5cb2c00 r7:c5c6c000 r6:00000001 r5:00000000
> r4:c5c43000
> [<bf1156d8>] (usb_disable_device [usbcore]) from [<bf10bccc>]
> (usb_disconnect+0xb4/0x244 [usbcore])
> r9:c5cb2a00 r8:c5c2d600 r7:c5c430a4 r6:c5c43070 r5:c5c43000 r4:00000000
> [<bf10bc18>] (usb_disconnect [usbcore]) from [<bf10d788>]
> (hub_event+0x678/0x11dc [usbcore])
> r10:00000100 r9:c05f1008 r8:c5c2dcf8 r7:c68fc400 r6:00000001 r5:40000000
> r4:00000000
> [<bf10d110>] (hub_event [usbcore]) from [<c0031db0>]
> (process_one_work+0x1d8/0x41c)
> r10:00000008 r9:00000000 r8:c060b1d0 r7:00000000 r6:c7ede200 r5:c6882480
> r4:c5c2dcf8
> [<c0031bd8>] (process_one_work) from [<c0032030>] (worker_thread+0x3c/0x670)
> r10:00000008 r9:c060b1e4 r8:c061ab60 r7:c6882498 r6:ffffe000 r5:c060b1d0
> r4:c6882480
> [<c0031ff4>] (worker_thread) from [<c0038270>] (kthread+0x134/0x14c)
> r10:c683fe90 r9:c0031ff4 r8:c6882480 r7:c6896000 r6:00000000 r5:c687bd80
> r4:c6803e80
> [<c003813c>] (kthread) from [<c00090e0>] (ret_from_fork+0x14/0x34)
> Exception stack(0xc6897fb0 to 0xc6897ff8)
> 7fa0: 00000000 00000000 00000000 00000000
> 7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 7fe0: 00000000 00000000 00000000 00000000 00000013 00000000
> r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c003813c
> r4:c687bd80
> ---[ end trace cb9c7f93aaa3ed36 ]---
> ------------[ cut here ]------------
>
>
> adam
>
Hi Adam,
this is a known issue and it's present in mainline and even in TI BSP.
It's been deprioritized for now, but I'll return to debugging it once
the common clock conversion is complete.
Thanks,
Bartosz
On 03/19/2018 11:11 AM, Adam Ford wrote:
> On Mon, Mar 19, 2018 at 10:59 AM, David Lechner <[email protected]> wrote:
>> On 03/19/2018 08:17 AM, Bartosz Golaszewski wrote:
>>>
>>> 2018-03-16 3:52 GMT+01:00 David Lechner <[email protected]>:
>>>>
>>>> This series converts mach-davinci to use the common clock framework.
>>>>
>>>> The series works like this, the first 19 patches create new clock drivers
>>>> using the common clock framework. There are basically 3 groups of clocks
>>>> -
>>>> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each
>>>> have
>>>> unique init data, which is the reason for so many patches.
>>>>
>>>> Then, starting with "ARM: davinci: pass clock as parameter to
>>>> davinci_timer_init()", we get the mach code ready for the switch by
>>>> adding the
>>>> code needed for the new clock drivers and adding #ifndef
>>>> CONFIG_COMMON_CLK
>>>> around the legacy clocks so that we can switch easily between the old and
>>>> the
>>>> new.
>>>>
>>>> "ARM: davinci: switch to common clock framework" actually flips the
>>>> switch
>>>> to start using the new clock drivers. Then the next 8 patches remove all
>>>> of the old clock code.
>>>>
>>>> The final three patches add device tree clock support to the one SoC that
>>>> supports it.
>>>>
>>>> This series has been tested on LEGO MINDSTORMS EV3 (device tree) and TI
>>>> OMAP-L138 LCDK (both device tree and legacy board file).
>>>>
>>>
>>> Hi David,
>>>
>>> thanks, with the u-boot fix everything seems to work fine. I tested
>>> da850-lcdk and da850-evm boards in DT and board file modes.
>>>
>
> I tested MMC and Ethernet. Both appear to be operating normally, but
> I have having USB issues.
>
> Should I be testing cpufreq? I noticed that when changing the
> frequencies, the USB appears to stop recognizing connections and
> disconnections.
>
> I did some testing on the DA850-EVM with USB from your repo, and I'm
> getting some crashing on MUSB unplug that do not appear in the
> 4.16-RC6 from linux-stable:
>
>
> ------------[ cut here ]------------
> WARNING: CPU: 0 PID: 13 at drivers/dma/cppi41.c:694
> cppi41_stop_chan+0x1f4/0x378 [cppi41]
> Modules linked in: evbug evdev mousedev hid_generic usbhid hid
> usb_f_ss_lb g_zero libcomposite configfs ofpart cmdlinepart m25p80
> spi_nor cppi41 adv7343 tvp514x vpif_display vpif_capture
> videobuf2_dma_con
> tig videobuf2_memops videobuf2_v4l2 videobuf2_common v4l2_fwnode
> v4l2_common snd_soc_simple_card tilcdc spi_davinci
> snd_soc_simple_card_utils videodev pwm_tiecap spi_bitbang da8xx
> drm_kms_helper phy_gener
> ic syscopyarea ohci_da8xx musb_hdrc sysfillrect sysimgblt fb_sys_fops
> ohci_hcd udc_core drm usbcore drm_panel_orientation_quirks usb_common
> snd_soc_tlv320aic3x vpif snd_soc_davinci_mcasp snd_soc_edma snd_
> soc_core snd_pcm_dmaengine snd_pcm rtc_omap snd_timer snd soundcore
> phy_da8xx_usb davinci_nand nand nand_ecc mtd pwm_bl backlight
> cpufreq_dt ti_aemif
> CPU: 0 PID: 13 Comm: kworker/0:1 Not tainted 4.16.0-rc5-g291ba8b-dirty #3
> Hardware name: Generic DA850/OMAP-L138/AM18x
> Workqueue: usb_hub_wq hub_event [usbcore]
> Backtrace:
> [<c000df94>] (dump_backtrace) from [<c000e264>] (show_stack+0x18/0x1c)
> r7:00000009 r6:00000000 r5:bf339ad0 r4:00000000
> [<c000e24c>] (show_stack) from [<c04864c0>] (dump_stack+0x20/0x28)
> [<c04864a0>] (dump_stack) from [<c001ac38>] (__warn+0xd4/0xfc)
> [<c001ab64>] (__warn) from [<c001ad7c>] (warn_slowpath_null+0x44/0x50)
> r8:c6c43080 r7:c05f1008 r6:bf338744 r5:000002b6 r4:bf339ad0
> [<c001ad38>] (warn_slowpath_null) from [<bf338744>]
> (cppi41_stop_chan+0x1f4/0x378 [cppi41])
> r6:c5e59410 r5:c5e59420 r4:c5feca50
> [<bf338550>] (cppi41_stop_chan [cppi41]) from [<bf213dac>]
> (cppi41_dma_channel_abort+0xe0/0x2a8 [musb_hdrc])
> r8:c6929180 r7:00000000 r6:c5c67290 r5:bf2175a0 r4:00000008
> [<bf213ccc>] (cppi41_dma_channel_abort [musb_hdrc]) from [<bf20c4bc>]
> (musb_cleanup_urb+0x60/0x210 [musb_hdrc])
> r10:00000001 r9:c5fca010 r8:c5c67290 r7:a0000093 r6:00000080 r5:c55b5100
> r4:c5fca5a8
> [<bf20c45c>] (musb_cleanup_urb [musb_hdrc]) from [<bf20ca8c>]
> (musb_urb_dequeue+0xfc/0x164 [musb_hdrc])
> r10:00000001 r9:40408280 r8:c5fca010 r7:a0000093 r6:00000000 r5:c55b5380
> r4:c55b5100
> [<bf20c990>] (musb_urb_dequeue [musb_hdrc]) from [<bf10fd7c>]
> (unlink1+0x34/0x13c [usbcore])
> r10:00000100 r9:c5cb2a00 r8:c55b5100 r7:ffffff94 r6:c5c6c000 r5:c5dd2380
> r4:c55b5100 r3:bf20c990
> [<bf10fd48>] (unlink1 [usbcore]) from [<bf112424>]
> (usb_hcd_flush_endpoint+0x164/0x1a4 [usbcore])
> r9:c5cb2a00 r8:c55b5100 r7:c5c6c000 r6:c5dd2398 r5:c5dd2380 r4:ffffe000
> [<bf1122c0>] (usb_hcd_flush_endpoint [usbcore]) from [<bf11563c>]
> (usb_disable_endpoint+0x50/0x94 [usbcore])
> r9:c5cb2a00 r8:bf39e898 r7:00000000 r6:c5c43000 r5:c5c43000 r4:c5dd2380
> [<bf1155ec>] (usb_disable_endpoint [usbcore]) from [<bf1156c4>]
> (usb_disable_interface+0x44/0x58 [usbcore])
> r5:c5dd2348 r4:00000000
> [<bf115680>] (usb_disable_interface [usbcore]) from [<bf118044>]
> (usb_unbind_interface+0x1c0/0x268 [usbcore])
> r7:c5cb2c00 r6:bf39e898 r5:c5cb2c20 r4:c5cb2c20
> [<bf117e84>] (usb_unbind_interface [usbcore]) from [<c02ce180>]
> (device_release_driver_internal+0x160/0x208)
> r10:00000100 r9:c5cb2a00 r8:00000034 r7:00000000 r6:bf39e898 r5:c5cb2c54
> r4:c5cb2c20
> [<c02ce020>] (device_release_driver_internal) from [<c02ce240>]
> (device_release_driver+0x18/0x1c)
> r9:c5cb2a00 r8:c05f1008 r7:c5c43070 r6:bf12895c r5:c5cb2c20 r4:c5dc91ac
> [<c02ce228>] (device_release_driver) from [<c02ccf70>]
> (bus_remove_device+0xd0/0x100)
> [<c02ccea0>] (bus_remove_device) from [<c02c9c60>] (device_del+0x120/0x378)
> r7:c5c43070 r6:c5cb2c28 r5:00000000 r4:c5cb2c20
> [<c02c9b40>] (device_del) from [<bf11576c>]
> (usb_disable_device+0x94/0x1d8 [usbcore])
> r10:00000100 r9:c5cb2a00 r8:c5cb2c00 r7:c5c6c000 r6:00000001 r5:00000000
> r4:c5c43000
> [<bf1156d8>] (usb_disable_device [usbcore]) from [<bf10bccc>]
> (usb_disconnect+0xb4/0x244 [usbcore])
> r9:c5cb2a00 r8:c5c2d600 r7:c5c430a4 r6:c5c43070 r5:c5c43000 r4:00000000
> [<bf10bc18>] (usb_disconnect [usbcore]) from [<bf10d788>]
> (hub_event+0x678/0x11dc [usbcore])
> r10:00000100 r9:c05f1008 r8:c5c2dcf8 r7:c68fc400 r6:00000001 r5:40000000
> r4:00000000
> [<bf10d110>] (hub_event [usbcore]) from [<c0031db0>]
> (process_one_work+0x1d8/0x41c)
> r10:00000008 r9:00000000 r8:c060b1d0 r7:00000000 r6:c7ede200 r5:c6882480
> r4:c5c2dcf8
> [<c0031bd8>] (process_one_work) from [<c0032030>] (worker_thread+0x3c/0x670)
> r10:00000008 r9:c060b1e4 r8:c061ab60 r7:c6882498 r6:ffffe000 r5:c060b1d0
> r4:c6882480
> [<c0031ff4>] (worker_thread) from [<c0038270>] (kthread+0x134/0x14c)
> r10:c683fe90 r9:c0031ff4 r8:c6882480 r7:c6896000 r6:00000000 r5:c687bd80
> r4:c6803e80
> [<c003813c>] (kthread) from [<c00090e0>] (ret_from_fork+0x14/0x34)
> Exception stack(0xc6897fb0 to 0xc6897ff8)
> 7fa0: 00000000 00000000 00000000 00000000
> 7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 7fe0: 00000000 00000000 00000000 00000000 00000013 00000000
> r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c003813c
> r4:c687bd80
> ---[ end trace cb9c7f93aaa3ed36 ]---
> ------------[ cut here ]------------
>
>
Hi Alexandre,
Do you have any insight on this error? I seem to recall something like this
when you were working on DA8xx MUSB last year.
I am wondering if this warning should be a warning in the kernel since it
seems like stopping CPPI when you unplug a cable even if it is busy is a
legitimate thing to do.
On Mon, Mar 19, 2018 at 10:59 AM, David Lechner <[email protected]> wrote:
> On 03/19/2018 08:17 AM, Bartosz Golaszewski wrote:
>>
>> 2018-03-16 3:52 GMT+01:00 David Lechner <[email protected]>:
>>>
>>> This series converts mach-davinci to use the common clock framework.
>>>
>>> The series works like this, the first 19 patches create new clock drivers
>>> using the common clock framework. There are basically 3 groups of clocks
>>> -
>>> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each
>>> have
>>> unique init data, which is the reason for so many patches.
>>>
>>> Then, starting with "ARM: davinci: pass clock as parameter to
>>> davinci_timer_init()", we get the mach code ready for the switch by
>>> adding the
>>> code needed for the new clock drivers and adding #ifndef
>>> CONFIG_COMMON_CLK
>>> around the legacy clocks so that we can switch easily between the old and
>>> the
>>> new.
>>>
>>> "ARM: davinci: switch to common clock framework" actually flips the
>>> switch
>>> to start using the new clock drivers. Then the next 8 patches remove all
>>> of the old clock code.
>>>
>>> The final three patches add device tree clock support to the one SoC that
>>> supports it.
>>>
>>> This series has been tested on LEGO MINDSTORMS EV3 (device tree) and TI
>>> OMAP-L138 LCDK (both device tree and legacy board file).
>>>
>>
>> Hi David,
>>
>> thanks, with the u-boot fix everything seems to work fine. I tested
>> da850-lcdk and da850-evm boards in DT and board file modes.
>>
I tested MMC and Ethernet. Both appear to be operating normally, but
I have having USB issues.
Should I be testing cpufreq? I noticed that when changing the
frequencies, the USB appears to stop recognizing connections and
disconnections.
I did some testing on the DA850-EVM with USB from your repo, and I'm
getting some crashing on MUSB unplug that do not appear in the
4.16-RC6 from linux-stable:
------------[ cut here ]------------
WARNING: CPU: 0 PID: 13 at drivers/dma/cppi41.c:694
cppi41_stop_chan+0x1f4/0x378 [cppi41]
Modules linked in: evbug evdev mousedev hid_generic usbhid hid
usb_f_ss_lb g_zero libcomposite configfs ofpart cmdlinepart m25p80
spi_nor cppi41 adv7343 tvp514x vpif_display vpif_capture
videobuf2_dma_con
tig videobuf2_memops videobuf2_v4l2 videobuf2_common v4l2_fwnode
v4l2_common snd_soc_simple_card tilcdc spi_davinci
snd_soc_simple_card_utils videodev pwm_tiecap spi_bitbang da8xx
drm_kms_helper phy_gener
ic syscopyarea ohci_da8xx musb_hdrc sysfillrect sysimgblt fb_sys_fops
ohci_hcd udc_core drm usbcore drm_panel_orientation_quirks usb_common
snd_soc_tlv320aic3x vpif snd_soc_davinci_mcasp snd_soc_edma snd_
soc_core snd_pcm_dmaengine snd_pcm rtc_omap snd_timer snd soundcore
phy_da8xx_usb davinci_nand nand nand_ecc mtd pwm_bl backlight
cpufreq_dt ti_aemif
CPU: 0 PID: 13 Comm: kworker/0:1 Not tainted 4.16.0-rc5-g291ba8b-dirty #3
Hardware name: Generic DA850/OMAP-L138/AM18x
Workqueue: usb_hub_wq hub_event [usbcore]
Backtrace:
[<c000df94>] (dump_backtrace) from [<c000e264>] (show_stack+0x18/0x1c)
r7:00000009 r6:00000000 r5:bf339ad0 r4:00000000
[<c000e24c>] (show_stack) from [<c04864c0>] (dump_stack+0x20/0x28)
[<c04864a0>] (dump_stack) from [<c001ac38>] (__warn+0xd4/0xfc)
[<c001ab64>] (__warn) from [<c001ad7c>] (warn_slowpath_null+0x44/0x50)
r8:c6c43080 r7:c05f1008 r6:bf338744 r5:000002b6 r4:bf339ad0
[<c001ad38>] (warn_slowpath_null) from [<bf338744>]
(cppi41_stop_chan+0x1f4/0x378 [cppi41])
r6:c5e59410 r5:c5e59420 r4:c5feca50
[<bf338550>] (cppi41_stop_chan [cppi41]) from [<bf213dac>]
(cppi41_dma_channel_abort+0xe0/0x2a8 [musb_hdrc])
r8:c6929180 r7:00000000 r6:c5c67290 r5:bf2175a0 r4:00000008
[<bf213ccc>] (cppi41_dma_channel_abort [musb_hdrc]) from [<bf20c4bc>]
(musb_cleanup_urb+0x60/0x210 [musb_hdrc])
r10:00000001 r9:c5fca010 r8:c5c67290 r7:a0000093 r6:00000080 r5:c55b5100
r4:c5fca5a8
[<bf20c45c>] (musb_cleanup_urb [musb_hdrc]) from [<bf20ca8c>]
(musb_urb_dequeue+0xfc/0x164 [musb_hdrc])
r10:00000001 r9:40408280 r8:c5fca010 r7:a0000093 r6:00000000 r5:c55b5380
r4:c55b5100
[<bf20c990>] (musb_urb_dequeue [musb_hdrc]) from [<bf10fd7c>]
(unlink1+0x34/0x13c [usbcore])
r10:00000100 r9:c5cb2a00 r8:c55b5100 r7:ffffff94 r6:c5c6c000 r5:c5dd2380
r4:c55b5100 r3:bf20c990
[<bf10fd48>] (unlink1 [usbcore]) from [<bf112424>]
(usb_hcd_flush_endpoint+0x164/0x1a4 [usbcore])
r9:c5cb2a00 r8:c55b5100 r7:c5c6c000 r6:c5dd2398 r5:c5dd2380 r4:ffffe000
[<bf1122c0>] (usb_hcd_flush_endpoint [usbcore]) from [<bf11563c>]
(usb_disable_endpoint+0x50/0x94 [usbcore])
r9:c5cb2a00 r8:bf39e898 r7:00000000 r6:c5c43000 r5:c5c43000 r4:c5dd2380
[<bf1155ec>] (usb_disable_endpoint [usbcore]) from [<bf1156c4>]
(usb_disable_interface+0x44/0x58 [usbcore])
r5:c5dd2348 r4:00000000
[<bf115680>] (usb_disable_interface [usbcore]) from [<bf118044>]
(usb_unbind_interface+0x1c0/0x268 [usbcore])
r7:c5cb2c00 r6:bf39e898 r5:c5cb2c20 r4:c5cb2c20
[<bf117e84>] (usb_unbind_interface [usbcore]) from [<c02ce180>]
(device_release_driver_internal+0x160/0x208)
r10:00000100 r9:c5cb2a00 r8:00000034 r7:00000000 r6:bf39e898 r5:c5cb2c54
r4:c5cb2c20
[<c02ce020>] (device_release_driver_internal) from [<c02ce240>]
(device_release_driver+0x18/0x1c)
r9:c5cb2a00 r8:c05f1008 r7:c5c43070 r6:bf12895c r5:c5cb2c20 r4:c5dc91ac
[<c02ce228>] (device_release_driver) from [<c02ccf70>]
(bus_remove_device+0xd0/0x100)
[<c02ccea0>] (bus_remove_device) from [<c02c9c60>] (device_del+0x120/0x378)
r7:c5c43070 r6:c5cb2c28 r5:00000000 r4:c5cb2c20
[<c02c9b40>] (device_del) from [<bf11576c>]
(usb_disable_device+0x94/0x1d8 [usbcore])
r10:00000100 r9:c5cb2a00 r8:c5cb2c00 r7:c5c6c000 r6:00000001 r5:00000000
r4:c5c43000
[<bf1156d8>] (usb_disable_device [usbcore]) from [<bf10bccc>]
(usb_disconnect+0xb4/0x244 [usbcore])
r9:c5cb2a00 r8:c5c2d600 r7:c5c430a4 r6:c5c43070 r5:c5c43000 r4:00000000
[<bf10bc18>] (usb_disconnect [usbcore]) from [<bf10d788>]
(hub_event+0x678/0x11dc [usbcore])
r10:00000100 r9:c05f1008 r8:c5c2dcf8 r7:c68fc400 r6:00000001 r5:40000000
r4:00000000
[<bf10d110>] (hub_event [usbcore]) from [<c0031db0>]
(process_one_work+0x1d8/0x41c)
r10:00000008 r9:00000000 r8:c060b1d0 r7:00000000 r6:c7ede200 r5:c6882480
r4:c5c2dcf8
[<c0031bd8>] (process_one_work) from [<c0032030>] (worker_thread+0x3c/0x670)
r10:00000008 r9:c060b1e4 r8:c061ab60 r7:c6882498 r6:ffffe000 r5:c060b1d0
r4:c6882480
[<c0031ff4>] (worker_thread) from [<c0038270>] (kthread+0x134/0x14c)
r10:c683fe90 r9:c0031ff4 r8:c6882480 r7:c6896000 r6:00000000 r5:c687bd80
r4:c6803e80
[<c003813c>] (kthread) from [<c00090e0>] (ret_from_fork+0x14/0x34)
Exception stack(0xc6897fb0 to 0xc6897ff8)
7fa0: 00000000 00000000 00000000 00000000
7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fe0: 00000000 00000000 00000000 00000000 00000013 00000000
r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c003813c
r4:c687bd80
---[ end trace cb9c7f93aaa3ed36 ]---
------------[ cut here ]------------
adam
>> I'll be working with this series in the following days and will do
>> some thorough testing and rebase my aemif series on top of it. I'll
>> also use the recently merged reset support for board files to get rid
>> of the exported reset functions.
>>
>> Thanks for your work!
>>
>> Best regards,
>> Bartosz Golaszewski
>>
>
> Sounds like a good plan to me. FYI, I've started a common-clk-v9 branch
> on my GitHub already with a few minor fixes.
On Mon, Mar 19, 2018 at 11:15 AM, Bartosz Golaszewski
<[email protected]> wrote:
> 2018-03-19 17:14 GMT+01:00 Bartosz Golaszewski <[email protected]>:
>> 2018-03-19 17:11 GMT+01:00 Adam Ford <[email protected]>:
>>> On Mon, Mar 19, 2018 at 10:59 AM, David Lechner <[email protected]> wrote:
>>>> On 03/19/2018 08:17 AM, Bartosz Golaszewski wrote:
>>>>>
>>>>> 2018-03-16 3:52 GMT+01:00 David Lechner <[email protected]>:
>>>>>>
>>>>>> This series converts mach-davinci to use the common clock framework.
>>>>>>
>>>>>> The series works like this, the first 19 patches create new clock drivers
>>>>>> using the common clock framework. There are basically 3 groups of clocks
>>>>>> -
>>>>>> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each
>>>>>> have
>>>>>> unique init data, which is the reason for so many patches.
>>>>>>
>>>>>> Then, starting with "ARM: davinci: pass clock as parameter to
>>>>>> davinci_timer_init()", we get the mach code ready for the switch by
>>>>>> adding the
>>>>>> code needed for the new clock drivers and adding #ifndef
>>>>>> CONFIG_COMMON_CLK
>>>>>> around the legacy clocks so that we can switch easily between the old and
>>>>>> the
>>>>>> new.
>>>>>>
>>>>>> "ARM: davinci: switch to common clock framework" actually flips the
>>>>>> switch
>>>>>> to start using the new clock drivers. Then the next 8 patches remove all
>>>>>> of the old clock code.
>>>>>>
>>>>>> The final three patches add device tree clock support to the one SoC that
>>>>>> supports it.
>>>>>>
>>>>>> This series has been tested on LEGO MINDSTORMS EV3 (device tree) and TI
>>>>>> OMAP-L138 LCDK (both device tree and legacy board file).
>>>>>>
Does anyone have an LCD connected to the LCDC controller with device
tree? I posted an RFC patch a while ago for the DA850-EVM, but I got
distracted and forgot about it, so I never working on getting the
patch ready for acceptance.
I am trying to test the LCD now, but I cannot get the screen to come
up, but in the process, it appears as if the clocking to the LCD isn't
quite right. I know it used to work, but I am going to probe some
pins, but I am getting warning messages I have never received before.
The desired clock frequency is 9000000, but when I use the cpufreq in
ondemand mode, I get the following messages:
# echo ondemand > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor
# tilcdc 1e13000.display: tilcdc_crtc_irq(0x00000161): FIFO underflow
tilcdc 1e13000.display: effective pixel clock rate (50000000Hz) differs from the
calculated rate (54000000Hz)
tilcdc 1e13000.display: effective pixel clock rate (50000000Hz) differs from the
calculated rate (54000000Hz)
tilcdc 1e13000.display: tilcdc_crtc_irq(0x00000161): FIFO underflow
tilcdc 1e13000.display: tilcdc_crtc_irq(0x00000161): FIFO underflow
tilcdc 1e13000.display: effective pixel clock rate (50000000Hz) differs from the
calculated rate (54000000Hz)
tilcdc 1e13000.display: effective pixel clock rate (50000000Hz) differs from the
calculated rate (54000000Hz)
tilcdc 1e13000.display: tilcdc_crtc_irq(0x00000161): FIFO underflow
tilcdc 1e13000.display: tilcdc_crtc_irq(0x00000161): FIFO underflow
tilcdc 1e13000.display: effective pixel clock rate (50000000Hz) differs from the
calculated rate (54000000Hz)
tilcdc 1e13000.display: effective pixel clock rate (50000000Hz) differs from the
calculated rate (54000000Hz)
tilcdc 1e13000.display: tilcdc_crtc_irq(0x00000161): FIFO underflow
As ondemend is used and the processor scaling happens, the above
message appears on and off.
I do not know if it impacts the LCD image since I haven't been able to
get it working yet, but I'll troubleshoot it and when/if I can get the
LCD working, I'll turn on the ondemand again and see how it behaves.
adam
>>>>>
>>>>> Hi David,
>>>>>
>>>>> thanks, with the u-boot fix everything seems to work fine. I tested
>>>>> da850-lcdk and da850-evm boards in DT and board file modes.
>>>>>
>>>
>>> I tested MMC and Ethernet. Both appear to be operating normally, but
>>> I have having USB issues.
>>>
>>> Should I be testing cpufreq? I noticed that when changing the
>>> frequencies, the USB appears to stop recognizing connections and
>>> disconnections.
>>>
>>> I did some testing on the DA850-EVM with USB from your repo, and I'm
>>> getting some crashing on MUSB unplug that do not appear in the
>>> 4.16-RC6 from linux-stable:
>>>
>>>
>>> ------------[ cut here ]------------
>>> WARNING: CPU: 0 PID: 13 at drivers/dma/cppi41.c:694
>>> cppi41_stop_chan+0x1f4/0x378 [cppi41]
>>> Modules linked in: evbug evdev mousedev hid_generic usbhid hid
>>> usb_f_ss_lb g_zero libcomposite configfs ofpart cmdlinepart m25p80
>>> spi_nor cppi41 adv7343 tvp514x vpif_display vpif_capture
>>> videobuf2_dma_con
>>> tig videobuf2_memops videobuf2_v4l2 videobuf2_common v4l2_fwnode
>>> v4l2_common snd_soc_simple_card tilcdc spi_davinci
>>> snd_soc_simple_card_utils videodev pwm_tiecap spi_bitbang da8xx
>>> drm_kms_helper phy_gener
>>> ic syscopyarea ohci_da8xx musb_hdrc sysfillrect sysimgblt fb_sys_fops
>>> ohci_hcd udc_core drm usbcore drm_panel_orientation_quirks usb_common
>>> snd_soc_tlv320aic3x vpif snd_soc_davinci_mcasp snd_soc_edma snd_
>>> soc_core snd_pcm_dmaengine snd_pcm rtc_omap snd_timer snd soundcore
>>> phy_da8xx_usb davinci_nand nand nand_ecc mtd pwm_bl backlight
>>> cpufreq_dt ti_aemif
>>> CPU: 0 PID: 13 Comm: kworker/0:1 Not tainted 4.16.0-rc5-g291ba8b-dirty #3
>>> Hardware name: Generic DA850/OMAP-L138/AM18x
>>> Workqueue: usb_hub_wq hub_event [usbcore]
>>> Backtrace:
>>> [<c000df94>] (dump_backtrace) from [<c000e264>] (show_stack+0x18/0x1c)
>>> r7:00000009 r6:00000000 r5:bf339ad0 r4:00000000
>>> [<c000e24c>] (show_stack) from [<c04864c0>] (dump_stack+0x20/0x28)
>>> [<c04864a0>] (dump_stack) from [<c001ac38>] (__warn+0xd4/0xfc)
>>> [<c001ab64>] (__warn) from [<c001ad7c>] (warn_slowpath_null+0x44/0x50)
>>> r8:c6c43080 r7:c05f1008 r6:bf338744 r5:000002b6 r4:bf339ad0
>>> [<c001ad38>] (warn_slowpath_null) from [<bf338744>]
>>> (cppi41_stop_chan+0x1f4/0x378 [cppi41])
>>> r6:c5e59410 r5:c5e59420 r4:c5feca50
>>> [<bf338550>] (cppi41_stop_chan [cppi41]) from [<bf213dac>]
>>> (cppi41_dma_channel_abort+0xe0/0x2a8 [musb_hdrc])
>>> r8:c6929180 r7:00000000 r6:c5c67290 r5:bf2175a0 r4:00000008
>>> [<bf213ccc>] (cppi41_dma_channel_abort [musb_hdrc]) from [<bf20c4bc>]
>>> (musb_cleanup_urb+0x60/0x210 [musb_hdrc])
>>> r10:00000001 r9:c5fca010 r8:c5c67290 r7:a0000093 r6:00000080 r5:c55b5100
>>> r4:c5fca5a8
>>> [<bf20c45c>] (musb_cleanup_urb [musb_hdrc]) from [<bf20ca8c>]
>>> (musb_urb_dequeue+0xfc/0x164 [musb_hdrc])
>>> r10:00000001 r9:40408280 r8:c5fca010 r7:a0000093 r6:00000000 r5:c55b5380
>>> r4:c55b5100
>>> [<bf20c990>] (musb_urb_dequeue [musb_hdrc]) from [<bf10fd7c>]
>>> (unlink1+0x34/0x13c [usbcore])
>>> r10:00000100 r9:c5cb2a00 r8:c55b5100 r7:ffffff94 r6:c5c6c000 r5:c5dd2380
>>> r4:c55b5100 r3:bf20c990
>>> [<bf10fd48>] (unlink1 [usbcore]) from [<bf112424>]
>>> (usb_hcd_flush_endpoint+0x164/0x1a4 [usbcore])
>>> r9:c5cb2a00 r8:c55b5100 r7:c5c6c000 r6:c5dd2398 r5:c5dd2380 r4:ffffe000
>>> [<bf1122c0>] (usb_hcd_flush_endpoint [usbcore]) from [<bf11563c>]
>>> (usb_disable_endpoint+0x50/0x94 [usbcore])
>>> r9:c5cb2a00 r8:bf39e898 r7:00000000 r6:c5c43000 r5:c5c43000 r4:c5dd2380
>>> [<bf1155ec>] (usb_disable_endpoint [usbcore]) from [<bf1156c4>]
>>> (usb_disable_interface+0x44/0x58 [usbcore])
>>> r5:c5dd2348 r4:00000000
>>> [<bf115680>] (usb_disable_interface [usbcore]) from [<bf118044>]
>>> (usb_unbind_interface+0x1c0/0x268 [usbcore])
>>> r7:c5cb2c00 r6:bf39e898 r5:c5cb2c20 r4:c5cb2c20
>>> [<bf117e84>] (usb_unbind_interface [usbcore]) from [<c02ce180>]
>>> (device_release_driver_internal+0x160/0x208)
>>> r10:00000100 r9:c5cb2a00 r8:00000034 r7:00000000 r6:bf39e898 r5:c5cb2c54
>>> r4:c5cb2c20
>>> [<c02ce020>] (device_release_driver_internal) from [<c02ce240>]
>>> (device_release_driver+0x18/0x1c)
>>> r9:c5cb2a00 r8:c05f1008 r7:c5c43070 r6:bf12895c r5:c5cb2c20 r4:c5dc91ac
>>> [<c02ce228>] (device_release_driver) from [<c02ccf70>]
>>> (bus_remove_device+0xd0/0x100)
>>> [<c02ccea0>] (bus_remove_device) from [<c02c9c60>] (device_del+0x120/0x378)
>>> r7:c5c43070 r6:c5cb2c28 r5:00000000 r4:c5cb2c20
>>> [<c02c9b40>] (device_del) from [<bf11576c>]
>>> (usb_disable_device+0x94/0x1d8 [usbcore])
>>> r10:00000100 r9:c5cb2a00 r8:c5cb2c00 r7:c5c6c000 r6:00000001 r5:00000000
>>> r4:c5c43000
>>> [<bf1156d8>] (usb_disable_device [usbcore]) from [<bf10bccc>]
>>> (usb_disconnect+0xb4/0x244 [usbcore])
>>> r9:c5cb2a00 r8:c5c2d600 r7:c5c430a4 r6:c5c43070 r5:c5c43000 r4:00000000
>>> [<bf10bc18>] (usb_disconnect [usbcore]) from [<bf10d788>]
>>> (hub_event+0x678/0x11dc [usbcore])
>>> r10:00000100 r9:c05f1008 r8:c5c2dcf8 r7:c68fc400 r6:00000001 r5:40000000
>>> r4:00000000
>>> [<bf10d110>] (hub_event [usbcore]) from [<c0031db0>]
>>> (process_one_work+0x1d8/0x41c)
>>> r10:00000008 r9:00000000 r8:c060b1d0 r7:00000000 r6:c7ede200 r5:c6882480
>>> r4:c5c2dcf8
>>> [<c0031bd8>] (process_one_work) from [<c0032030>] (worker_thread+0x3c/0x670)
>>> r10:00000008 r9:c060b1e4 r8:c061ab60 r7:c6882498 r6:ffffe000 r5:c060b1d0
>>> r4:c6882480
>>> [<c0031ff4>] (worker_thread) from [<c0038270>] (kthread+0x134/0x14c)
>>> r10:c683fe90 r9:c0031ff4 r8:c6882480 r7:c6896000 r6:00000000 r5:c687bd80
>>> r4:c6803e80
>>> [<c003813c>] (kthread) from [<c00090e0>] (ret_from_fork+0x14/0x34)
>>> Exception stack(0xc6897fb0 to 0xc6897ff8)
>>> 7fa0: 00000000 00000000 00000000 00000000
>>> 7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
>>> 7fe0: 00000000 00000000 00000000 00000000 00000013 00000000
>>> r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c003813c
>>> r4:c687bd80
>>> ---[ end trace cb9c7f93aaa3ed36 ]---
>>> ------------[ cut here ]------------
>>>
>>>
>>> adam
>>>
>>
>> Hi Adam,
>>
>> this is a known issue and it's present in mainline and even in TI BSP.
>> It's been deprioritized for now, but I'll return to debugging it once
>> the common clock conversion is complete.
>>
>> Thanks,
>> Bartosz
>
> Ugh, -ETOOEARLY
>
> I meant the ohci dying during cpufreq bug, not the crash you posted.
>
> Bart
On 03/19/2018 08:17 AM, Bartosz Golaszewski wrote:
> 2018-03-16 3:52 GMT+01:00 David Lechner <[email protected]>:
>> This series converts mach-davinci to use the common clock framework.
>>
>> The series works like this, the first 19 patches create new clock drivers
>> using the common clock framework. There are basically 3 groups of clocks -
>> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each have
>> unique init data, which is the reason for so many patches.
>>
>> Then, starting with "ARM: davinci: pass clock as parameter to
>> davinci_timer_init()", we get the mach code ready for the switch by adding the
>> code needed for the new clock drivers and adding #ifndef CONFIG_COMMON_CLK
>> around the legacy clocks so that we can switch easily between the old and the
>> new.
>>
>> "ARM: davinci: switch to common clock framework" actually flips the switch
>> to start using the new clock drivers. Then the next 8 patches remove all
>> of the old clock code.
>>
>> The final three patches add device tree clock support to the one SoC that
>> supports it.
>>
>> This series has been tested on LEGO MINDSTORMS EV3 (device tree) and TI
>> OMAP-L138 LCDK (both device tree and legacy board file).
>>
>
> Hi David,
>
> thanks, with the u-boot fix everything seems to work fine. I tested
> da850-lcdk and da850-evm boards in DT and board file modes.
>
> I'll be working with this series in the following days and will do
> some thorough testing and rebase my aemif series on top of it. I'll
> also use the recently merged reset support for board files to get rid
> of the exported reset functions.
>
> Thanks for your work!
>
> Best regards,
> Bartosz Golaszewski
>
Sounds like a good plan to me. FYI, I've started a common-clk-v9 branch
on my GitHub already with a few minor fixes.
On 03/19/2018 12:52 PM, Adam Ford wrote:
> On Mon, Mar 19, 2018 at 11:15 AM, Bartosz Golaszewski
> <[email protected]> wrote:
>> 2018-03-19 17:14 GMT+01:00 Bartosz Golaszewski <[email protected]>:
>>> 2018-03-19 17:11 GMT+01:00 Adam Ford <[email protected]>:
>>>> On Mon, Mar 19, 2018 at 10:59 AM, David Lechner <[email protected]> wrote:
>>>>> On 03/19/2018 08:17 AM, Bartosz Golaszewski wrote:
>>>>>>
>>>>>> 2018-03-16 3:52 GMT+01:00 David Lechner <[email protected]>:
>>>>>>>
>>>>>>> This series converts mach-davinci to use the common clock framework.
>>>>>>>
>>>>>>> The series works like this, the first 19 patches create new clock drivers
>>>>>>> using the common clock framework. There are basically 3 groups of clocks
>>>>>>> -
>>>>>>> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each
>>>>>>> have
>>>>>>> unique init data, which is the reason for so many patches.
>>>>>>>
>>>>>>> Then, starting with "ARM: davinci: pass clock as parameter to
>>>>>>> davinci_timer_init()", we get the mach code ready for the switch by
>>>>>>> adding the
>>>>>>> code needed for the new clock drivers and adding #ifndef
>>>>>>> CONFIG_COMMON_CLK
>>>>>>> around the legacy clocks so that we can switch easily between the old and
>>>>>>> the
>>>>>>> new.
>>>>>>>
>>>>>>> "ARM: davinci: switch to common clock framework" actually flips the
>>>>>>> switch
>>>>>>> to start using the new clock drivers. Then the next 8 patches remove all
>>>>>>> of the old clock code.
>>>>>>>
>>>>>>> The final three patches add device tree clock support to the one SoC that
>>>>>>> supports it.
>>>>>>>
>>>>>>> This series has been tested on LEGO MINDSTORMS EV3 (device tree) and TI
>>>>>>> OMAP-L138 LCDK (both device tree and legacy board file).
>>>>>>>
>
>
> Does anyone have an LCD connected to the LCDC controller with device
> tree? I posted an RFC patch a while ago for the DA850-EVM, but I got
> distracted and forgot about it, so I never working on getting the
> patch ready for acceptance.
>
> I am trying to test the LCD now, but I cannot get the screen to come
> up, but in the process, it appears as if the clocking to the LCD isn't
> quite right. I know it used to work, but I am going to probe some
> pins, but I am getting warning messages I have never received before.
> The desired clock frequency is 9000000, but when I use the cpufreq in
> ondemand mode, I get the following messages:
>
> # echo ondemand > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor
> # tilcdc 1e13000.display: tilcdc_crtc_irq(0x00000161): FIFO underflow
> tilcdc 1e13000.display: effective pixel clock rate (50000000Hz) differs from the
> calculated rate (54000000Hz)
> tilcdc 1e13000.display: effective pixel clock rate (50000000Hz) differs from the
> calculated rate (54000000Hz)
> tilcdc 1e13000.display: tilcdc_crtc_irq(0x00000161): FIFO underflow
> tilcdc 1e13000.display: tilcdc_crtc_irq(0x00000161): FIFO underflow
> tilcdc 1e13000.display: effective pixel clock rate (50000000Hz) differs from the
> calculated rate (54000000Hz)
> tilcdc 1e13000.display: effective pixel clock rate (50000000Hz) differs from the
> calculated rate (54000000Hz)
> tilcdc 1e13000.display: tilcdc_crtc_irq(0x00000161): FIFO underflow
> tilcdc 1e13000.display: tilcdc_crtc_irq(0x00000161): FIFO underflow
> tilcdc 1e13000.display: effective pixel clock rate (50000000Hz) differs from the
> calculated rate (54000000Hz)
> tilcdc 1e13000.display: effective pixel clock rate (50000000Hz) differs from the
> calculated rate (54000000Hz)
> tilcdc 1e13000.display: tilcdc_crtc_irq(0x00000161): FIFO underflow
>
> As ondemend is used and the processor scaling happens, the above
> message appears on and off.
>
> I do not know if it impacts the LCD image since I haven't been able to
> get it working yet, but I'll troubleshoot it and when/if I can get the
> LCD working, I'll turn on the ondemand again and see how it behaves.
>
> adam
>
>
I've just been using the VGA connector on the LCDK since that is the only
hardware I have that uses the LCDC controller and I haven't tried it with
ondemand CPU freq yet.
But, I do know this. The parent clock for the LCDC (PLL0 SYSCLK2) must be
(according to the TRM) set to a fixed ratio to the ARM clock (/2), so it
can only have certain rates. The tilcdc driver then tries to pick a
divider for that rate to get close enough to the requested 54MHz. Also,
this divider must be at least 2. It can't be 1 (or 0).
So, if the CPU throttles down to 100, 200, or 300MHz, then 50Mz is as
close as any integer divider can get. The kernel prints a warning if
the difference between the requested and actual rate is over 5%. There
is a note in the kernel comments that this 5% value is arbitrary, so
maybe it needs to change to 10%?
I haven't dug deep enough to understand why the driver thinks it needs
a 54MHz pixel when you think it should be 9MHz.
I am also occasionally seeing the underflow error when the CPU is busy.
Maybe there is some more tweaking that could be done with the master
priority controller (unrelated to this patch series)? Or maybe if you
want to use the LCDC, then you just need to run at 475MHz all of the
time?
Quoting David Lechner (2018-03-15 19:52:16)
> This series converts mach-davinci to use the common clock framework.
>
> The series works like this, the first 19 patches create new clock drivers
> using the common clock framework. There are basically 3 groups of clocks -
> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each have
> unique init data, which is the reason for so many patches.
Should I apply the first 19 patches to clk tree? Looking over them
nothing stands out except for your self comment about the bad
reviewed-by tag which I can remove.
Hi Stephen,
On Tuesday 20 March 2018 06:23 AM, Stephen Boyd wrote:
> Quoting David Lechner (2018-03-15 19:52:16)
>> This series converts mach-davinci to use the common clock framework.
>>
>> The series works like this, the first 19 patches create new clock drivers
>> using the common clock framework. There are basically 3 groups of clocks -
>> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each have
>> unique init data, which is the reason for so many patches.
>
> Should I apply the first 19 patches to clk tree? Looking over them
> nothing stands out except for your self comment about the bad
> reviewed-by tag which I can remove.
I think it will be a good idea to go ahead merge the drivers/clk/ parts
for v4.17.
I have been traveling, and have not been able to review this version.
But I have closely reviewed previous versions. If there really are
issues, I am sure we can get follow-on patches to fix those.
But getting these into v4.17 will enable platform parts to come in
easily into v4.18
Thanks,
Sekhar
Quoting David Lechner (2018-03-15 19:52:34)
> +
> +typedef int (*da8xx_cfgchip_init)(struct device *dev, void __iomem *base);
Should be struct regmap *regmap?
I've squashed this in.
diff --git a/drivers/clk/davinci/da8xx-cfgchip.c b/drivers/clk/davinci/da8xx-cfgchip.c
index 858d3786b27b..c971111d2601 100644
--- a/drivers/clk/davinci/da8xx-cfgchip.c
+++ b/drivers/clk/davinci/da8xx-cfgchip.c
@@ -736,7 +736,7 @@ static const struct platform_device_id da8xx_cfgchip_id_table[] = {
{ }
};
-typedef int (*da8xx_cfgchip_init)(struct device *dev, void __iomem *base);
+typedef int (*da8xx_cfgchip_init)(struct device *dev, struct regmap *regmap);
static int da8xx_cfgchip_probe(struct platform_device *pdev)
{
On 03/20/2018 11:54 AM, Stephen Boyd wrote:
> Quoting David Lechner (2018-03-15 19:52:34)
>> +
>> +typedef int (*da8xx_cfgchip_init)(struct device *dev, void __iomem *base);
>
> Should be struct regmap *regmap?
Yes. It looks like this was copied and pasted from one of the other drivers.
Thank you for fixing it.
>
> I've squashed this in.
>
> diff --git a/drivers/clk/davinci/da8xx-cfgchip.c b/drivers/clk/davinci/da8xx-cfgchip.c
> index 858d3786b27b..c971111d2601 100644
> --- a/drivers/clk/davinci/da8xx-cfgchip.c
> +++ b/drivers/clk/davinci/da8xx-cfgchip.c
> @@ -736,7 +736,7 @@ static const struct platform_device_id da8xx_cfgchip_id_table[] = {
> { }
> };
>
> -typedef int (*da8xx_cfgchip_init)(struct device *dev, void __iomem *base);
> +typedef int (*da8xx_cfgchip_init)(struct device *dev, struct regmap *regmap);
>
> static int da8xx_cfgchip_probe(struct platform_device *pdev)
> {
>
Quoting David Lechner (2018-03-15 19:52:18)
> +
> +static int davinci_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
> +{
> + struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
> + struct debugfs_regset32 *regset;
> + struct dentry *d;
> +
> + regset = kzalloc(sizeof(regset), GFP_KERNEL);
Should be sizeof(*regset)?
I squashed this in:
diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c
index 588a48927436..89d30bf95102 100644
--- a/drivers/clk/davinci/pll.c
+++ b/drivers/clk/davinci/pll.c
@@ -882,7 +882,7 @@ static int davinci_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
struct debugfs_regset32 *regset;
struct dentry *d;
- regset = kzalloc(sizeof(regset), GFP_KERNEL);
+ regset = kzalloc(sizeof(*regset), GFP_KERNEL);
if (!regset)
return -ENOMEM;
Quoting David Lechner (2018-03-15 19:52:29)
> +static int dm355_psc_init(struct device *dev, void __iomem *base)
> +{
> + return davinci_psc_register_clocks(base, dm355_psc_info, 42, base);
> +}
> +
Should be dev for that first argument to davinci_psc_register_clocks()?
I squashed this in:
diff --git a/drivers/clk/davinci/psc-dm355.c b/drivers/clk/davinci/psc-dm355.c
index 249a05330457..6995ecea2677 100644
--- a/drivers/clk/davinci/psc-dm355.c
+++ b/drivers/clk/davinci/psc-dm355.c
@@ -70,7 +70,7 @@ static const struct davinci_lpsc_clk_info dm355_psc_info[] = {
static int dm355_psc_init(struct device *dev, void __iomem *base)
{
- return davinci_psc_register_clocks(base, dm355_psc_info, 42, base);
+ return davinci_psc_register_clocks(dev, dm355_psc_info, 42, base);
}
static struct clk_bulk_data dm355_psc_parent_clks[] = {
Quoting David Lechner (2018-03-15 19:52:17)
> This adds a new binding for the PLL IP blocks in the mach-davinci
> family of processors. Currently, only da850 has device tree support
> but these bindings can also work for other SoCs in this family just
> by adding new compatible strings.
>
> Note: Although these PLL controllers are very similar to the TI Keystone
> SoCs, we are not re-using those bindings. The Keystone bindings use a
> legacy one-node-per-clock binding. Furthermore, the mach-davinici SoCs
> have a slightly different PLL register layout and a number of quirks
> that can't be handled by the existing bindings, so the keystone bindings
> could not be used as-is anyway.
>
> Signed-off-by: David Lechner <[email protected]>
> Reviewed-by: Rob Herring <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:20)
> This adds platform-specific declarations for the PLL clocks on TI DA850/
> OMAP-L138/AM18XX SoCs.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:34)
> This adds a new driver for the gate and multiplexer clocks in the
> CFGCHIPn syscon registers on TI DA8XX-type SoCs.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:29)
> This adds platform-specific declarations for the PSC clocks on TI
> DM355 based systems.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:26)
> This adds a new driver for mach-davinci PSC clocks. This is porting the
> code from arch/arm/mach-davinci/psc.c to the common clock framework and
> is converting it to use regmap to simplify the code. Additionally, it
> adds device tree support for these clocks.
>
> Note: although there are similar clocks for TI Keystone we are not able
> to share the code for a few reasons. The keystone clocks are device tree
> only and use legacy one-node-per-clock bindings. Also the keystone
> driver makes the assumption that there is only one PSC per SoC and uses
> global variables, but here we have two controllers per SoC.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:30)
> This adds platform-specific declarations for the PSC clocks on TI
> DM365 based systems.
>
> Signed-off-by: David Lechner <[email protected]>
> Reviewed-by: Sekhar Nori <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:33)
> This adds a new binding for the clocks present in the CFGCHIP syscon
> registers in TI DA8XX SoCs.
>
> Signed-off-by: David Lechner <[email protected]>
> Reviewed-by: Rob Herring <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:31)
> This adds platform-specific declarations for the PSC clocks on TI
> DM644x based systems.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:35)
> This adds a new driver for the USB PHY clocks in the CFGCHIP2 syscon
> register on TI DA8XX-type SoCs.
>
> The USB0 (USB 2.0) PHY clock is an interesting case because it calls
> clk_enable() in a reentrant way. The USB 2.0 PSC only has to be enabled
> temporarily while we are locking the PLL, which takes place during the
> clk_enable() callback.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:32)
> This adds platform-specific declarations for the PSC clocks on TI
> DM646x based systems.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:28)
> This adds platform-specific declarations for the PSC clocks on TI DA850/
> OMAP-L138/AM18XX SoCs.
>
> Signed-off-by: David Lechner <[email protected]>
> Reviewed-by: Sekhar Nori <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:22)
> This adds platform-specific declarations for the PLL clocks on TI
> DM365 based systems.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:27)
> This adds platform-specific declarations for the PSC clocks on TI DA830/
> OMAP-L137/AM17XX SoCs.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:23)
> This adds platform-specific declarations for the PLL clocks on TI
> DM644x based systems.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:25)
> This adds a new binding for the Power Sleep Controller (PSC) for the
> mach-davinci family of processors.
>
> Note: Although TI Keystone has a very similar PSC, we are not using the
> existing bindings. Keystone is using a legacy one-node-per-clock binding
> (actually two nodes if you count the separate reset binding for the same
> IP block). Also, some davinci LPSCs have quirks that aren't handled by
> the keystone bindings, so we would be adding one compatible string per
> clock with quirks instead of just a new compatible string for each
> controller.
>
> Signed-off-by: David Lechner <[email protected]>
> Reviewed-by: Rob Herring <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:21)
> This adds platform-specific declarations for the PLL clocks on TI
> DM355 based systems.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:19)
> This adds platform-specific declarations for the PLL clocks on TI DA830/
> OMAP-L137/AM17XX SoCs.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:18)
> This adds a new driver for mach-davinci PLL clocks. This is porting the
> code from arch/arm/mach-davinci/clock.c to the common clock framework.
> Additionally, it adds device tree support for these clocks.
>
> The ifeq ($(CONFIG_COMMON_CLK), y) in the Makefile is needed to prevent
> compile errors until the clock code in arch/arm/mach-davinci is removed.
>
> Note: although there are similar clocks for TI Keystone we are not able
> to share the code for a few reasons. The keystone clocks are device tree
> only and use legacy one-node-per-clock bindings. Also the register
> layouts are a bit different, which would add even more if/else mess
> to the keystone clocks. And the keystone PLL driver doesn't support
> setting clock rates.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
Applied to clk-next
Quoting David Lechner (2018-03-15 19:52:24)
> This adds platform-specific declarations for the PLL clocks on TI
> DM646x based systems.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
Applied to clk-next
On Friday 16 March 2018 10:50 PM, David Lechner wrote:
> On 03/15/2018 09:52 PM, David Lechner wrote:
>> This adds clock provider nodes for da850 and wires them up to all of the
>> devices.
>>
>> Signed-off-by: David Lechner <[email protected]>
>> ---
>
> ...
>
> This is the mcasp0: mcasp@100000 node...
>
>> @@ -560,6 +720,7 @@
>> dmas = <&edma0 1 1>,
>> <&edma0 0 1>;
>> dma-names = "tx", "rx";
>> + clocks = <&psc1 7>;
>
> After some testing, it looks like it needs to be:
>
> + power-domains = <&psc1 7>;
>
> instead of
>
> + clocks = <&psc1 7>;
We should probably have both clocks and power-domains properties for all
PSC clocks. This way, the driver can change without a corresponding DT
update dependency.
Thanks,
Sekhar
On 04/02/2018 06:12 AM, Sekhar Nori wrote:
> On Friday 16 March 2018 10:50 PM, David Lechner wrote:
>> On 03/15/2018 09:52 PM, David Lechner wrote:
>>> This adds clock provider nodes for da850 and wires them up to all of the
>>> devices.
>>>
>>> Signed-off-by: David Lechner <[email protected]>
>>> ---
>>
>> ...
>>
>> This is the mcasp0: mcasp@100000 node...
>>
>>> @@ -560,6 +720,7 @@
>>> dmas = <&edma0 1 1>,
>>> <&edma0 0 1>;
>>> dma-names = "tx", "rx";
>>> + clocks = <&psc1 7>;
>>
>> After some testing, it looks like it needs to be:
>>
>> + power-domains = <&psc1 7>;
>>
>> instead of
>>
>> + clocks = <&psc1 7>;
>
> We should probably have both clocks and power-domains properties for all
> PSC clocks. This way, the driver can change without a corresponding DT
> update dependency.
>
> Thanks,
> Sekhar
>
That's fine with me. I just didn't know how people felt about using properties
that are not documented.
On Monday 02 April 2018 09:45 PM, David Lechner wrote:
> On 04/02/2018 06:12 AM, Sekhar Nori wrote:
>> On Friday 16 March 2018 10:50 PM, David Lechner wrote:
>>> On 03/15/2018 09:52 PM, David Lechner wrote:
>>>> This adds clock provider nodes for da850 and wires them up to all of
>>>> the
>>>> devices.
>>>>
>>>> Signed-off-by: David Lechner <[email protected]>
>>>> ---
>>>
>>> ...
>>>
>>> This is the mcasp0: mcasp@100000 node...
>>>
>>>> @@ -560,6 +720,7 @@
>>>> dmas = <&edma0 1 1>,
>>>> <&edma0 0 1>;
>>>> dma-names = "tx", "rx";
>>>> + clocks = <&psc1 7>;
>>>
>>> After some testing, it looks like it needs to be:
>>>
>>> + power-domains = <&psc1 7>;
>>>
>>> instead of
>>>
>>> + clocks = <&psc1 7>;
>>
>> We should probably have both clocks and power-domains properties for all
>> PSC clocks. This way, the driver can change without a corresponding DT
>> update dependency.
>>
>> Thanks,
>> Sekhar
>>
>
> That's fine with me. I just didn't know how people felt about using
> properties
> that are not documented.
Good point. How to ease documentation for generic properties like these
was discussed in the past, but there is no guidance in
Documentation/devicetree/bindings that I can see.
So, in the interest of reduced controversy, its probably better to do
what you already have and only populate properties already documented in
the bindings.
Thanks,
Sekhar
On Friday 16 March 2018 08:22 AM, David Lechner wrote:
> +static struct resource dm644x_pll1_resources[] = {
> + {
> + .start = DAVINCI_PLL1_BASE,
> + .end = DAVINCI_PLL1_BASE + SZ_4K - 1,
The .end should be DAVINCI_PLL1_BASE + SZ_1K - 1, otherwise it prevents
PLL2 from getting registered.
> + .flags = IORESOURCE_MEM,
> + },
> +};
> +
> +static struct platform_device dm644x_pll1_device = {
> + .name = "dm644x-pll1",
> + .id = -1,
> + .resource = dm644x_pll1_resources,
> + .num_resources = ARRAY_SIZE(dm644x_pll1_resources),
> +};
> +
> +static struct resource dm644x_pll2_resources[] = {
> + {
> + .start = DAVINCI_PLL2_BASE,
> + .end = DAVINCI_PLL2_BASE + SZ_4K - 1,
And this too should be fixed, else it prevents the PSC from getting
registered.
> + .flags = IORESOURCE_MEM,
> + },
> +};
With these fixed, I still had to enable 'clk_ignore_unused' on DM644x
EVM to get to NFS boot. I think root of the problem is that pm_runtime()
APIs are not working in the legacy boot mode.
This can be seen even on the DA850 LCDK in legacy boot. pm_genpd_summary
in debugfs shows all domains are off and there are no devices registered
under the "da850-psc1: emac" domain. NFS mounting still works on the
DA850 LCDK because clk_summary shows enable and prepare count of 4 for
emac. Not sure how that's happening. But on DM644x EVM, the emac clock
enable count is 0.
Still looking at whats going wrong here. I am testing your v8 branch
with clk-davinci branch from clk-next merged to get the fixes Stephen made.
Thanks,
Sekhar
On 04/03/2018 05:26 AM, Sekhar Nori wrote:
> On Friday 16 March 2018 08:22 AM, David Lechner wrote:
>> +static struct resource dm644x_pll1_resources[] = {
>> + {
>> + .start = DAVINCI_PLL1_BASE,
>> + .end = DAVINCI_PLL1_BASE + SZ_4K - 1,
>
> The .end should be DAVINCI_PLL1_BASE + SZ_1K - 1, otherwise it prevents
> PLL2 from getting registered.
>
>> + .flags = IORESOURCE_MEM,
>> + },
>> +};
>> +
>> +static struct platform_device dm644x_pll1_device = {
>> + .name = "dm644x-pll1",
>> + .id = -1,
>> + .resource = dm644x_pll1_resources,
>> + .num_resources = ARRAY_SIZE(dm644x_pll1_resources),
>> +};
>> +
>> +static struct resource dm644x_pll2_resources[] = {
>> + {
>> + .start = DAVINCI_PLL2_BASE,
>> + .end = DAVINCI_PLL2_BASE + SZ_4K - 1,
>
> And this too should be fixed, else it prevents the PSC from getting
> registered.
>
>> + .flags = IORESOURCE_MEM,
>> + },
>> +};
>
> With these fixed, I still had to enable 'clk_ignore_unused' on DM644x
> EVM to get to NFS boot. I think root of the problem is that pm_runtime()
> APIs are not working in the legacy boot mode.
>
> This can be seen even on the DA850 LCDK in legacy boot. pm_genpd_summary
> in debugfs shows all domains are off and there are no devices registered
> under the "da850-psc1: emac" domain. NFS mounting still works on the
> DA850 LCDK because clk_summary shows enable and prepare count of 4 for
> emac. Not sure how that's happening. But on DM644x EVM, the emac clock
> enable count is 0.
>
> Still looking at whats going wrong here. I am testing your v8 branch
> with clk-davinci branch from clk-next merged to get the fixes Stephen made.
>
In legacy mode, genpd is not being used. I didn't see any mechanism for
genpd lookup without device tree. So, we are still relying on the
matching in arch/arm/mach-davinci/pm_domain.c.
I suspect we need to fix the clock lookups in
drivers/clk/davinci/psc-dm644x.c.
LPSC_CLKDEV2(emac_clkdev, NULL, "davinci_emac.1",
"fck", "davinci_mdio.0");
NULL might need to be changed to "fck" to be picked up by pm matching
and "davinci_emac.1" should be verified that it matches the actual EMAC
device name.
On Tuesday 03 April 2018 10:00 PM, David Lechner wrote:
> On 04/03/2018 05:26 AM, Sekhar Nori wrote:
>> On Friday 16 March 2018 08:22 AM, David Lechner wrote:
>>> +static struct resource dm644x_pll1_resources[] = {
>>> + {
>>> + .start = DAVINCI_PLL1_BASE,
>>> + .end = DAVINCI_PLL1_BASE + SZ_4K - 1,
>>
>> The .end should be DAVINCI_PLL1_BASE + SZ_1K - 1, otherwise it prevents
>> PLL2 from getting registered.
>>
>>> + .flags = IORESOURCE_MEM,
>>> + },
>>> +};
>>> +
>>> +static struct platform_device dm644x_pll1_device = {
>>> + .name = "dm644x-pll1",
>>> + .id = -1,
>>> + .resource = dm644x_pll1_resources,
>>> + .num_resources = ARRAY_SIZE(dm644x_pll1_resources),
>>> +};
>>> +
>>> +static struct resource dm644x_pll2_resources[] = {
>>> + {
>>> + .start = DAVINCI_PLL2_BASE,
>>> + .end = DAVINCI_PLL2_BASE + SZ_4K - 1,
>>
>> And this too should be fixed, else it prevents the PSC from getting
>> registered.
>>
>>> + .flags = IORESOURCE_MEM,
>>> + },
>>> +};
>>
>> With these fixed, I still had to enable 'clk_ignore_unused' on DM644x
>> EVM to get to NFS boot. I think root of the problem is that pm_runtime()
>> APIs are not working in the legacy boot mode.
>>
>> This can be seen even on the DA850 LCDK in legacy boot. pm_genpd_summary
>> in debugfs shows all domains are off and there are no devices registered
>> under the "da850-psc1: emac" domain. NFS mounting still works on the
>> DA850 LCDK because clk_summary shows enable and prepare count of 4 for
>> emac. Not sure how that's happening. But on DM644x EVM, the emac clock
>> enable count is 0.
>>
>> Still looking at whats going wrong here. I am testing your v8 branch
>> with clk-davinci branch from clk-next merged to get the fixes Stephen
>> made.
>>
>
> In legacy mode, genpd is not being used. I didn't see any mechanism for
Ah, I got stumped by the genpd related debug entries popping up.
Probably something should be done to make sure they don't show up in
legacy boot. And some comments to that effect in psc.c will help.
> genpd lookup without device tree. So, we are still relying on the
> matching in arch/arm/mach-davinci/pm_domain.c.
This is fine. We just need legacy boot to keep working without regressions.
>
> I suspect we need to fix the clock lookups in
> drivers/clk/davinci/psc-dm644x.c.
>
> LPSC_CLKDEV2(emac_clkdev, NULL, "davinci_emac.1",
> "fck", "davinci_mdio.0");
>
> NULL might need to be changed to "fck" to be picked up by pm matching
> and "davinci_emac.1" should be verified that it matches the actual EMAC
> device name.
NULL con_id matches what we have for DA850 and also what we had for
DM644x prior to CCF conversion. So, I did not really suspect that. The
device name does match. I will check what else could be going on based
on your input.
Thanks,
Sekhar
On Wednesday 04 April 2018 12:17 PM, Sekhar Nori wrote:
> On Tuesday 03 April 2018 10:00 PM, David Lechner wrote:
>> On 04/03/2018 05:26 AM, Sekhar Nori wrote:
>>> On Friday 16 March 2018 08:22 AM, David Lechner wrote:
>>>> +static struct resource dm644x_pll1_resources[] = {
>>>> + {
>>>> + .start = DAVINCI_PLL1_BASE,
>>>> + .end = DAVINCI_PLL1_BASE + SZ_4K - 1,
>>>
>>> The .end should be DAVINCI_PLL1_BASE + SZ_1K - 1, otherwise it prevents
>>> PLL2 from getting registered.
>>>
>>>> + .flags = IORESOURCE_MEM,
>>>> + },
>>>> +};
>>>> +
>>>> +static struct platform_device dm644x_pll1_device = {
>>>> + .name = "dm644x-pll1",
>>>> + .id = -1,
>>>> + .resource = dm644x_pll1_resources,
>>>> + .num_resources = ARRAY_SIZE(dm644x_pll1_resources),
>>>> +};
>>>> +
>>>> +static struct resource dm644x_pll2_resources[] = {
>>>> + {
>>>> + .start = DAVINCI_PLL2_BASE,
>>>> + .end = DAVINCI_PLL2_BASE + SZ_4K - 1,
>>>
>>> And this too should be fixed, else it prevents the PSC from getting
>>> registered.
>>>
>>>> + .flags = IORESOURCE_MEM,
>>>> + },
>>>> +};
>>>
>>> With these fixed, I still had to enable 'clk_ignore_unused' on DM644x
>>> EVM to get to NFS boot. I think root of the problem is that pm_runtime()
>>> APIs are not working in the legacy boot mode.
>>>
>>> This can be seen even on the DA850 LCDK in legacy boot. pm_genpd_summary
>>> in debugfs shows all domains are off and there are no devices registered
>>> under the "da850-psc1: emac" domain. NFS mounting still works on the
>>> DA850 LCDK because clk_summary shows enable and prepare count of 4 for
>>> emac. Not sure how that's happening. But on DM644x EVM, the emac clock
>>> enable count is 0.
>>>
>>> Still looking at whats going wrong here. I am testing your v8 branch
>>> with clk-davinci branch from clk-next merged to get the fixes Stephen
>>> made.
>>>
>>
>> In legacy mode, genpd is not being used. I didn't see any mechanism for
>
> Ah, I got stumped by the genpd related debug entries popping up.
> Probably something should be done to make sure they don't show up in
> legacy boot. And some comments to that effect in psc.c will help.
>
>> genpd lookup without device tree. So, we are still relying on the
>> matching in arch/arm/mach-davinci/pm_domain.c.
>
> This is fine. We just need legacy boot to keep working without regressions.
>
>>
>> I suspect we need to fix the clock lookups in
>> drivers/clk/davinci/psc-dm644x.c.
>>
>> LPSC_CLKDEV2(emac_clkdev, NULL, "davinci_emac.1",
>> "fck", "davinci_mdio.0");
>>
>> NULL might need to be changed to "fck" to be picked up by pm matching
>> and "davinci_emac.1" should be verified that it matches the actual EMAC
>> device name.
>
> NULL con_id matches what we have for DA850 and also what we had for
> DM644x prior to CCF conversion. So, I did not really suspect that. The
> device name does match. I will check what else could be going on based
> on your input.
This issue is because emac platform device is getting registered really
early on dm644x even before the clocks are ready in postcore_initcall().
I will send a patch fixing that.
Thanks,
Sekhar
On 04/03/2018 05:26 AM, Sekhar Nori wrote:
> On Friday 16 March 2018 08:22 AM, David Lechner wrote:
>> +static struct resource dm644x_pll1_resources[] = {
>> + {
>> + .start = DAVINCI_PLL1_BASE,
>> + .end = DAVINCI_PLL1_BASE + SZ_4K - 1,
>
> The .end should be DAVINCI_PLL1_BASE + SZ_1K - 1, otherwise it prevents
> PLL2 from getting registered.
>
>> + .flags = IORESOURCE_MEM,
>> + },
>> +};
>> +
>> +static struct platform_device dm644x_pll1_device = {
>> + .name = "dm644x-pll1",
>> + .id = -1,
>> + .resource = dm644x_pll1_resources,
>> + .num_resources = ARRAY_SIZE(dm644x_pll1_resources),
>> +};
>> +
>> +static struct resource dm644x_pll2_resources[] = {
>> + {
>> + .start = DAVINCI_PLL2_BASE,
>> + .end = DAVINCI_PLL2_BASE + SZ_4K - 1,
>
> And this too should be fixed, else it prevents the PSC from getting
> registered.
Thanks. I've checked and this needs to be fixed for dm646x, dm355 and
dm365 as well.
On Friday 16 March 2018 08:22 AM, David Lechner wrote:
> +static int __init of_davinci_timer_init(struct device_node *np)
> +{
> + struct clk *clk;
> +
> + clk = of_clk_get(np, 0);
> + if (IS_ERR(clk)) {
> + struct of_phandle_args clkspec;
> +
> + /*
> + * Fall back to using ref_clk if the actual clock is not
> + * available. This currently always happens because platform
> + * clocks (i.e PLLs and PSCs) are registered as platform
> + * devices and therefore are not available at this point in
> + * the boot process.
It seems to me that this is not going to be a temporary problem (or at
least will be around for quite a while). So, I think we can as well just
look for ref_clk directly.
> + */
> + clkspec.np = of_find_node_by_name(NULL, "ref_clk");
> + if (IS_ERR(clkspec.np)) {
> + pr_err("%s: No clock available for timer!\n", __func__);
> + return PTR_ERR(clkspec.np);
> + }
> + clk = of_clk_get_from_provider(&clkspec);
> + of_node_put(clkspec.np);
> + }
> +
> + davinci_timer_init(clk);
> +
> + return 0;
> +}
> +TIMER_OF_DECLARE(davinci_timer, "ti,davinci-timer", of_davinci_timer_init);
Here, I think we should use "ti,da850-timer" so we can change the fixed
clock we are looking for based on the SoC. At a minimum, we should have
"ti,da850-timer" in the DT along with "ti,davinci-timer".
BTW, I noticed that "ti,davinci-timer" is not documented. I think we
need to add a binding documentation too.
Thanks,
Sekhar
On Friday 16 March 2018 08:22 AM, David Lechner wrote:
> This changes davinci_timer_init() so that we pass the clock as a
> parameter instead of using clk_get(). This is done in preparation
> for converting to the common clock framework.
>
> It removes the requirement that we have to have a clock with con_id
> of "timer0", which will be good for DT bindings since clock-names =
> "timer0" doesn't really make sense.
>
> Additionally, when we convert to the common clock framework, most of
> the clocks will be platform devices, which will not be available at
> this point during the boot process, so we will need to pass a clock
> that is available (i.e. ref_clk) instead of the "timer0" clock.
>
> NB: The comment added in time.c is not entirely true when this patch
> is applied, but it will be correct once the conversion to the common
> clock framework is complete in subsequent patches.
I think its better to add the comment when its actually applicable, even
if it needs to be a separate patch.
>
> Also, drop use of extern in header file since we are touching the
> definition.
>
> Signed-off-by: David Lechner <[email protected]>
> -
> -void __init davinci_timer_init(void)
> +void __init davinci_timer_init(struct clk *timer_clk)
> {
> - struct clk *timer_clk;
> struct davinci_soc_info *soc_info = &davinci_soc_info;
> unsigned int clockevent_id;
> unsigned int clocksource_id;
> @@ -373,7 +371,14 @@ void __init davinci_timer_init(void)
> }
> }
>
> - timer_clk = clk_get(NULL, "timer0");
> + /*
> + * REVISIT: Currently, timer_clk will be "ref_clk". However, the actual
> + * clock for this device comes from a PLL AUXCLK or a PSC clock
> + * (depending on the SoC). The PLL and PSC clocks are not registered
> + * until later in boot because they are platform devices. We should try
> + * again later to get the real clock so that the real clock is not
> + * turned off when disabling unused clocks, which would stop the timer.
This disabling later should not happen because you have the timer clocks
marked as LPSC_ALWAYS_ENABLED which translates to CLK_IS_CRITICAL and
that should make sure they are never disabled.
The issue should be documented is that we depend on bootloader leaving
the timer0 enabled on DM355, DM365, DM644x and DM646x. Of these, I have
tested only DM644x so far. I will check others and see the status of
timer0 there.
Its not really a great situation here, but I don't have a good
alternative to suggest as well if having genpd support in PSC means we
cannot be using CLK_OF_DECLARE().
Thanks,
Sekhar