[PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code
There are 5 LSB bits defined in PDSTAT and the code currently uses a mask of 1 bit to check the status. Also there is PDSTAT and PDCTL registers defined for ARM domain and DSP domain where as the code always read the ARM PDSTAT register and DSP PDCTL register. This patch fixes these issues. Reviewed-by: Sergei Shtylyov Signed-off-by: Murali Karicheri --- comments against previous version of the patch addressed:- - Moved the bug fix to a separate patch arch/arm/mach-davinci/include/mach/psc.h |2 +- arch/arm/mach-davinci/psc.c | 19 ++- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index 47fd0bc..63c4366 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h @@ -233,7 +233,7 @@ #define PTCMD 0x120 #define PTSTAT 0x128 #define PDSTAT 0x200 -#define PDCTL1 0x304 +#define PDCTL 0x300 #define MDSTAT 0x800 #define MDCTL 0xA00 diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c index 1fb6bdf..f157d9c 100644 --- a/arch/arm/mach-davinci/psc.c +++ b/arch/arm/mach-davinci/psc.c @@ -52,7 +52,7 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) void davinci_psc_config(unsigned int domain, unsigned int ctlr, unsigned int id, bool enable, u32 flags) { - u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl; + 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; @@ -79,11 +79,11 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, mdctl |= MDCTL_FORCE; __raw_writel(mdctl, psc_base + MDCTL + 4 * id); - pdstat = __raw_readl(psc_base + PDSTAT); - if ((pdstat & 0x0001) == 0) { - pdctl1 = __raw_readl(psc_base + PDCTL1); - pdctl1 |= 0x1; - __raw_writel(pdctl1, psc_base + PDCTL1); + pdstat = __raw_readl(psc_base + PDSTAT + 4 * domain); + if ((pdstat & 0x1F) == 0) { + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); + pdctl |= 0x1; + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); ptcmd = 1 << domain; __raw_writel(ptcmd, psc_base + PTCMD); @@ -92,9 +92,10 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, epcpr = __raw_readl(psc_base + EPCPR); } while epcpr >> domain) & 1) == 0)); - pdctl1 = __raw_readl(psc_base + PDCTL1); - pdctl1 |= 0x100; - __raw_writel(pdctl1, psc_base + PDCTL1); + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); + pdctl |= 0x100; + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); + } else { ptcmd = 1 << domain; __raw_writel(ptcmd, psc_base + PTCMD); -- 1.7.0.4 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v2 2/2] ARM: davinci: enhancement to support multiple power domains
In one of the new SoC that we are working on, there are multiple power domains similar to that in C6670. Currently clock module assumes that there are only two power domains (ARM and DSP). This patch enhances the code to support more than two power domains and will allow porting of Linux on to the above SoC. Reviewed-by :Sergei Shtylyov Signed-off-by: Murali Karicheri --- comments against previous version addressed:- - Moved the bug fix in the psc code to a separate patch arch/arm/mach-davinci/clock.c | 13 +++-- arch/arm/mach-davinci/clock.h | 10 +- arch/arm/mach-davinci/dm644x.c |4 ++-- arch/arm/mach-davinci/dm646x.c |2 +- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index 0086113..008772e 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -31,19 +31,12 @@ static LIST_HEAD(clocks); static DEFINE_MUTEX(clocks_mutex); static DEFINE_SPINLOCK(clockfw_lock); -static unsigned psc_domain(struct clk *clk) -{ - return (clk->flags & PSC_DSP) - ? DAVINCI_GPSC_DSPDOMAIN - : DAVINCI_GPSC_ARMDOMAIN; -} - static void __clk_enable(struct clk *clk) { if (clk->parent) __clk_enable(clk->parent); if (clk->usecount++ == 0 && (clk->flags & CLK_PSC)) - davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, + davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc, true, clk->flags); } @@ -53,7 +46,7 @@ static void __clk_disable(struct clk *clk) return; if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) && (clk->flags & CLK_PSC)) - davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, + davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc, false, clk->flags); if (clk->parent) __clk_disable(clk->parent); @@ -237,7 +230,7 @@ static int __init clk_disable_unused(void) pr_debug("Clocks: disable unused %s\n", ck->name); - davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc, + davinci_psc_config(ck->domain, ck->gpsc, ck->lpsc, false, ck->flags); } spin_unlock_irq(&clockfw_lock); diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index a705f36..46f0f1b 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h @@ -93,6 +93,7 @@ struct clk { u8 usecount; u8 lpsc; u8 gpsc; + u8 domain; u32 flags; struct clk *parent; struct list_headchildren; /* list of children */ @@ -107,11 +108,10 @@ struct clk { /* Clock flags: SoC-specific flags start at BIT(16) */ #define ALWAYS_ENABLED BIT(1) #define CLK_PSCBIT(2) -#define PSC_DSPBIT(3) /* PSC uses DSP domain, not ARM */ -#define CLK_PLLBIT(4) /* PLL-derived clock */ -#define PRE_PLLBIT(5) /* source is before PLL mult/div */ -#define PSC_SWRSTDISABLE BIT(6) /* Disable state is SwRstDisable */ -#define PSC_FORCE BIT(7) /* Force module state transtition */ +#define CLK_PLLBIT(3) /* PLL-derived clock */ +#define PRE_PLLBIT(4) /* source is before PLL mult/div */ +#define PSC_SWRSTDISABLE BIT(5) /* Disable state is SwRstDisable */ +#define PSC_FORCE BIT(6) /* Force module state transtition */ #define CLK(dev, con, ck) \ { \ diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 555ff5b..f38c4bb 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -130,7 +130,7 @@ static struct clk dsp_clk = { .name = "dsp", .parent = &pll1_sysclk1, .lpsc = DAVINCI_LPSC_GEM, - .flags = PSC_DSP, + .domain = DAVINCI_GPSC_DSPDOMAIN, .usecount = 1, /* REVISIT how to disable? */ }; @@ -145,7 +145,7 @@ static struct clk vicp_clk = { .name = "vicp", .parent = &pll1_sysclk2, .lpsc = DAVINCI_LPSC_IMCOP, - .flags = PSC_DSP, + .domain = DAVINCI_GPSC_DSPDOMAIN, .usecount = 1, /* REVISIT how to disable? */ }; diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 552031e..5bec8b6 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -160,7 +160,7
[PATCH] davinci: pdctl next bit position incorrect
The PDCTL NEXT bit is incorrectly set to bit 1 instead of bit 0. This patch fixes this issue Signed-off-by: Murali Karicheri --- arch/arm/mach-davinci/include/mach/psc.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index 39bf6ae..a03b8ba 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h @@ -298,7 +298,7 @@ #define MDSTAT_STATE_MASK 0x3f #define PDSTAT_STATE_MASK 0x1f #define MDCTL_FORCEBIT(31) -#define PDCTL_NEXT BIT(1) +#define PDCTL_NEXT BIT(0) #define PDCTL_EPCGOOD BIT(8) #ifndef __ASSEMBLER__ -- 1.7.4.1 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH] arm:davinci: clk - migrate to new common clock API
As a first step towards migrating davinci platforms to use common clock framework, replace all instances of clk_enable() with clk_prepare_enable() and clk_disable() with clk_disable_unprepare(). Until the platform is switched to use the CONFIG_HAVE_CLK_PREPARE Kconfig variable, this just adds a might_sleep() call and would work without any issues. This will make it easy later to switch to common clk based implementation of clk driver from DaVinci specific driver. Signed-off-by: Murali Karicheri --- 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 |4 ++-- arch/arm/mach-davinci/board-dm644x-evm.c|2 +- arch/arm/mach-davinci/board-neuros-osd2.c |2 +- arch/arm/mach-davinci/devices-da8xx.c |6 +++--- arch/arm/mach-davinci/serial.c |2 +- arch/arm/mach-davinci/time.c|4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index 1c7b1f4..4821fba 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -324,7 +324,7 @@ static __init void dm355_evm_init(void) if (IS_ERR(aemif)) WARN("%s: unable to get AEMIF clock\n", __func__); else - clk_enable(aemif); + clk_prepare_enable(aemif); platform_add_devices(davinci_evm_devices, ARRAY_SIZE(davinci_evm_devices)); diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c index 8e77032..b754ccf 100644 --- a/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/arch/arm/mach-davinci/board-dm355-leopard.c @@ -246,7 +246,7 @@ static __init void dm355_leopard_init(void) if (IS_ERR(aemif)) WARN("%s: unable to get AEMIF clock\n", __func__); else - clk_enable(aemif); + clk_prepare_enable(aemif); platform_add_devices(davinci_leopard_devices, ARRAY_SIZE(davinci_leopard_devices)); diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 2830692..3a4743b 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -481,7 +481,7 @@ static void __init evm_init_cpld(void) aemif_clk = clk_get(NULL, "aemif"); if (IS_ERR(aemif_clk)) return; - clk_enable(aemif_clk); + clk_prepare_enable(aemif_clk); if (request_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE, "cpld") == NULL) @@ -492,7 +492,7 @@ static void __init evm_init_cpld(void) SECTION_SIZE); fail: pr_err("ERROR: can't map CPLD\n"); - clk_disable(aemif_clk); + clk_disable_unprepare(aemif_clk); return; } diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index d34ed55..04ef708 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -775,7 +775,7 @@ static __init void davinci_evm_init(void) struct davinci_soc_info *soc_info = &davinci_soc_info; aemif_clk = clk_get(NULL, "aemif"); - clk_enable(aemif_clk); + clk_prepare_enable(aemif_clk); if (HAS_ATA) { if (HAS_NAND || HAS_NOR) diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index 5de69f2..7fdd0a7b 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c @@ -221,7 +221,7 @@ static __init void davinci_ntosd2_init(void) int status; aemif_clk = clk_get(NULL, "aemif"); - clk_enable(aemif_clk); + clk_prepare_enable(aemif_clk); if (HAS_ATA) { if (HAS_NAND) diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index d1624a3..20141f5 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -905,7 +905,7 @@ static int da850_sata_init(struct device *dev, void __iomem *addr) if (IS_ERR(da850_sata_clk)) return PTR_ERR(da850_sata_clk); - ret = clk_enable(da850_sata_clk); + ret = clk_prepare_enable(da850_sata_clk); if (ret) goto err0; @@ -936,7 +936,7 @@ static int da850_sata_init(struct device *dev, void __iomem *addr) return 0; err1: - clk_disable(da850_sata_clk); + clk_disable_unprepare(da850_sata_clk); err0: clk_put(da850_sata_clk); return ret; @@ -944,7 +944,7 @@ err0: static void da850_sata_exit(struct dev
[PATCH] i2c:clk: preparation for switch to common clock framework
As a first step towards migrating davinci platforms to use common clock framework, replace all instances of clk_enable() with clk_prepare_enable() and clk_disable() with clk_disable_unprepare(). Until the platform is switched to use the CONFIG_HAVE_CLK_PREPARE Kconfig variable, this just adds a might_sleep() call and would work without any issues. This will make it easy later to switch to common clk based implementation of clk driver from DaVinci specific driver. Signed-off-by: Murali Karicheri --- drivers/i2c/busses/i2c-davinci.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 79b4bcb..8e47ec1 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -681,7 +681,7 @@ static int davinci_i2c_probe(struct platform_device *pdev) r = -ENODEV; goto err_free_mem; } - clk_enable(dev->clk); + clk_prepare_enable(dev->clk); dev->base = ioremap(mem->start, resource_size(mem)); if (!dev->base) { @@ -726,7 +726,7 @@ err_free_irq: err_unuse_clocks: iounmap(dev->base); err_mem_ioremap: - clk_disable(dev->clk); + clk_disable_unprepare(dev->clk); clk_put(dev->clk); dev->clk = NULL; err_free_mem: @@ -750,7 +750,7 @@ static int davinci_i2c_remove(struct platform_device *pdev) i2c_del_adapter(&dev->adapter); put_device(&pdev->dev); - clk_disable(dev->clk); + clk_disable_unprepare(dev->clk); clk_put(dev->clk); dev->clk = NULL; @@ -772,7 +772,7 @@ static int davinci_i2c_suspend(struct device *dev) /* put I2C into reset */ davinci_i2c_reset_ctrl(i2c_dev, 0); - clk_disable(i2c_dev->clk); + clk_disable_unprepare(i2c_dev->clk); return 0; } @@ -782,7 +782,7 @@ static int davinci_i2c_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev); - clk_enable(i2c_dev->clk); + clk_prepare_enable(i2c_dev->clk); /* take I2C out of reset */ davinci_i2c_reset_ctrl(i2c_dev, 1); -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 0/1 ] i2c:clk: preparation for switch to common clock framework
Hi i2c subsystem maintainer, Re-sending since the previous patch seems to have not made it to the mailing list.. I am working to migrate DaVinci SoCs to common clock framwork. I am hoping to have this patch merged to linux-next for v3.6 so that mach-davinci patches for clock framework change can be reviewed and merged in subsequent releases. Please merge this to your linux-next tree for v3.6 Thanks Murali Karicheri (1): i2c:clk: preparation for switch to common clock framework drivers/i2c/busses/i2c-davinci.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 1/1] i2c:clk: preparation for switch to common clock framework
As a first step towards migrating davinci platforms to use common clock framework, replace all instances of clk_enable() with clk_prepare_enable() and clk_disable() with clk_disable_unprepare(). Until the platform is switched to use the CONFIG_HAVE_CLK_PREPARE Kconfig variable, this just adds a might_sleep() call and would work without any issues. This will make it easy later to switch to common clk based implementation of clk driver from DaVinci specific driver. Signed-off-by: Murali Karicheri diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index b6185dc..85ce548 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -704,7 +704,7 @@ static int davinci_i2c_probe(struct platform_device *pdev) r = -ENODEV; goto err_free_mem; } - clk_enable(dev->clk); + clk_prepare_enable(dev->clk); dev->base = ioremap(mem->start, resource_size(mem)); if (!dev->base) { @@ -751,7 +751,7 @@ err_free_irq: err_unuse_clocks: iounmap(dev->base); err_mem_ioremap: - clk_disable(dev->clk); + clk_disable_unprepare(dev->clk); clk_put(dev->clk); dev->clk = NULL; err_free_mem: @@ -775,7 +775,7 @@ static int davinci_i2c_remove(struct platform_device *pdev) i2c_del_adapter(&dev->adapter); put_device(&pdev->dev); - clk_disable(dev->clk); + clk_disable_unprepare(dev->clk); clk_put(dev->clk); dev->clk = NULL; @@ -797,7 +797,7 @@ static int davinci_i2c_suspend(struct device *dev) /* put I2C into reset */ davinci_i2c_reset_ctrl(i2c_dev, 0); - clk_disable(i2c_dev->clk); + clk_disable_unprepare(i2c_dev->clk); return 0; } @@ -807,7 +807,7 @@ static int davinci_i2c_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev); - clk_enable(i2c_dev->clk); + clk_prepare_enable(i2c_dev->clk); /* take I2C out of reset */ davinci_i2c_reset_ctrl(i2c_dev, 1); -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 1/1] spi:clk: preparation for switch to common clock framework
As a first step towards migrating davinci platforms to use common clock framework, replace all instances of clk_enable() with clk_prepare_enable() and clk_disable() with clk_disable_unprepare(). Until the platform is switched to use the CONFIG_HAVE_CLK_PREPARE Kconfig variable, this just adds a might_sleep() call and would work without any issues. This will make it easy later to switch to common clk based implementation of clk driver from DaVinci specific driver. Signed-off-by: Murali Karicheri Reviewed-by: Mike Turquette diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index c1ec52d..3f54f9e 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -843,7 +843,7 @@ static int __devinit davinci_spi_probe(struct platform_device *pdev) ret = -ENODEV; goto put_master; } - clk_enable(dspi->clk); + clk_prepare_enable(dspi->clk); master->bus_num = pdev->id; master->num_chipselect = pdata->num_chipselect; @@ -927,7 +927,7 @@ free_dma: dma_release_channel(dspi->dma_rx); dma_release_channel(dspi->dma_tx); free_clk: - clk_disable(dspi->clk); + clk_disable_unprepare(dspi->clk); clk_put(dspi->clk); put_master: spi_master_put(master); @@ -963,7 +963,7 @@ static int __devexit davinci_spi_remove(struct platform_device *pdev) spi_bitbang_stop(&dspi->bitbang); - clk_disable(dspi->clk); + clk_disable_unprepare(dspi->clk); clk_put(dspi->clk); spi_master_put(master); free_irq(dspi->irq, dspi); -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 0/1] spi:clk: preparation for switch to common clock framework
Hi spi subsystem maintainer, I am working to migrate DaVinci SoCs to common clock framwork. I am hoping to have this patch merged to linux-next for v3.6 so that mach-davinci patches for clock framework change can be reviewed and merged in subsequent releases. Please merge this to your linux-next tree for v3.6 Thanks Murali Karicheri (1): spi:clk: preparation for switch to common clock framework drivers/spi/spi-davinci.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 1/1] wdt:clk: preparation for switch to common clock framework
As a first step towards migrating davinci platforms to use common clock framework, replace all instances of clk_enable() with clk_prepare_enable() and clk_disable() with clk_disable_unprepare(). Until the platform is switched to use the CONFIG_HAVE_CLK_PREPARE Kconfig variable, this just adds a might_sleep() call and would work without any issues. This will make it easy later to switch to common clk based implementation of clk driver from DaVinci specific driver. Signed-off-by: Murali Karicheri Reviewed-by: Mike Turquette diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index c8c5c80..eb44b03 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c @@ -208,7 +208,7 @@ static int __devinit davinci_wdt_probe(struct platform_device *pdev) if (WARN_ON(IS_ERR(wdt_clk))) return PTR_ERR(wdt_clk); - clk_enable(wdt_clk); + clk_prepare_enable(wdt_clk); if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) heartbeat = DEFAULT_HEARTBEAT; @@ -256,7 +256,7 @@ static int __devexit davinci_wdt_remove(struct platform_device *pdev) wdt_mem = NULL; } - clk_disable(wdt_clk); + clk_disable_unprepare(wdt_clk); clk_put(wdt_clk); return 0; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 0/1] wdt:clk: preparation for switch to common clock framework
Hi wdt subsystem maintainer, Re-sending since the previous patch seems to have not made it to the mailing list.. I am working to migrate DaVinci SoCs to common clock framwork. I am hoping to have this patch merged to linux-next for v3.6 so that mach-davinci patches for clock framework change can be reviewed and merged in subsequent releases. Please merge this to your linux-next tree for v3.6 Thanks Murali Karicheri (1): wdt:clk: preparation for switch to common clock framework drivers/watchdog/davinci_wdt.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 1/1] mtd:nand:clk: preparation for switch to common clock framework
As a first step towards migrating davinci platforms to use common clock framework, replace all instances of clk_enable() with clk_prepare_enable() and clk_disable() with clk_disable_unprepare(). Until the platform is switched to use the CONFIG_HAVE_CLK_PREPARE Kconfig variable, this just adds a might_sleep() call and would work without any issues. This will make it easy later to switch to common clk based implementation of clk driver from DaVinci specific driver. Signed-off-by: Murali Karicheri Reviewed-by: Mike Turquette diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index f386b3c..df1ab7d 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -724,7 +724,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev) goto err_clk; } - ret = clk_enable(info->clk); + ret = clk_prepare_enable(info->clk); if (ret < 0) { dev_dbg(&pdev->dev, "unable to enable AEMIF clock, err %d\n", ret); @@ -835,7 +835,7 @@ syndrome_done: err_scan: err_timing: - clk_disable(info->clk); + clk_disable_unprepare(info->clk); err_clk_enable: clk_put(info->clk); @@ -872,7 +872,7 @@ static int __exit nand_davinci_remove(struct platform_device *pdev) nand_release(&info->mtd); - clk_disable(info->clk); + clk_disable_unprepare(info->clk); clk_put(info->clk); kfree(info); -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 0/1] mtd:nand:clk: preparation for switch to common clock
Hi subsystem maintainer, Re-sending after adding Reviewed-by in the commit log. I am working to migrate DaVinci SoCs to common clock framwork. I am hoping to have this patch merged to linux-next for v3.6 so that mach-davinci patches for clock framework change can be reviewed and merged in subsequent releases. Please merge this to your linux-next tree for v3.6 Thanks Murali Karicheri (1): mtd:nand:clk: preparation for switch to common clock framework drivers/mtd/nand/davinci_nand.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 0/1] mtd:nand:clk: preparation for switch to common clock
Hi Arnd, I am working to migrate DaVinci SoCs to common clock framwork. I have following prepare patch for davinci nand driver which is sitting in the list for some time. Could you merge this to linxu-next for v3.6? As the mach-davinci patches are dependent on this, getting this to v3.6 is important for an early migration of mach-davinci soc code to use common clock framework. Going through the sub system will delay the work.I got 2 other driver prepare patches merged already to linux-next through the subsystem tree (i2c and gpio). subsystem owners, Please respond if you have plan to merge this to your tree. Thanks Murali Karicheri (1): mtd:nand:clk: preparation for switch to common clock framework drivers/mtd/nand/davinci_nand.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 1/1] mtd:nand:clk: preparation for switch to common clock framework
As a first step towards migrating davinci platforms to use common clock framework, replace all instances of clk_enable() with clk_prepare_enable() and clk_disable() with clk_disable_unprepare(). Until the platform is switched to use the CONFIG_HAVE_CLK_PREPARE Kconfig variable, this just adds a might_sleep() call and would work without any issues. This will make it easy later to switch to common clk based implementation of clk driver from DaVinci specific driver. Signed-off-by: Murali Karicheri Reviewed-by: Mike Turquette diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index f386b3c..df1ab7d 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -724,7 +724,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev) goto err_clk; } - ret = clk_enable(info->clk); + ret = clk_prepare_enable(info->clk); if (ret < 0) { dev_dbg(&pdev->dev, "unable to enable AEMIF clock, err %d\n", ret); @@ -835,7 +835,7 @@ syndrome_done: err_scan: err_timing: - clk_disable(info->clk); + clk_disable_unprepare(info->clk); err_clk_enable: clk_put(info->clk); @@ -872,7 +872,7 @@ static int __exit nand_davinci_remove(struct platform_device *pdev) nand_release(&info->mtd); - clk_disable(info->clk); + clk_disable_unprepare(info->clk); clk_put(info->clk); kfree(info); -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 0/1] wdt:clk: preparation for switch to common clock framework
Hi Arnd, I am working to migrate DaVinci SoCs to common clock framwork. I have following prepare patch for davinci wdt driver which is sitting in the list for some time. Could you merge this to linxu-next for v3.6? As the mach-davinci patches are dependent on this, getting this to v3.6 is important for an early migration of mach-davinci soc code to use common clock framework. Going through the sub system will delay the work. I got 2 other driver prepare patches merged already to linux-next through the subsystem tree (i2c and gpio). subsystem owners, Please respond if you have plan to merge this to your tree. Thanks Murali Karicheri (1): wdt:clk: preparation for switch to common clock framework drivers/watchdog/davinci_wdt.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 1/1] wdt:clk: preparation for switch to common clock framework
As a first step towards migrating davinci platforms to use common clock framework, replace all instances of clk_enable() with clk_prepare_enable() and clk_disable() with clk_disable_unprepare(). Until the platform is switched to use the CONFIG_HAVE_CLK_PREPARE Kconfig variable, this just adds a might_sleep() call and would work without any issues. This will make it easy later to switch to common clk based implementation of clk driver from DaVinci specific driver. Signed-off-by: Murali Karicheri Reviewed-by: Mike Turquette diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index c8c5c80..eb44b03 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c @@ -208,7 +208,7 @@ static int __devinit davinci_wdt_probe(struct platform_device *pdev) if (WARN_ON(IS_ERR(wdt_clk))) return PTR_ERR(wdt_clk); - clk_enable(wdt_clk); + clk_prepare_enable(wdt_clk); if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) heartbeat = DEFAULT_HEARTBEAT; @@ -256,7 +256,7 @@ static int __devexit davinci_wdt_remove(struct platform_device *pdev) wdt_mem = NULL; } - clk_disable(wdt_clk); + clk_disable_unprepare(wdt_clk); clk_put(wdt_clk); return 0; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 1/1] spi:clk: preparation for switch to common clock framework
As a first step towards migrating davinci platforms to use common clock framework, replace all instances of clk_enable() with clk_prepare_enable() and clk_disable() with clk_disable_unprepare(). Until the platform is switched to use the CONFIG_HAVE_CLK_PREPARE Kconfig variable, this just adds a might_sleep() call and would work without any issues. This will make it easy later to switch to common clk based implementation of clk driver from DaVinci specific driver. Signed-off-by: Murali Karicheri Reviewed-by: Mike Turquette diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index c1ec52d..3f54f9e 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -843,7 +843,7 @@ static int __devinit davinci_spi_probe(struct platform_device *pdev) ret = -ENODEV; goto put_master; } - clk_enable(dspi->clk); + clk_prepare_enable(dspi->clk); master->bus_num = pdev->id; master->num_chipselect = pdata->num_chipselect; @@ -927,7 +927,7 @@ free_dma: dma_release_channel(dspi->dma_rx); dma_release_channel(dspi->dma_tx); free_clk: - clk_disable(dspi->clk); + clk_disable_unprepare(dspi->clk); clk_put(dspi->clk); put_master: spi_master_put(master); @@ -963,7 +963,7 @@ static int __devexit davinci_spi_remove(struct platform_device *pdev) spi_bitbang_stop(&dspi->bitbang); - clk_disable(dspi->clk); + clk_disable_unprepare(dspi->clk); clk_put(dspi->clk); spi_master_put(master); free_irq(dspi->irq, dspi); -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 0/1] spi:clk: preparation for switch to common clock framework
Hi Arnd, I am working to migrate DaVinci SoCs to common clock framwork. I have following prepare patch for davinci spi driver which is sitting in the list for some time. Could you merge this to linxu-next for v3.6? As the mach-davinci patches are dependent on this, getting this to v3.6 is important for an early migration of mach-davinci soc code to use common clock framework. Going through the sub system will delay the work. I got 2 other driver prepare patches merged already to linux-next through the subsystem tree (i2c and gpio). subsystem owners, Please respond if you have plan to merge this to your tree. Thanks Murali Karicheri (1): spi:clk: preparation for switch to common clock framework drivers/spi/spi-davinci.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[RFC PATCH 01/10] clk:davinci - add Main PLL clock driver
This is the driver for the main PLL clock hardware found on DM SoCs. This driver borrowed code from arch/arm/mach-davinci/clock.c and implemented the driver as per common clock provider API. The main PLL hardware typically has a multiplier, a pre-divider and a post-divider. Some of the SoCs has the divider fixed meaning they can not be configured through a register. HAS_PREDIV and HAS_POSTDIV flags are used to tell the driver if a hardware has these dividers present or not. Driver is configured through the structure clk_davinci_pll_data that has the platform data for the driver. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/davinci/clk-davinci-pll.c b/drivers/clk/davinci/clk-davinci-pll.c new file mode 100644 index 000..13e1690 --- /dev/null +++ b/drivers/clk/davinci/clk-davinci-pll.c @@ -0,0 +1,128 @@ +/* + * PLL clk driver DaVinci devices + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * TODO - Add set_parent_rate() + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +#define PLLM 0x110 +#define PLLM_PLLM_MASK 0xff +#define PREDIV 0x114 +#define POSTDIV 0x128 +#define PLLDIV_EN BIT(15) + +/** + * struct clk_davinci_pll - DaVinci Main pll clock + * @hw: clk_hw for the pll + * @pll_data: PLL driver specific data + */ +struct clk_davinci_pll { + struct clk_hw hw; + struct clk_davinci_pll_data *pll_data; +}; + +#define to_clk_pll(_hw) container_of(_hw, struct clk_davinci_pll, hw) + +static unsigned long clk_pllclk_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_davinci_pll *pll = to_clk_pll(hw); + struct clk_davinci_pll_data *pll_data = pll->pll_data; + u32 mult = 1, prediv = 1, postdiv = 1; + unsigned long rate = parent_rate; + + /* If there is a device specific recalc defined invoke it. Otherwise +* fallback to default one +*/ + mult = __raw_readl(pll_data->pllm); + if (pll_data->pllm_multiplier) + mult = pll_data->pllm_multiplier * + (mult & pll_data->pllm_mask); + else + mult = (mult & pll_data->pllm_mask) + 1; + + if (pll_data->flags & CLK_DAVINCI_PLL_HAS_PREDIV) { + /* pre-divider is fixed, take prediv value from pll_data */ + if (pll_data->fixed_prediv) + prediv = pll_data->fixed_prediv; + else { + prediv = __raw_readl(pll_data->prediv); + if (prediv & PLLDIV_EN) + prediv = (prediv & pll_data->prediv_mask) + 1; + else + prediv = 1; + } + } + + if (pll_data->flags & CLK_DAVINCI_PLL_HAS_POSTDIV) { + postdiv = __raw_readl(pll_data->postdiv); + if (postdiv & PLLDIV_EN) + postdiv = (postdiv & pll_data->postdiv_mask) + 1; + else + postdiv = 1; + } + + rate /= prediv; + rate *= mult; + rate /= postdiv; + + pr_debug("PLL%d: input = %lu MHz [ ", +pll_data->num, parent_rate / 100); + 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 / 100); + return rate; +} + +static const struct clk_ops clk_pll_ops = { + .recalc_rate = clk_pllclk_recalc, +}; + +struct clk *clk_register_davinci_pll(struct device *dev, const char *name, + const char *parent_name, + struct clk_davinci_pll_data *pll_data) +{ + struct clk_init_data init; + struct clk_davinci_pll *pll; + struct clk *clk; + + if (!pll_data) + return ERR_PTR(-ENODEV); + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + init.name = name; + init.ops = &clk_pll_ops; + init.flags = pll_data->flags; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + pll->pll_data = pll_data; + pll->hw.init = &init; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) + kfree(pll); + +
[RFC PATCH 00/10] Use common clk drivers for DaVinci
This is the RFC patch for implementing clock tree for DaVinci SoCs using common clk framework. Currently arch/arm/mach-davinci/clock.c and arch/arm/mach-davinci/psc.c implements clock drivers for DaVinci. This patch makes these code obsolete and migrate the SoC code to use the common clk based drivers and initialization. This adds two clk drivers specific to DaVinci and Keystone (found in c6x arch such as C6678) devices. Some of the existing clk drivers such as clk-fixed-rate, clk-divider, and clk-mux are re-used in addition to the DaVinci specific drivers to initialize the clock tree for the SoCs. The figure below is provided to help understand the hardware and the code implemented in this patch and more details can be found in SoC specific documentation from Texas Instruments. The figure below is borrowed from chapter 6 of http://www.ti.com/lit/ug/sprue14c/sprue14c.pdf |---||-| |---||| CLKIN -| || PLL | | ||PLLDIV1 |--SYSCLK1 | MUX || mult|---| MUX ||| OSCIN -| | | | div | | | | || |---| | |-| |---|---| ---|PLLDIV2 |--SYSCLK2 | | ||| -- CLKMODE |---| PLLEN |... | | || | ---|PLLDIV5 |--SYSCLK5 |-- |AUXCLK | || |--| BPDIV |---SYSCLKBP || Main PLL1 structure in DM644x There are two Main PLLs in DM644x. PLL1 and PLL2. Each of these generate different clocks in the DM device through PLL dividers. Figure above shows this for PLL1. Similar hardware exists for PLL2 and the related output clocks. The hardware is similar in most of the DM SoCs. Some of the recent Keystone devices (c6678 under c6x architecture) include a slight variant of the PLL that implemented different registers for the multipliers and dividers. All of these devices include PLL dividers (PLLDIVx) and Power Sleep controllers (PSC). The SoCs defines various Power Domains and Clock domains and there are PSC modules that controls power and clocks to various hardware IPs of the SoC. Following drivers are used for various clock hardware blocks:- CLKIN and OSCIN - clk-fixed-rate (existing driver) MUX - clk-mux (existing driver) PLLDIVx - clk-divider (existing driver) PLL mult/div - clk-davinci-pll (new driver) clk-keystone-pll (new driver) PSC - clk-davinci-psc.c (new driver The patch series is split in two:- patch 1-5 for drivers and 6-10 for machine specific code. Please note that initially only DM644x is supported. The idea is to review the initial patch and get a feedback on the overall structure of the code organization. The other SoCs will be added in subsequent patch revisions. The driver code implements the features needed to support DM644x and is expected to be enhanced in subsequent patch revisions to support additional SoCs. I have boot tested this on DM6446 EVM I have. Also verified reboot command works and the clock rates are set as before. The patches depends on the following patches that I had sent for review earlier: davinci spi driver preparation @ https://patchwork.kernel.org/patch/1389321/ davinci watchdog driver preparation @ https://lkml.org/lkml/2012/9/7/634 davinci nand driver preparation @ https://lkml.org/lkml/2012/9/7/635 davinci i2c driver preparation @ https://patchwork.kernel.org/patch/1388841/ davinci gpio driver preparation @ https://lkml.org/lkml/2012/8/31/341 [RFC - PATCH] base:pm: prepare driver for common clock framework in the davinci mailing list Following are to be discussed as part of this patch review. 1. arch/arm/pm.c. This is configuring PLL controller registers for suspend and resume. It appears that we need to move this code to clk-davinci-pll.c. But I can't find APIs for suspend and resume in the common clk framework. How is this expected to work? Currently i have kept the code ASIS. 2. There are usecount=1 in the old clock implementation for dsp, vicp and timer2 clocks. CLK_IGNORE_UNUSED flag is used currently to implement the same as disabling these unused clocks causes issues in boot up, NOTE: I am doing this work as a background activity and hence the progress will be slow. Please volunteer to help me in this effort by offering to test or migrating other devices to this framework. Murali Karicheri (10): clk:davinci - add Main PLL clock driver clk:davinci - add PSC clock driver clk:keystone - add Main PLL clock driver clk:davinci - common clk driver initialization clk:davinci - add build infrastructure ARM:davinci - restructure header files for c
[RFC PATCH 02/10] clk:davinci - add PSC clock driver
This is the driver for the Power Sleep Controller (PSC) hardware found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed code from arch/arm/mach-davinci/psc.c and implemented the driver as per common clock provider API. The PSC module is responsible for enabling/disabling the Power Domain and Clock domain for different IPs present in the SoC. The driver is configured through the platform data structure struct clk_davinci_psc_data. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/davinci/clk-davinci-psc.c b/drivers/clk/davinci/clk-davinci-psc.c new file mode 100644 index 000..b7aa332 --- /dev/null +++ b/drivers/clk/davinci/clk-davinci-psc.c @@ -0,0 +1,197 @@ +/* + * PSC clk driver for DaVinci devices + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include + +/* PSC register offsets */ +#define EPCPR 0x070 +#define PTCMD 0x120 +#define PTSTAT 0x128 +#define PDSTAT 0x200 +#define PDCTL 0x300 +#define MDSTAT 0x800 +#define MDCTL 0xA00 + +/* PSC module states */ +#define PSC_STATE_SWRSTDISABLE 0 +#define PSC_STATE_SYNCRST 1 +#define PSC_STATE_DISABLE 2 +#define PSC_STATE_ENABLE 3 + +#define MDSTAT_STATE_MASK 0x3f +#define PDSTAT_STATE_MASK 0x1f +#define MDCTL_FORCEBIT(31) +#define PDCTL_NEXT BIT(0) +#define PDCTL_EPCGOOD BIT(8) + +/* PSC flags */ +#define PSC_SWRSTDISABLE BIT(0) /* Disable state is SwRstDisable */ +#define PSC_FORCE BIT(1) /* Force module state transtition */ +#define PSC_HAS_EXT_POWER_CNTL BIT(2) /* PSC has external power control + * available (for DM6446 SoC) */ +/** + * struct clk_psc - DaVinci PSC clock + * @hw: clk_hw for the psc + * @psc_data: PSC driver specific data + * @lock: Spinlock used by the driver + */ +struct clk_psc { + struct clk_hw hw; + struct clk_davinci_psc_data *psc_data; + spinlock_t *lock; +}; + +#define to_clk_psc(_hw) container_of(_hw, struct clk_psc, hw) + +/* Enable or disable a PSC domain */ +static void clk_psc_config(void __iomem *base, unsigned int domain, + unsigned int id, bool enable, u32 flags) +{ + u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl; + u32 next_state = PSC_STATE_ENABLE; + void __iomem *psc_base = base; + + if (!enable) { + if (flags & 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); + + if (flags & PSC_HAS_EXT_POWER_CNTL) { + do { + epcpr = __raw_readl(psc_base + EPCPR); + } while epcpr >> domain) & 1) == 0)); + } + + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); + pdctl |= 0x100; + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); + + 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)); +} + +static int clk_psc_is_enabled(struct clk_hw *hw) +{ + struct clk_psc *psc = to_clk_psc(hw); + struct clk_davinci_psc_data *psc_data = psc->psc_data; + u32 mdstat; + + mdstat = __raw_readl(psc_data->base + MDSTAT + 4 * psc_data->lpsc); + /* if clocked, state can be "Enable" or "SyncReset" */ +
[RFC PATCH 04/10] clk:davinci - common clk driver initialization
This is the common clk driver initialization function for DaVinci SoCs and other SoCs that uses similar hardware architecture. Different clocks present in the SoC are passed to this function using a clk table and this function initialize the various drivers. Existing driver such as clk-fixed-rate, clk-divider, clk-mux and DaVinci specific clk drivers are initialized by this function. Also adds clock lookup for shared clocks used by various drivers. davinci-clock.h declares the various structures used for defining the DaVinci clocks. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/davinci/davinci-clock.c b/drivers/clk/davinci/davinci-clock.c new file mode 100644 index 000..a791888 --- /dev/null +++ b/drivers/clk/davinci/davinci-clock.c @@ -0,0 +1,210 @@ +/* + * Clock initialization code for DaVinci devices + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_SPINLOCK(_lock); + +struct clk *davinci_lookup_clk(struct davinci_clk_lookup *clocks, + const char *con_id) +{ + struct davinci_clk_lookup *c; + + for (c = clocks; c->_clk; c++) { + if (c->con_id && !strcmp(c->con_id, con_id)) + return c->clk; + } + return NULL; +} + +#ifdef CONFIG_CLK_DAVINCI_PLL +static void register_davinci_pll_clk(struct davinci_clk_lookup *c, + struct clk_davinci_pll_data *pll_data) +{ + + WARN_ON(!pll_data->phy_pllm); + pll_data->pllm = ioremap(pll_data->phy_pllm, 4); + WARN_ON(!pll_data->pllm); + if (pll_data->phy_prediv) { + pll_data->prediv = ioremap(pll_data->phy_prediv, 4); + WARN_ON(!pll_data->prediv); + } + if (pll_data->phy_postdiv) { + pll_data->postdiv = ioremap(pll_data->phy_postdiv, 4); + WARN_ON(!pll_data->postdiv); + } + c->clk = clk_register_davinci_pll(NULL, + c->_clk->name, c->_clk->parent->name, + pll_data); +} +#else +static void register_davinci_pll_clk(struct davinci_clk_lookup *c, + struct clk_davinci_pll_data *pll_data) +{ + return; +} +#endif + +#ifdef CONFIG_CLK_KEYSTONE_PLL +static void register_keystone_pll_clk(struct davinci_clk_lookup *c, + struct clk_keystone_pll_data *pll_data) +{ + WARN_ON(!pll_data->phy_pllm); + pll_data->pllm = ioremap(pll_data->phy_pllm, 4); + WARN_ON(!pll_data->pllm); + WARN_ON(!pll_data->phy_main_pll_ctl0); + pll_data->main_pll_ctl0 = + ioremap(pll_data->phy_main_pll_ctl0, 4); + WARN_ON(!pll_data->main_pll_ctl0); + c->clk = clk_register_keystone_pll(NULL, + c->_clk->name, c->_clk->parent->name, +pll_data); +} +#else +static void register_keystone_pll_clk(struct davinci_clk_lookup *c, + struct clk_keystone_pll_data *pll_data) +{ + return; +} +#endif + +int __init davinci_common_clk_init(struct davinci_clk_lookup *clocks, + struct davinci_dev_lookup *dev_clk_lookups, + u8 num_gpscs, u32 *psc_bases) +{ + void __iomem **base = NULL, *reg; + struct davinci_clk_lookup *c; + struct davinci_clk *_clk; + unsigned long rate; + int i, skip; + + WARN_ON(!num_gpscs); + WARN_ON(psc_bases == NULL); + + base = kzalloc(sizeof(void __iomem *) * num_gpscs, GFP_KERNEL); + WARN_ON(!base); + for (i = 0; i < num_gpscs; i++) { + base[i] = ioremap(psc_bases[i], SZ_4K); + WARN_ON(!base[i]); + } + + for (c = clocks; c->_clk; c++) { + skip = 0; + _clk = c->_clk; + + if (_clk->ref_clk_data) { + /* root node */ + struct clk_fixed_data *ref_clk_dat = _clk->ref_clk_data; + + if (ref_clk_dat->recalc) + rate = ref_clk_dat->recalc(0); + else + rate = ref_clk_dat->rate; + + c->clk = clk_register_fixed_rate(NULL, _clk->name, + NULL, ref_clk_dat->flags, rate); + } else if (_clk->pll_data.main_pll) { + /* This is a PLL clock */ + if
[RFC PATCH 06/10] ARM:davinci - restructure header files for common clk migration
As part of migrating to common clk framework usage in DaVinci SoCs, clock.h and clock.c are being deprecated as the pll and psc clock drivers are moved to drivers/clk/davinci. The relevant PLL defines are moved to include/mach/pll.h and will be used by SoC specific code instead of using clock.h. The psc.c code is being deprecated as the psc specific code is moved to the drivers/clk/davinci. So the extern definitions are not used anymore and is now conditionally included. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/include/mach/pll.h b/arch/arm/mach-davinci/include/mach/pll.h new file mode 100644 index 000..a76b349 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/pll.h @@ -0,0 +1,81 @@ +/* + * TI DaVinci PLL definitions + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __ASM_ARCH_PLL_H +#define __ASM_ARCH_PLL_H + +#define DAVINCI_PLL1_BASE 0x01c40800 +#define DAVINCI_PLL2_BASE 0x01c40c00 +#define MAX_PLL 2 + +/* PLL/Reset register offsets */ +#define PLLCTL 0x100 +#define PLLCTL_PLLENBIT(0) +#define PLLCTL_PLLPWRDNBIT(1) +#define PLLCTL_PLLRST BIT(3) +#define PLLCTL_PLLDIS BIT(4) +#define PLLCTL_PLLENSRCBIT(5) +#define PLLCTL_CLKMODE BIT(8) + +#define PLLCTL_CLKMODE_SHIFT 8 +#define PLLCTL_CLKMODE_WIDTH 1 +#define PLLCTL_PLLEN_SHIFT 0 +#define PLLCTL_PLLEN_WIDTH 1 + +#define PLLDIV1 0x118 +#define PLLDIV2 0x11c +#define PLLDIV3 0x120 +#define BPDIV 0x12c +#define PLLCMD 0x138 +#define PLLSTAT0x13c +#define PLLALNCTL 0x140 +#define PLLDCHANGE 0x144 +#define PLLCKEN0x148 +#define PLLCKSTAT 0x14c +#define PLLSYSTAT 0x150 +#define PLLDIV4 0x160 +#define PLLDIV5 0x164 +#define PLLDIV6 0x168 +#define PLLDIV7 0x16c +#define PLLDIV8 0x170 +#define PLLDIV9 0x174 +#define PLLDIV100x178 +#define PLLDIV110x17c +#define PLLDIV120x180 +#define PLLDIV130x184 +#define PLLDIV140x188 +#define PLLDIV150x18c +#define PLLDIV160x190 +#define PLLDIV_RATIO_MASK 0x1f +#define PLLDIV_EN BIT(15) + +/* + * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN + * cycles to ensure that the PLLC has switched to bypass mode. Delay of 1us + * ensures we are good for all > 4MHz OSCIN/CLKIN inputs. Typically the input + * is ~25MHz. Units are micro seconds. + */ +#define PLL_BYPASS_TIME1 +/* From OMAP-L138 datasheet table 6-4. Units are micro seconds */ +#define PLL_RESET_TIME 1 +/* + * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4 + * Units are micro seconds. + */ +#define PLL_LOCK_TIME 20 +#define PLLSTAT_GOSTAT BIT(0) +#define PLLCMD_GOSET BIT(0) + +#endif /* __ASM_ARCH_PLL_H */ diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index 405318e..6abb94c 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h @@ -251,9 +251,11 @@ #ifndef __ASSEMBLER__ +#ifndef CONFIG_COMMON_CLK extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id); extern void davinci_psc_config(unsigned int domain, unsigned int ctlr, unsigned int id, bool enable, u32 flags); +#endif #endif diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h index 1c971d8..7faa530 100644 --- a/arch/arm/mach-davinci/include/mach/time.h +++ b/arch/arm/mach-davinci/include/mach/time.h @@ -31,5 +31,7 @@ enum { #define ID_TO_TIMER(id)(IS_TIMER1(id) != 0) extern struct davinci_timer_instance davinci_timer_instance[]; - +#ifdef CONFIG_COMMON_CLK +extern void davinci_watchdog_reset(struct platform_device *); +#endif #endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */ -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[RFC PATCH 07/10] ARM:davinci - adding new type for cpu_clks in soc_info
To define the clock nodes available on a SoC, a new structure is defined that will be used by SoC specific code to define the clock table. This table is used by davinci_common_clk_init() to initialize the clk drivers. Also added a new field dev_clk_lookups to define clock aliases for devices that share same clocks. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index bdc4aa8..8abee09 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -54,7 +54,12 @@ struct davinci_soc_info { u32 jtag_id_reg; struct davinci_id *ids; unsigned long ids_num; +#ifdef CONFIG_COMMON_CLK + struct davinci_clk_lookup *cpu_clks; + struct davinci_dev_lookup *dev_clk_lookups; +#else struct clk_lookup *cpu_clks; +#endif u32 *psc_bases; unsigned long psc_bases_num; u32 pinmux_base; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[RFC PATCH 03/10] clk:keystone - add Main PLL clock driver
This is the driver for the main PLL clock hardware found on Keystone devices (c6x such as C6678). This driver is implemented as per common clock provider API. The main PLL hardware typically has a multiplier, and a divider. struct clk_keystone_pll_data is used to configure the driver for a specific platform. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/keystone/clk-keystone-pll.c b/drivers/clk/keystone/clk-keystone-pll.c new file mode 100644 index 000..0e1a1c4 --- /dev/null +++ b/drivers/clk/keystone/clk-keystone-pll.c @@ -0,0 +1,94 @@ +/* + * Main PLL clk driver for Keystone devices + * + * Copyright (C) 2012 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * struct clk_pll - DaVinci Main pll clock + * @hw: clk_hw for the pll + * @pll_data: PLL driver specific data + */ +struct clk_pll { + struct clk_hw hw; + struct clk_keystone_pll_data *pll_data; +}; + +#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw) + +static unsigned long clk_pllclk_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pll *pll = to_clk_pll(hw); + struct clk_keystone_pll_data *pll_data = pll->pll_data; + unsigned long rate = parent_rate; + u32 pllm, plld, postdiv, val; + + /* get bit0-5 of PLLM from PLLM PLL control register */ + val = __raw_readl(pll_data->pllm); + pllm = (val & pll_data->pllm_lower_mask); + + /* bit6-12 of PLLM is in Main PLL control register */ + val = __raw_readl(pll_data->main_pll_ctl0); + pllm |= ((val & pll_data->pllm_upper_mask) + >> pll_data->pllm_upper_shift); + plld = (val & pll_data->plld_mask); + postdiv = pll_data->fixed_postdiv; + + rate /= (plld + 1); + rate = (rate * (pllm + 1)); + rate /= postdiv; + + pr_notice("main_pll_clk rate is %ld, postdiv = %d, pllm = %d," \ + "plld = %d\n", rate, postdiv, pllm, plld); + return rate; +} + +static const struct clk_ops clk_pll_ops = { + .recalc_rate = clk_pllclk_recalc, +}; + +struct clk *clk_register_keystone_pll(struct device *dev, const char *name, + const char *parent_name, + struct clk_keystone_pll_data *pll_data) +{ + struct clk_init_data init; + struct clk_pll *pll; + struct clk *clk; + + if (!pll_data) + return ERR_PTR(-ENODEV); + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &clk_pll_ops; + init.flags = 0; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + pll->pll_data = pll_data; + pll->hw.init = &init; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) + kfree(pll); + + return clk; +} diff --git a/include/linux/platform_data/clk-keystone-pll.h b/include/linux/platform_data/clk-keystone-pll.h new file mode 100644 index 000..eecf6a6 --- /dev/null +++ b/include/linux/platform_data/clk-keystone-pll.h @@ -0,0 +1,34 @@ +/* + * TI Keyston clk-pll driver platform data definitions + * + * Copyright (C) 2012 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __CLK_KEYSTONE_PLL_H +#define __CLK_KEYSTONE_PLL_H + +struct clk_keystone_pll_data { + u32 phy_pllm; /* holds lower bits of PLLM */ + u32 phy_main_pll_ctl0; /* holds upper bits of PLLM */ + /* mapped addresses. should be initialized by */ + void __iomem *pllm; + void __iomem *main_pll_ctl0; + u32 pllm_lower_mask; + u32 pllm_upper_mask; + u32 pllm_upper_shift; + u32 plld_mask; + u32 fixed_postdiv; /* use this value for postdiv */ +}; + +extern struct clk *clk_register_keystone_pll(struct device *dev, + const char *name, const char *parent_name, + struct clk_keystone_pll_data *pll_data); +#endif /* CLK_KEYSTONE_PLL_H */ -- 1.7.9.5 _
[RFC PATCH 08/10] ARM:davinci - migrating to use davinci_common_clk_init
The common clk code uses a new function davinci_common_clk_init() defined in drivers/clk/davinci/davinci-clock.c to initialize the clk drivers. This function is now invoked in time.c as part of davinci_timer_init(). Currently davinci_clk_init() is called from davinci_common_init() which is too early to initialize common clk drivers. Also include pll.h instead of clock.h in some of the source files. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index 64b0f65..f854296 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -20,7 +20,9 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#endif struct davinci_soc_info davinci_soc_info; EXPORT_SYMBOL(davinci_soc_info); @@ -106,7 +108,9 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) goto err; if (davinci_soc_info.cpu_clks) { +#ifndef CONFIG_COMMON_CLK ret = davinci_clk_init(davinci_soc_info.cpu_clks); +#endif if (ret != 0) goto err; @@ -122,5 +126,7 @@ void __init davinci_init_late(void) { davinci_cpufreq_init(); davinci_pm_init(); +#ifndef CONFIG_COMMON_CLK davinci_clk_disable_unused(); +#endif } diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index d2f96662..96ee175 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -24,7 +24,9 @@ #include #include "davinci.h" +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#endif #define DAVINCI_I2C_BASE0x01C21000 #define DAVINCI_ATA_BASE0x01C66000 diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c index eb8360b..8802fdc 100644 --- a/arch/arm/mach-davinci/pm.c +++ b/arch/arm/mach-davinci/pm.c @@ -23,7 +23,11 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#else +#include +#endif #define DEEPSLEEP_SLEEPCOUNT_MASK 0x diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S index d4e9316..5c04a7c 100644 --- a/arch/arm/mach-davinci/sleep.S +++ b/arch/arm/mach-davinci/sleep.S @@ -24,7 +24,11 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#else +#include +#endif /* Arbitrary, hardware currently does not update PHYRDY correctly */ #define PHYRDY_CYCLES 0x1000 @@ -183,6 +187,7 @@ ENDPROC(davinci_cpu_suspend) * r1: contains virtual base for DDR2 Power and Sleep controller (PSC) * r2: contains PSC number for DDR2 */ + ENTRY(davinci_ddr_psc_config) /* Set next state in mdctl for DDR2 */ mov r6, #MDCTL diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index 9847938..cc3bb96 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -18,6 +18,9 @@ #include #include #include +#ifdef CONFIG_COMMON_CLK +#include +#endif #include #include @@ -27,7 +30,9 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#endif static struct clock_event_device clockevent_davinci; static unsigned int davinci_clock_tick_rate; @@ -347,6 +352,14 @@ static void __init davinci_timer_init(void) "%s: can't register clocksource!\n"; int i; +#ifdef CONFIG_COMMON_CLK + if (davinci_soc_info.cpu_clks) { + davinci_common_clk_init(davinci_soc_info.cpu_clks, + davinci_soc_info.dev_clk_lookups, + davinci_soc_info.psc_bases_num, + davinci_soc_info.psc_bases); + } +#endif clockevent_id = soc_info->timer_info->clockevent_id; clocksource_id = soc_info->timer_info->clocksource_id; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[RFC PATCH 05/10] clk:davinci - add build infrastructure
Add Makefile and Kconfig for the DaVinci and Keystone clock drivers Signed-off-by: Murali Karicheri diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 7f0b5ca..b732dfd 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -40,4 +40,6 @@ config COMMON_CLK_WM831X Supports the clocking subsystem of the WM831x/2x series of PMICs from Wolfson Microlectronics. +source "drivers/clk/davinci/Kconfig" +source "drivers/clk/keystone/Kconfig" endmenu diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 5869ea3..9f5c4e0 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -13,3 +13,5 @@ obj-$(CONFIG_ARCH_INTEGRATOR) += versatile/ # Chip specific obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o +obj-$(CONFIG_DAVINCI_CLKS) += davinci/ +obj-$(CONFIG_KEYSTONE_CLKS)+= keystone/ diff --git a/drivers/clk/davinci/Kconfig b/drivers/clk/davinci/Kconfig new file mode 100644 index 000..2202c25 --- /dev/null +++ b/drivers/clk/davinci/Kconfig @@ -0,0 +1,42 @@ +menu "TI DaVinci Clock Drivers" + depends on COMMON_CLK + +config CLK_DAVINCI_PSC + bool "TI DaVici PSC Clock driver" + default n + ---help--- + Selects clock driver for DaVinci PSC clocks. This clock + hardware is found on TI DaVinci SoCs and other SoCs that + uses this hardware IP. This hardware has a local power + sleep control module that gate the clock to the IP. + +config CLK_DAVINCI_PLL + bool "DaVici Main PLL clock" + ---help--- + Selects clock driver for DaVinci Main PLL. This clock + hardware is found on TI DaVinci SoCs. This typically has + a multiplier, a pre divider and post driver. Some of the + SoCs has the the dividers fixed, and others have it + programmable + +config DAVINCI_CLKS + bool "TI DaVinci common clocks" + default n + select CLK_DAVINCI_PSC + select DAVINCI_CLKINIT + ---help--- + Selects common clock drivers for DaVinci. These clocks + are re-used across many TI SoCs that are based on DaVinci and + Keystone (c6x) families. This config option is used to select + the common clock driver for DaVinci based SoCs. SoCs specific + Kconfig option needs to select the driver for clocks specific + to the SoC. + +config DAVINCI_CLKINIT + bool "TI DaVici Clock initialization" + default n + ---help--- + Selects clock driver initialization for DaVinci and Keystone + architectures. +endmenu + diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile new file mode 100644 index 000..420e9c3 --- /dev/null +++ b/drivers/clk/davinci/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_CLK_DAVINCI_PLL) += clk-davinci-pll.o +obj-$(CONFIG_CLK_DAVINCI_PSC) += clk-davinci-psc.o +obj-$(CONFIG_DAVINCI_CLKINIT) += davinci-clock.o diff --git a/drivers/clk/keystone/Kconfig b/drivers/clk/keystone/Kconfig new file mode 100644 index 000..c0ea97a --- /dev/null +++ b/drivers/clk/keystone/Kconfig @@ -0,0 +1,6 @@ +config CLK_KEYSTONE_PLL + bool "Keystone Main PLL clock" + ---help--- + Selects the clock driver for Keystone Main PLL. This clock + hardware is found on TI c6x based SoCs + diff --git a/drivers/clk/keystone/Makefile b/drivers/clk/keystone/Makefile new file mode 100644 index 000..6ae8ae9 --- /dev/null +++ b/drivers/clk/keystone/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_CLK_KEYSTONE_PLL) += clk-keystone-pll.o -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[RFC PATCH 09/10] ARM:davinci - update the dm644x soc code to use common clk drivers
The clock tree for dm644x is defined using the new structure davinci_clk. The SoC specific code re-uses clk-fixed-rate, clk-divider and clk-mux drivers in addition to the davinci specific clk drivers, clk-davinci-pll and clk-davinci-psc. Macros are defined to define the various clocks in the SoC. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 0755d46..fdacdbd 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -12,6 +12,14 @@ #include #include #include +#ifdef CONFIG_COMMON_CLK +#include +#include +#include +#include +#include +#include +#endif #include @@ -26,9 +34,16 @@ #include #include "davinci.h" -#include "clock.h" #include "mux.h" #include "asp.h" +#ifndef CONFIG_COMMON_CLK +#include "clock.h" +#else +#define PLLM 0x110 +#define PREDIV 0x114 +#define POSTDIV 0x128 +#define PLLM_PLLM_MASK 0xff +#endif /* * Device specific clocks @@ -42,6 +57,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, @@ -324,6 +340,258 @@ static struct clk_lookup dm644x_clks[] = { CLK("watchdog", NULL, &timer2_clk), CLK(NULL, NULL, NULL), }; +#else +static struct clk_davinci_pll_data pll1_data = { + .phy_pllm = DAVINCI_PLL1_BASE + PLLM, + .phy_prediv = DAVINCI_PLL1_BASE + PREDIV, + .phy_postdiv= DAVINCI_PLL1_BASE + POSTDIV, + .pllm_mask = PLLM_PLLM_MASK, + .prediv_mask= PLLDIV_RATIO_MASK, + .postdiv_mask = PLLDIV_RATIO_MASK, + .num = 1, +}; + +static struct clk_fixed_data clkin_data = { + .rate = DM644X_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +static struct davinci_clk ref_clk_clkin = { + .name = "clkin", + .ref_clk_data = &clkin_data, +}; + +static struct clk_fixed_data oscin_data = { + .rate = DM644X_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +static struct davinci_clk ref_clk_oscin = { + .name = "oscin", + .ref_clk_data = &oscin_data, +}; + +static const char *ref_clk_mux_parents[] = {"clkin", "oscin"}; + +static struct clk_mux_data ref_clk_mux_data = { + .shift = PLLCTL_CLKMODE_SHIFT, + .width = PLLCTL_CLKMODE_WIDTH, + .num_parents= ARRAY_SIZE(ref_clk_mux_parents), + .parents= ref_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk ref_clk_mux = { + .name = "ref_clk_mux", + .parent = &ref_clk_clkin, + .mux_data = &ref_clk_mux_data, +}; + +static struct davinci_clk pll1_clk = { + .name = "pll1", + .pll_type = DAVINCI_MAIN_PLL, + .parent = &ref_clk_mux, + .pll_data = { + .davinci = &pll1_data, + }, +}; + +static const char *pll1_plldiv_clk_mux_parents[] = { + "ref_clk_mux", "pll1"}; + +static struct clk_mux_data pll1_plldiv_clk_mux_data = { + .shift = PLLCTL_PLLEN_SHIFT, + .width = PLLCTL_PLLEN_WIDTH, + .num_parents= ARRAY_SIZE(pll1_plldiv_clk_mux_parents), + .parents= pll1_plldiv_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk pll1_plldiv_clk_mux = { + .name = "pll1_plldiv_clk_mux", + .parent = &pll1_clk, + .mux_data = &pll1_plldiv_clk_mux_data, +}; + +#define define_pll1_div_clk(__pll, __div, __name) \ + static struct clk_divider_data pll1_div_data##__div = { \ + .div_reg= DAVINCI_PLL1_BASE + PLLDIV##__div,\ + .width = 5,\ + }; \ + \ + static struct davinci_clk __name = {\ + .name = #__name, \ + .parent = &__pll, \ + .pll_div_data = &pll1_div_data##__div, \ + } + +define_pll1_div_clk(pll1_plldiv_clk_mux, 1, pll1_sysclk1); +define_pll1_div_clk(pll1_plldiv_clk_mux, 2, pll1_sysclk2); +define_pll1_div_clk(pll1_plldiv_clk_mux, 3, pll1_sysclk3); +define_pll1_div_clk(pll1_plldiv_clk_mux, 4, pll1_sysclk4); +define_pll1_div_clk(pll1_plldiv_clk_mux, 5, pll1_sysclk5); + +static struct clk_divider_data pll1_sysclkbp_data = { + .div_reg = BPDIV, +}; + +static struct davinci_clk pll1_sysclkbp = { + .name = "
[PATCH v1 03/12] clk: keystone - add Main PLL clock driver
This is the driver for the main PLL clock hardware found on Keystone devices (c6x such as C6678). This driver is implemented as per common clock provider API. The main PLL hardware typically has a multiplier, and a divider. struct clk_keystone_pll_data is used to configure the driver for a specific platform. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/keystone/clk-keystone-pll.c b/drivers/clk/keystone/clk-keystone-pll.c new file mode 100644 index 000..0e1a1c4 --- /dev/null +++ b/drivers/clk/keystone/clk-keystone-pll.c @@ -0,0 +1,94 @@ +/* + * Main PLL clk driver for Keystone devices + * + * Copyright (C) 2012 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * struct clk_pll - DaVinci Main pll clock + * @hw: clk_hw for the pll + * @pll_data: PLL driver specific data + */ +struct clk_pll { + struct clk_hw hw; + struct clk_keystone_pll_data *pll_data; +}; + +#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw) + +static unsigned long clk_pllclk_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pll *pll = to_clk_pll(hw); + struct clk_keystone_pll_data *pll_data = pll->pll_data; + unsigned long rate = parent_rate; + u32 pllm, plld, postdiv, val; + + /* get bit0-5 of PLLM from PLLM PLL control register */ + val = __raw_readl(pll_data->pllm); + pllm = (val & pll_data->pllm_lower_mask); + + /* bit6-12 of PLLM is in Main PLL control register */ + val = __raw_readl(pll_data->main_pll_ctl0); + pllm |= ((val & pll_data->pllm_upper_mask) + >> pll_data->pllm_upper_shift); + plld = (val & pll_data->plld_mask); + postdiv = pll_data->fixed_postdiv; + + rate /= (plld + 1); + rate = (rate * (pllm + 1)); + rate /= postdiv; + + pr_notice("main_pll_clk rate is %ld, postdiv = %d, pllm = %d," \ + "plld = %d\n", rate, postdiv, pllm, plld); + return rate; +} + +static const struct clk_ops clk_pll_ops = { + .recalc_rate = clk_pllclk_recalc, +}; + +struct clk *clk_register_keystone_pll(struct device *dev, const char *name, + const char *parent_name, + struct clk_keystone_pll_data *pll_data) +{ + struct clk_init_data init; + struct clk_pll *pll; + struct clk *clk; + + if (!pll_data) + return ERR_PTR(-ENODEV); + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &clk_pll_ops; + init.flags = 0; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + pll->pll_data = pll_data; + pll->hw.init = &init; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) + kfree(pll); + + return clk; +} diff --git a/include/linux/platform_data/clk-keystone-pll.h b/include/linux/platform_data/clk-keystone-pll.h new file mode 100644 index 000..eecf6a6 --- /dev/null +++ b/include/linux/platform_data/clk-keystone-pll.h @@ -0,0 +1,34 @@ +/* + * TI Keyston clk-pll driver platform data definitions + * + * Copyright (C) 2012 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __CLK_KEYSTONE_PLL_H +#define __CLK_KEYSTONE_PLL_H + +struct clk_keystone_pll_data { + u32 phy_pllm; /* holds lower bits of PLLM */ + u32 phy_main_pll_ctl0; /* holds upper bits of PLLM */ + /* mapped addresses. should be initialized by */ + void __iomem *pllm; + void __iomem *main_pll_ctl0; + u32 pllm_lower_mask; + u32 pllm_upper_mask; + u32 pllm_upper_shift; + u32 plld_mask; + u32 fixed_postdiv; /* use this value for postdiv */ +}; + +extern struct clk *clk_register_keystone_pll(struct device *dev, + const char *name, const char *parent_name, + struct clk_keystone_pll_data *pll_data); +#endif /* CLK_KEYSTONE_PLL_H */ -- 1.7.9.5 _
[PATCH v1 02/12] clk: davinci - add PSC clock driver
This is the driver for the Power Sleep Controller (PSC) hardware found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed code from arch/arm/mach-davinci/psc.c and implemented the driver as per common clock provider API. The PSC module is responsible for enabling/disabling the Power Domain and Clock domain for different IPs present in the SoC. The driver is configured through the platform data structure struct clk_davinci_psc_data. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/davinci/clk-davinci-psc.c b/drivers/clk/davinci/clk-davinci-psc.c new file mode 100644 index 000..b7aa332 --- /dev/null +++ b/drivers/clk/davinci/clk-davinci-psc.c @@ -0,0 +1,197 @@ +/* + * PSC clk driver for DaVinci devices + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include + +/* PSC register offsets */ +#define EPCPR 0x070 +#define PTCMD 0x120 +#define PTSTAT 0x128 +#define PDSTAT 0x200 +#define PDCTL 0x300 +#define MDSTAT 0x800 +#define MDCTL 0xA00 + +/* PSC module states */ +#define PSC_STATE_SWRSTDISABLE 0 +#define PSC_STATE_SYNCRST 1 +#define PSC_STATE_DISABLE 2 +#define PSC_STATE_ENABLE 3 + +#define MDSTAT_STATE_MASK 0x3f +#define PDSTAT_STATE_MASK 0x1f +#define MDCTL_FORCEBIT(31) +#define PDCTL_NEXT BIT(0) +#define PDCTL_EPCGOOD BIT(8) + +/* PSC flags */ +#define PSC_SWRSTDISABLE BIT(0) /* Disable state is SwRstDisable */ +#define PSC_FORCE BIT(1) /* Force module state transtition */ +#define PSC_HAS_EXT_POWER_CNTL BIT(2) /* PSC has external power control + * available (for DM6446 SoC) */ +/** + * struct clk_psc - DaVinci PSC clock + * @hw: clk_hw for the psc + * @psc_data: PSC driver specific data + * @lock: Spinlock used by the driver + */ +struct clk_psc { + struct clk_hw hw; + struct clk_davinci_psc_data *psc_data; + spinlock_t *lock; +}; + +#define to_clk_psc(_hw) container_of(_hw, struct clk_psc, hw) + +/* Enable or disable a PSC domain */ +static void clk_psc_config(void __iomem *base, unsigned int domain, + unsigned int id, bool enable, u32 flags) +{ + u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl; + u32 next_state = PSC_STATE_ENABLE; + void __iomem *psc_base = base; + + if (!enable) { + if (flags & 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); + + if (flags & PSC_HAS_EXT_POWER_CNTL) { + do { + epcpr = __raw_readl(psc_base + EPCPR); + } while epcpr >> domain) & 1) == 0)); + } + + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); + pdctl |= 0x100; + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); + + 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)); +} + +static int clk_psc_is_enabled(struct clk_hw *hw) +{ + struct clk_psc *psc = to_clk_psc(hw); + struct clk_davinci_psc_data *psc_data = psc->psc_data; + u32 mdstat; + + mdstat = __raw_readl(psc_data->base + MDSTAT + 4 * psc_data->lpsc); + /* if clocked, state can be "Enable" or "SyncReset" */ +
[PATCH v1 00/12] Use common clk drivers for DaVinci
This is v1 of the patch series for implementing clock tree for DaVinci SoCs using common clk framework. updates in v1: - Added DM365 and DM355 - updates to davinci_clk struct to accomodate clk-fixed-factor data initial version:- Currently arch/arm/mach-davinci/clock.c and arch/arm/mach-davinci/psc.c implements clock drivers for DaVinci. This patch makes these code obsolete and migrate the SoC code to use the common clk based drivers. This adds two clk drivers specific to DaVinci and Keystone (found in c6x arch such as C6678) devices. Some of the existing clk drivers such as clk-fixed-rate, clk-divider, and clk-mux are re-used in addition to the DaVinci specific drivers to initialize the clock tree for the SoCs. Please refer chapter 6 of http://www.ti.com/lit/ug/sprue14c/sprue14c.pdf for details of the PLL hardware in DM6446 and chapter 7 for defails of the PSC hardware. There are two Main PLLs in DM644x. PLL1 and PLL2. Each of these generate different clocks in the DM device through PLL dividers. Figure above shows this for PLL1. Similar hardware exists for PLL2 and the related output clocks. The hardware is similar in most of the DM SoCs. Some of the recent Keystone devices (c6678 under c6x architecture) include a slight variant of the PLL that implemented different registers for the multipliers and dividers. All of these devices include PLL dividers (PLLDIVx) and Power Sleep controllers (PSC). The SoCs defines various Power Domains and Clock domains and there are PSC modules that controls power and clocks to various hardware IPs of the SoC. Following drivers are used for various clock hardware blocks:- CLKIN and OSCIN - clk-fixed-rate (existing driver) MUX - clk-mux (existing driver) PLLDIVx - clk-divider (existing driver) PLL mult/div - clk-davinci-pll (new driver) clk-keystone-pll (new driver) PSC - clk-davinci-psc.c (new driver The patch series is split in two:- patch 1-5 for drivers and 6-12 for machine specific code. Please note that initially only DM644x is supported. The idea is to review the initial patch and get a feedback on the overall structure of the code organization. The other SoCs will be added in subsequent patch revisions. The driver code implements the features needed to support DM644x and is expected to be enhanced in subsequent patch revisions to support additional SoCs. I have boot tested this on DM6446 EVM I have. Also verified reboot command works and the clock rates are set as before. The patches depends on the following patches that I had sent for review earlier: davinci spi driver preparation @ https://patchwork.kernel.org/patch/1389321/ davinci watchdog driver preparation @ https://lkml.org/lkml/2012/9/7/634 davinci nand driver preparation @ https://lkml.org/lkml/2012/9/7/635 davinci i2c driver preparation @ https://patchwork.kernel.org/patch/1388841/ davinci gpio driver preparation @ https://lkml.org/lkml/2012/8/31/341 [RFC - PATCH] base:pm: prepare driver for common clock framework in the davinci mailing list Following are to be discussed as part of this patch review. 1. arch/arm/pm.c. This is configuring PLL controller registers for suspend and resume. It appears that we need to move this code to clk-davinci-pll.c. But I can't find APIs for suspend and resume in the common clk framework. How is this expected to work? Currently i have kept the code ASIS. 2. There are usecount=1 in the old clock implementation for dsp, vicp and timer2 clocks. CLK_IGNORE_UNUSED flag is used currently to implement the same as disabling these unused clocks causes issues in boot up, NOTE: I am doing this work as a background activity and hence the progress will be slow. Please volunteer to help me in this effort by offering to test or migrating other devices to this framework. ====== Murali Karicheri (12): clk: davinci - add Main PLL clock driver clk: davinci - add PSC clock driver clk: keystone - add Main PLL clock driver clk: davinci - common clk driver initialization clk: davinci - add build infrastructure ARM: davinci - restructure header files for common clk migration ARM: davinci - adding new type for cpu_clks in soc_info ARM: davinci - migrating to use davinci_common_clk_init ARM: davinci - update the dm644x soc code to use common clk drivers ARM: davinci - update the dm355 soc code to use common clk drivers ARM: davinci - update the dm365 soc code to use common clk drivers ARM: davinci - switch to common clk framework arch/arm/Kconfig |1 + arch/arm/mach-davinci/Kconfig |6 + arch/arm/mach-davinci/Makefile | 11 +- arch/arm/mach-davinci/common.c |6 + arch/arm/mach-davinci/devices.c|2 + arch/arm/mach-davinci/dm355.c | 343 +++- arch/arm/mach-davinci/dm
[PATCH v1 01/12] clk: davinci - add Main PLL clock driver
This is the driver for the main PLL clock hardware found on DM SoCs. This driver borrowed code from arch/arm/mach-davinci/clock.c and implemented the driver as per common clock provider API. The main PLL hardware typically has a multiplier, a pre-divider and a post-divider. Some of the SoCs has the divider fixed meaning they can not be configured through a register. HAS_PREDIV and HAS_POSTDIV flags are used to tell the driver if a hardware has these dividers present or not. Driver is configured through the structure clk_davinci_pll_data that has the platform data for the driver. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/davinci/clk-davinci-pll.c b/drivers/clk/davinci/clk-davinci-pll.c new file mode 100644 index 000..13e1690 --- /dev/null +++ b/drivers/clk/davinci/clk-davinci-pll.c @@ -0,0 +1,128 @@ +/* + * PLL clk driver DaVinci devices + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * TODO - Add set_parent_rate() + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +#define PLLM 0x110 +#define PLLM_PLLM_MASK 0xff +#define PREDIV 0x114 +#define POSTDIV 0x128 +#define PLLDIV_EN BIT(15) + +/** + * struct clk_davinci_pll - DaVinci Main pll clock + * @hw: clk_hw for the pll + * @pll_data: PLL driver specific data + */ +struct clk_davinci_pll { + struct clk_hw hw; + struct clk_davinci_pll_data *pll_data; +}; + +#define to_clk_pll(_hw) container_of(_hw, struct clk_davinci_pll, hw) + +static unsigned long clk_pllclk_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_davinci_pll *pll = to_clk_pll(hw); + struct clk_davinci_pll_data *pll_data = pll->pll_data; + u32 mult = 1, prediv = 1, postdiv = 1; + unsigned long rate = parent_rate; + + /* If there is a device specific recalc defined invoke it. Otherwise +* fallback to default one +*/ + mult = __raw_readl(pll_data->pllm); + if (pll_data->pllm_multiplier) + mult = pll_data->pllm_multiplier * + (mult & pll_data->pllm_mask); + else + mult = (mult & pll_data->pllm_mask) + 1; + + if (pll_data->flags & CLK_DAVINCI_PLL_HAS_PREDIV) { + /* pre-divider is fixed, take prediv value from pll_data */ + if (pll_data->fixed_prediv) + prediv = pll_data->fixed_prediv; + else { + prediv = __raw_readl(pll_data->prediv); + if (prediv & PLLDIV_EN) + prediv = (prediv & pll_data->prediv_mask) + 1; + else + prediv = 1; + } + } + + if (pll_data->flags & CLK_DAVINCI_PLL_HAS_POSTDIV) { + postdiv = __raw_readl(pll_data->postdiv); + if (postdiv & PLLDIV_EN) + postdiv = (postdiv & pll_data->postdiv_mask) + 1; + else + postdiv = 1; + } + + rate /= prediv; + rate *= mult; + rate /= postdiv; + + pr_debug("PLL%d: input = %lu MHz [ ", +pll_data->num, parent_rate / 100); + 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 / 100); + return rate; +} + +static const struct clk_ops clk_pll_ops = { + .recalc_rate = clk_pllclk_recalc, +}; + +struct clk *clk_register_davinci_pll(struct device *dev, const char *name, + const char *parent_name, + struct clk_davinci_pll_data *pll_data) +{ + struct clk_init_data init; + struct clk_davinci_pll *pll; + struct clk *clk; + + if (!pll_data) + return ERR_PTR(-ENODEV); + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + init.name = name; + init.ops = &clk_pll_ops; + init.flags = pll_data->flags; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + pll->pll_data = pll_data; + pll->hw.init = &init; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) + kfree(pll); + +
[PATCH v1 07/12] ARM: davinci - adding new type for cpu_clks in soc_info
To define the clock nodes available on a SoC, a new structure is defined that will be used by SoC specific code to define the clock table. This table is used by davinci_common_clk_init() to initialize the clk drivers. Also added a new field dev_clk_lookups to define clock aliases for devices that share same clocks. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index bdc4aa8..8abee09 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -54,7 +54,12 @@ struct davinci_soc_info { u32 jtag_id_reg; struct davinci_id *ids; unsigned long ids_num; +#ifdef CONFIG_COMMON_CLK + struct davinci_clk_lookup *cpu_clks; + struct davinci_dev_lookup *dev_clk_lookups; +#else struct clk_lookup *cpu_clks; +#endif u32 *psc_bases; unsigned long psc_bases_num; u32 pinmux_base; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v1 05/12] clk: davinci - add build infrastructure
Add Makefile and Kconfig for the DaVinci and Keystone clock drivers Signed-off-by: Murali Karicheri diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 7f0b5ca..b732dfd 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -40,4 +40,6 @@ config COMMON_CLK_WM831X Supports the clocking subsystem of the WM831x/2x series of PMICs from Wolfson Microlectronics. +source "drivers/clk/davinci/Kconfig" +source "drivers/clk/keystone/Kconfig" endmenu diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 5869ea3..f469edb 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -13,3 +13,5 @@ obj-$(CONFIG_ARCH_INTEGRATOR) += versatile/ # Chip specific obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o +obj-$(CONFIG_DAVINCI_CLKS) += davinci/ +obj-$(CONFIG_CLK_KEYSTONE_PLL) += keystone/ diff --git a/drivers/clk/davinci/Kconfig b/drivers/clk/davinci/Kconfig new file mode 100644 index 000..2202c25 --- /dev/null +++ b/drivers/clk/davinci/Kconfig @@ -0,0 +1,42 @@ +menu "TI DaVinci Clock Drivers" + depends on COMMON_CLK + +config CLK_DAVINCI_PSC + bool "TI DaVici PSC Clock driver" + default n + ---help--- + Selects clock driver for DaVinci PSC clocks. This clock + hardware is found on TI DaVinci SoCs and other SoCs that + uses this hardware IP. This hardware has a local power + sleep control module that gate the clock to the IP. + +config CLK_DAVINCI_PLL + bool "DaVici Main PLL clock" + ---help--- + Selects clock driver for DaVinci Main PLL. This clock + hardware is found on TI DaVinci SoCs. This typically has + a multiplier, a pre divider and post driver. Some of the + SoCs has the the dividers fixed, and others have it + programmable + +config DAVINCI_CLKS + bool "TI DaVinci common clocks" + default n + select CLK_DAVINCI_PSC + select DAVINCI_CLKINIT + ---help--- + Selects common clock drivers for DaVinci. These clocks + are re-used across many TI SoCs that are based on DaVinci and + Keystone (c6x) families. This config option is used to select + the common clock driver for DaVinci based SoCs. SoCs specific + Kconfig option needs to select the driver for clocks specific + to the SoC. + +config DAVINCI_CLKINIT + bool "TI DaVici Clock initialization" + default n + ---help--- + Selects clock driver initialization for DaVinci and Keystone + architectures. +endmenu + diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile new file mode 100644 index 000..420e9c3 --- /dev/null +++ b/drivers/clk/davinci/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_CLK_DAVINCI_PLL) += clk-davinci-pll.o +obj-$(CONFIG_CLK_DAVINCI_PSC) += clk-davinci-psc.o +obj-$(CONFIG_DAVINCI_CLKINIT) += davinci-clock.o diff --git a/drivers/clk/keystone/Kconfig b/drivers/clk/keystone/Kconfig new file mode 100644 index 000..c0ea97a --- /dev/null +++ b/drivers/clk/keystone/Kconfig @@ -0,0 +1,6 @@ +config CLK_KEYSTONE_PLL + bool "Keystone Main PLL clock" + ---help--- + Selects the clock driver for Keystone Main PLL. This clock + hardware is found on TI c6x based SoCs + diff --git a/drivers/clk/keystone/Makefile b/drivers/clk/keystone/Makefile new file mode 100644 index 000..6ae8ae9 --- /dev/null +++ b/drivers/clk/keystone/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_CLK_KEYSTONE_PLL) += clk-keystone-pll.o -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v1 04/12] clk: davinci - common clk driver initialization
This is the common clk driver initialization function for DaVinci SoCs and other SoCs that uses similar hardware architecture. Different clocks present in the SoC are passed to this function using a clk table and this function initialize the various drivers. Existing driver such as clk-fixed-rate, clk-divider, clk-mux and DaVinci specific clk drivers are initialized by this function. Also adds clock lookup for shared clocks used by various drivers. davinci-clock.h declares the various structures used for defining the DaVinci clocks. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/davinci/davinci-clock.c b/drivers/clk/davinci/davinci-clock.c new file mode 100644 index 000..1addec3 --- /dev/null +++ b/drivers/clk/davinci/davinci-clock.c @@ -0,0 +1,220 @@ +/* + * Clock initialization code for DaVinci devices + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_SPINLOCK(_lock); + +struct clk *davinci_lookup_clk(struct davinci_clk_lookup *clocks, + const char *con_id) +{ + struct davinci_clk_lookup *c; + + for (c = clocks; c->_clk; c++) { + if (c->con_id && !strcmp(c->con_id, con_id)) + return c->clk; + } + return NULL; +} + +#ifdef CONFIG_CLK_DAVINCI_PLL +static void register_davinci_pll_clk(struct davinci_clk_lookup *c, + struct clk_davinci_pll_data *pll_data) +{ + + WARN_ON(!pll_data->phy_pllm); + pll_data->pllm = ioremap(pll_data->phy_pllm, 4); + WARN_ON(!pll_data->pllm); + if (pll_data->phy_prediv) { + pll_data->prediv = ioremap(pll_data->phy_prediv, 4); + WARN_ON(!pll_data->prediv); + } + if (pll_data->phy_postdiv) { + pll_data->postdiv = ioremap(pll_data->phy_postdiv, 4); + WARN_ON(!pll_data->postdiv); + } + c->clk = clk_register_davinci_pll(NULL, + c->_clk->name, c->_clk->parent->name, + pll_data); +} +#else +static void register_davinci_pll_clk(struct davinci_clk_lookup *c, + struct clk_davinci_pll_data *pll_data) +{ + return; +} +#endif + +#ifdef CONFIG_CLK_KEYSTONE_PLL +static void register_keystone_pll_clk(struct davinci_clk_lookup *c, + struct clk_keystone_pll_data *pll_data) +{ + WARN_ON(!pll_data->phy_pllm); + pll_data->pllm = ioremap(pll_data->phy_pllm, 4); + WARN_ON(!pll_data->pllm); + WARN_ON(!pll_data->phy_main_pll_ctl0); + pll_data->main_pll_ctl0 = + ioremap(pll_data->phy_main_pll_ctl0, 4); + WARN_ON(!pll_data->main_pll_ctl0); + c->clk = clk_register_keystone_pll(NULL, + c->_clk->name, c->_clk->parent->name, +pll_data); +} +#else +static void register_keystone_pll_clk(struct davinci_clk_lookup *c, + struct clk_keystone_pll_data *pll_data) +{ + return; +} +#endif + +int __init davinci_common_clk_init(struct davinci_clk_lookup *clocks, + struct davinci_dev_lookup *dev_clk_lookups, + u8 num_gpscs, u32 *psc_bases) +{ + void __iomem **base = NULL, *reg; + struct davinci_clk_lookup *c; + struct davinci_clk *_clk; + unsigned long rate; + int i, skip; + + WARN_ON(!num_gpscs); + WARN_ON(psc_bases == NULL); + + base = kzalloc(sizeof(void __iomem *) * num_gpscs, GFP_KERNEL); + WARN_ON(!base); + for (i = 0; i < num_gpscs; i++) { + base[i] = ioremap(psc_bases[i], SZ_4K); + WARN_ON(!base[i]); + } + + for (c = clocks; c->_clk; c++) { + skip = 0; + _clk = c->_clk; + + if (_clk->ref_clk_data) { + /* root node */ + struct clk_fixed_rate_data *ref_clk_dat = _clk->ref_clk_data; + + if (ref_clk_dat->recalc) + rate = ref_clk_dat->recalc(0); + else + rate = ref_clk_dat->rate; + + c->clk = clk_register_fixed_rate(NULL, _clk->name, + NULL, ref_clk_dat->flags, rate); + } else if (_clk->pll_data.main_pll) { +
[PATCH v1 08/12] ARM: davinci - migrating to use davinci_common_clk_init
The common clk code uses a new function davinci_common_clk_init() defined in drivers/clk/davinci/davinci-clock.c to initialize the clk drivers. This function is now invoked in time.c as part of davinci_timer_init(). Currently davinci_clk_init() is called from davinci_common_init() which is too early to initialize common clk drivers. Also include pll.h instead of clock.h in some of the source files. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index 64b0f65..f854296 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -20,7 +20,9 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#endif struct davinci_soc_info davinci_soc_info; EXPORT_SYMBOL(davinci_soc_info); @@ -106,7 +108,9 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) goto err; if (davinci_soc_info.cpu_clks) { +#ifndef CONFIG_COMMON_CLK ret = davinci_clk_init(davinci_soc_info.cpu_clks); +#endif if (ret != 0) goto err; @@ -122,5 +126,7 @@ void __init davinci_init_late(void) { davinci_cpufreq_init(); davinci_pm_init(); +#ifndef CONFIG_COMMON_CLK davinci_clk_disable_unused(); +#endif } diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index d2f96662..96ee175 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -24,7 +24,9 @@ #include #include "davinci.h" +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#endif #define DAVINCI_I2C_BASE0x01C21000 #define DAVINCI_ATA_BASE0x01C66000 diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c index eb8360b..8802fdc 100644 --- a/arch/arm/mach-davinci/pm.c +++ b/arch/arm/mach-davinci/pm.c @@ -23,7 +23,11 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#else +#include +#endif #define DEEPSLEEP_SLEEPCOUNT_MASK 0x diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S index d4e9316..5c04a7c 100644 --- a/arch/arm/mach-davinci/sleep.S +++ b/arch/arm/mach-davinci/sleep.S @@ -24,7 +24,11 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#else +#include +#endif /* Arbitrary, hardware currently does not update PHYRDY correctly */ #define PHYRDY_CYCLES 0x1000 @@ -183,6 +187,7 @@ ENDPROC(davinci_cpu_suspend) * r1: contains virtual base for DDR2 Power and Sleep controller (PSC) * r2: contains PSC number for DDR2 */ + ENTRY(davinci_ddr_psc_config) /* Set next state in mdctl for DDR2 */ mov r6, #MDCTL diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index 9847938..cc3bb96 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -18,6 +18,9 @@ #include #include #include +#ifdef CONFIG_COMMON_CLK +#include +#endif #include #include @@ -27,7 +30,9 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#endif static struct clock_event_device clockevent_davinci; static unsigned int davinci_clock_tick_rate; @@ -347,6 +352,14 @@ static void __init davinci_timer_init(void) "%s: can't register clocksource!\n"; int i; +#ifdef CONFIG_COMMON_CLK + if (davinci_soc_info.cpu_clks) { + davinci_common_clk_init(davinci_soc_info.cpu_clks, + davinci_soc_info.dev_clk_lookups, + davinci_soc_info.psc_bases_num, + davinci_soc_info.psc_bases); + } +#endif clockevent_id = soc_info->timer_info->clockevent_id; clocksource_id = soc_info->timer_info->clocksource_id; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v1 06/12] ARM: davinci - restructure header files for common clk migration
As part of migrating to common clk framework usage in DaVinci SoCs, clock.h and clock.c are being deprecated as the pll and psc clock drivers are moved to drivers/clk/davinci. The relevant PLL defines are moved to include/mach/pll.h and will be used by SoC specific code instead of using clock.h. The psc.c code is being deprecated as the psc specific code is moved to the drivers/clk/davinci. So the extern definitions are not used anymore and is now conditionally included. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/include/mach/pll.h b/arch/arm/mach-davinci/include/mach/pll.h new file mode 100644 index 000..d21e5b9 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/pll.h @@ -0,0 +1,82 @@ +/* + * TI DaVinci PLL definitions + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __ASM_ARCH_PLL_H +#define __ASM_ARCH_PLL_H + +#define DAVINCI_PLL1_BASE 0x01c40800 +#define DAVINCI_PLL2_BASE 0x01c40c00 +#define MAX_PLL 2 + +/* PLL/Reset register offsets */ +#define PLLCTL 0x100 +#define PLLCTL_PLLENBIT(0) +#define PLLCTL_PLLPWRDNBIT(1) +#define PLLCTL_PLLRST BIT(3) +#define PLLCTL_PLLDIS BIT(4) +#define PLLCTL_PLLENSRCBIT(5) +#define PLLCTL_CLKMODE BIT(8) + +#define PLLCTL_CLKMODE_SHIFT 8 +#define PLLCTL_CLKMODE_WIDTH 1 +#define PLLCTL_PLLEN_SHIFT 0 +#define PLLCTL_PLLEN_WIDTH 1 + +#define PLLDIV1 0x118 +#define PLLDIV2 0x11c +#define PLLDIV3 0x120 +#define OSCDIV1 0x124 +#define BPDIV 0x12c +#define PLLCMD 0x138 +#define PLLSTAT0x13c +#define PLLALNCTL 0x140 +#define PLLDCHANGE 0x144 +#define PLLCKEN0x148 +#define PLLCKSTAT 0x14c +#define PLLSYSTAT 0x150 +#define PLLDIV4 0x160 +#define PLLDIV5 0x164 +#define PLLDIV6 0x168 +#define PLLDIV7 0x16c +#define PLLDIV8 0x170 +#define PLLDIV9 0x174 +#define PLLDIV100x178 +#define PLLDIV110x17c +#define PLLDIV120x180 +#define PLLDIV130x184 +#define PLLDIV140x188 +#define PLLDIV150x18c +#define PLLDIV160x190 +#define PLLDIV_RATIO_MASK 0x1f +#define PLLDIV_EN BIT(15) + +/* + * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN + * cycles to ensure that the PLLC has switched to bypass mode. Delay of 1us + * ensures we are good for all > 4MHz OSCIN/CLKIN inputs. Typically the input + * is ~25MHz. Units are micro seconds. + */ +#define PLL_BYPASS_TIME1 +/* From OMAP-L138 datasheet table 6-4. Units are micro seconds */ +#define PLL_RESET_TIME 1 +/* + * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4 + * Units are micro seconds. + */ +#define PLL_LOCK_TIME 20 +#define PLLSTAT_GOSTAT BIT(0) +#define PLLCMD_GOSET BIT(0) + +#endif /* __ASM_ARCH_PLL_H */ diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index 405318e..6abb94c 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h @@ -251,9 +251,11 @@ #ifndef __ASSEMBLER__ +#ifndef CONFIG_COMMON_CLK extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id); extern void davinci_psc_config(unsigned int domain, unsigned int ctlr, unsigned int id, bool enable, u32 flags); +#endif #endif diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h index 1c971d8..7faa530 100644 --- a/arch/arm/mach-davinci/include/mach/time.h +++ b/arch/arm/mach-davinci/include/mach/time.h @@ -31,5 +31,7 @@ enum { #define ID_TO_TIMER(id)(IS_TIMER1(id) != 0) extern struct davinci_timer_instance davinci_timer_instance[]; - +#ifdef CONFIG_COMMON_CLK +extern void davinci_watchdog_reset(struct platform_device *); +#endif #endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */ -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v1 10/12] ARM: davinci - update the dm355 soc code to use common clk drivers
The clock tree for dm355 is defined using the new structure davinci_clk. The SoC specific code re-uses clk-fixed-rate, clk-divider, clk-fixed-factor and clk-mux drivers in addition to the davinci specific clk drivers, clk-davinci-pll and clk-davinci-psc. Macros are used to define the various clocks in the SoC. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index e47a3f0..d160586 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -13,8 +13,15 @@ #include #include #include - #include +#ifdef CONFIG_COMMON_CLK +#include +#include +#include +#include +#include +#include +#endif #include @@ -30,17 +37,24 @@ #include #include "davinci.h" -#include "clock.h" #include "mux.h" #include "asp.h" +#ifndef CONFIG_COMMON_CLK +#include "clock.h" +#else +#define PLLM 0x110 +#define PREDIV 0x114 +#define POSTDIV 0x128 +#define PLLM_PLLM_MASK 0xff +#endif #define DM355_UART2_BASE (IO_PHYS + 0x206000) - /* * Device specific clocks */ #define DM355_REF_FREQ 2400/* 24 or 36 MHz */ +#ifndef CONFIG_COMMON_CLK static struct pll_data pll1_data = { .num = 1, .phys_base = DAVINCI_PLL1_BASE, @@ -380,6 +394,298 @@ static struct clk_lookup dm355_clks[] = { CLK(NULL, "usb", &usb_clk), CLK(NULL, NULL, NULL), }; +#else +static struct clk_davinci_pll_data pll1_data = { + .phy_pllm = DAVINCI_PLL1_BASE + PLLM, + .phy_prediv = DAVINCI_PLL1_BASE + PREDIV, + .phy_postdiv= DAVINCI_PLL1_BASE + POSTDIV, + .pllm_mask = PLLM_PLLM_MASK, + .prediv_mask= PLLDIV_RATIO_MASK, + .postdiv_mask = PLLDIV_RATIO_MASK, + .num= 1, + .pll_flags = CLK_DAVINCI_PLL_HAS_PREDIV | +CLK_DAVINCI_PLL_HAS_POSTDIV, + .fixed_prediv = 8, +}; + +static struct clk_fixed_rate_data clkin_data = { + /* FIXME -- crystal rate is board-specific */ + .rate = DM355_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +static struct davinci_clk ref_clk_clkin = { + .name = "clkin", + .ref_clk_data = &clkin_data, +}; + +static struct clk_fixed_rate_data oscin_data = { + /* FIXME -- crystal rate is board-specific */ + .rate = DM355_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +static struct davinci_clk ref_clk_oscin = { + .name = "oscin", + .ref_clk_data = &oscin_data, +}; + +static const char *ref_clk_mux_parents[] = {"clkin", "oscin"}; + +static struct clk_mux_data ref_clk_mux_data = { + .shift = PLLCTL_CLKMODE_SHIFT, + .width = PLLCTL_CLKMODE_WIDTH, + .num_parents= ARRAY_SIZE(ref_clk_mux_parents), + .parents= ref_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk ref_clk_mux = { + .name = "ref_clk_mux", + .parent = &ref_clk_clkin, + .mux_data = &ref_clk_mux_data, +}; + +static struct davinci_clk pll1_clk = { + .name = "pll1", + .pll_type = DAVINCI_MAIN_PLL, + .parent = &ref_clk_mux, + .pll_data = { + .davinci= &pll1_data, + }, +}; + +static const char *pll1_plldiv_clk_mux_parents[] = { + "ref_clk_mux", "pll1"}; + +static struct clk_mux_data pll1_plldiv_clk_mux_data = { + .shift = PLLCTL_PLLEN_SHIFT, + .width = PLLCTL_PLLEN_WIDTH, + .num_parents= ARRAY_SIZE(pll1_plldiv_clk_mux_parents), + .parents= pll1_plldiv_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk pll1_plldiv_clk_mux = { + .name = "pll1_plldiv_clk_mux", + .parent = &pll1_clk, + .mux_data = &pll1_plldiv_clk_mux_data, +}; + +#define define_pll1_div_clk(__pll, __div, __name) \ + static struct clk_divider_data pll1_div_data##__div = { \ + .div_reg= DAVINCI_PLL1_BASE + PLLDIV##__div,\ + .width = 5,\ + }; \ + \ + static struct davinci_clk __name = {\ + .name = #__name, \ + .parent = &__pll, \ + .pll_div_data = &pll1_div_data##__div, \ + } + +define_pll1_div_clk(pll1_plldiv_clk_mux, 1, pll1_sysclk1); +d
[PATCH v1 09/12] ARM: davinci - update the dm644x soc code to use common clk drivers
The clock tree for dm644x is defined using the new structure davinci_clk. The SoC specific code re-uses clk-fixed-rate, clk-divider and clk-mux drivers in addition to the davinci specific clk drivers, clk-davinci-pll and clk-davinci-psc. Macros are defined to define the various clocks in the SoC. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 0755d46..0ced6b7 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -12,6 +12,14 @@ #include #include #include +#ifdef CONFIG_COMMON_CLK +#include +#include +#include +#include +#include +#include +#endif #include @@ -26,9 +34,16 @@ #include #include "davinci.h" -#include "clock.h" #include "mux.h" #include "asp.h" +#ifndef CONFIG_COMMON_CLK +#include "clock.h" +#else +#define PLLM 0x110 +#define PREDIV 0x114 +#define POSTDIV 0x128 +#define PLLM_PLLM_MASK 0xff +#endif /* * Device specific clocks @@ -42,6 +57,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, @@ -324,6 +340,258 @@ static struct clk_lookup dm644x_clks[] = { CLK("watchdog", NULL, &timer2_clk), CLK(NULL, NULL, NULL), }; +#else +static struct clk_davinci_pll_data pll1_data = { + .phy_pllm = DAVINCI_PLL1_BASE + PLLM, + .phy_prediv = DAVINCI_PLL1_BASE + PREDIV, + .phy_postdiv= DAVINCI_PLL1_BASE + POSTDIV, + .pllm_mask = PLLM_PLLM_MASK, + .prediv_mask= PLLDIV_RATIO_MASK, + .postdiv_mask = PLLDIV_RATIO_MASK, + .num= 1, +}; + +static struct clk_fixed_rate_data clkin_data = { + .rate = DM644X_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +static struct davinci_clk ref_clk_clkin = { + .name = "clkin", + .ref_clk_data = &clkin_data, +}; + +static struct clk_fixed_rate_data oscin_data = { + .rate = DM644X_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +static struct davinci_clk ref_clk_oscin = { + .name = "oscin", + .ref_clk_data = &oscin_data, +}; + +static const char *ref_clk_mux_parents[] = {"clkin", "oscin"}; + +static struct clk_mux_data ref_clk_mux_data = { + .shift = PLLCTL_CLKMODE_SHIFT, + .width = PLLCTL_CLKMODE_WIDTH, + .num_parents= ARRAY_SIZE(ref_clk_mux_parents), + .parents= ref_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk ref_clk_mux = { + .name = "ref_clk_mux", + .parent = &ref_clk_clkin, + .mux_data = &ref_clk_mux_data, +}; + +static struct davinci_clk pll1_clk = { + .name = "pll1", + .pll_type = DAVINCI_MAIN_PLL, + .parent = &ref_clk_mux, + .pll_data = { + .davinci = &pll1_data, + }, +}; + +static const char *pll1_plldiv_clk_mux_parents[] = { + "ref_clk_mux", "pll1"}; + +static struct clk_mux_data pll1_plldiv_clk_mux_data = { + .shift = PLLCTL_PLLEN_SHIFT, + .width = PLLCTL_PLLEN_WIDTH, + .num_parents= ARRAY_SIZE(pll1_plldiv_clk_mux_parents), + .parents= pll1_plldiv_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk pll1_plldiv_clk_mux = { + .name = "pll1_plldiv_clk_mux", + .parent = &pll1_clk, + .mux_data = &pll1_plldiv_clk_mux_data, +}; + +#define define_pll1_div_clk(__pll, __div, __name) \ + static struct clk_divider_data pll1_div_data##__div = { \ + .div_reg= DAVINCI_PLL1_BASE + PLLDIV##__div,\ + .width = 5,\ + }; \ + \ + static struct davinci_clk __name = {\ + .name = #__name, \ + .parent = &__pll, \ + .pll_div_data = &pll1_div_data##__div, \ + }; + +define_pll1_div_clk(pll1_plldiv_clk_mux, 1, pll1_sysclk1); +define_pll1_div_clk(pll1_plldiv_clk_mux, 2, pll1_sysclk2); +define_pll1_div_clk(pll1_plldiv_clk_mux, 3, pll1_sysclk3); +define_pll1_div_clk(pll1_plldiv_clk_mux, 4, pll1_sysclk4); +define_pll1_div_clk(pll1_plldiv_clk_mux, 5, pll1_sysclk5); + +static struct clk_divider_data pll1_sysclkbp_data = { + .div_
[PATCH v1 11/12] ARM: davinci - update the dm365 soc code to use common clk drivers
The clock tree for dm365 is defined using the structure davinci_clk. The SoC specific code re-uses clk-fixed-rate, clk-divider, clk-fixed-factor and clk-mux drivers in addition to the davinci specific clk drivers, clk-davinci-pll and clk-davinci-psc. Macros are used to define the various clocks in the SoC. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index f473745..0a44d75 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -18,6 +18,14 @@ #include #include #include +#ifdef CONFIG_COMMON_CLK +#include +#include +#include +#include +#include +#endif + #include @@ -32,11 +40,21 @@ #include #include #include +#ifdef CONFIG_COMMON_CLK +#include +#endif #include "davinci.h" -#include "clock.h" #include "mux.h" #include "asp.h" +#ifndef CONFIG_COMMON_CLK +#include "clock.h" +#else +#define PLLM 0x110 +#define PREDIV 0x114 +#define POSTDIV 0x128 +#define PLLM_PLLM_MASK 0xff +#endif #define DM365_REF_FREQ 2400/* 24 MHz on the DM365 EVM */ @@ -56,6 +74,7 @@ #define DM365_EMAC_CNTRL_RAM_OFFSET0x1000 #define DM365_EMAC_CNTRL_RAM_SIZE 0x2000 +#ifndef CONFIG_COMMON_CLK static struct pll_data pll1_data = { .num= 1, .phys_base = DAVINCI_PLL1_BASE, @@ -479,6 +498,308 @@ static struct clk_lookup dm365_clks[] = { CLK(NULL, "mjcp", &mjcp_clk), CLK(NULL, NULL, NULL), }; +#else +static struct clk_fixed_rate_data oscin_data = { + .rate = DM365_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +/* oscillator in as well as aux clock domain */ +static struct davinci_clk ref_clk_oscin = { + .name = "oscin", + .ref_clk_data = &oscin_data, +}; + +static struct clk_davinci_pll_data pll1_data = { + .phy_pllm = DAVINCI_PLL1_BASE + PLLM, + .phy_prediv = DAVINCI_PLL1_BASE + PREDIV, + .phy_postdiv= DAVINCI_PLL1_BASE + POSTDIV, + .pllm_mask = PLLM_PLLM_MASK, + .prediv_mask= PLLDIV_RATIO_MASK, + .postdiv_mask = PLLDIV_RATIO_MASK, + .num= 1, + .pll_flags = CLK_DAVINCI_PLL_HAS_PREDIV | +CLK_DAVINCI_PLL_HAS_POSTDIV, +}; + +static struct davinci_clk pll1_clk = { + .name = "pll1", + .pll_type = DAVINCI_MAIN_PLL, + .parent = &ref_clk_oscin, + .pll_data = { + .davinci= &pll1_data, + }, +}; + +static const char *pll1_plldiv_clk_mux_parents[] = { + "oscin", "pll1"}; + +static struct clk_mux_data pll1_plldiv_clk_mux_data = { + .shift = PLLCTL_PLLEN_SHIFT, + .width = PLLCTL_PLLEN_WIDTH, + .num_parents= ARRAY_SIZE(pll1_plldiv_clk_mux_parents), + .parents= pll1_plldiv_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk pll1_plldiv_clk_mux = { + .name = "pll1_plldiv_clk_mux", + .parent = &pll1_clk, + .mux_data = &pll1_plldiv_clk_mux_data, +}; + +#define define_pll1_div_clk(__pll, __div, __name) \ + static struct clk_divider_data pll1_div_data##__div = { \ + .div_reg= DAVINCI_PLL1_BASE + PLLDIV##__div,\ + .width = 5,\ + }; \ + \ + static struct davinci_clk __name = {\ + .name = #__name, \ + .parent = &__pll, \ + .pll_div_data = &pll1_div_data##__div, \ + }; + +static struct clk_fixed_factor_data fixed_clk_data = { + .mult = 1, + .div= 1, +}; + +static struct davinci_clk pll1_aux_clk = { + .name = "pll1_aux_clk", + .parent = &ref_clk_oscin, + .fixed_factor_data = &fixed_clk_data, +}; + +static struct clk_divider_data pll1_sysclkbp_data = { + .div_reg= DAVINCI_PLL2_BASE + BPDIV, + .width = 5, +}; + +static struct davinci_clk pll1_sysclkbp = { + .name = "pll1_sysclkbp", + .parent = &ref_clk_oscin, + .pll_div_data = &pll1_sysclkbp_data, +}; + +static struct clk_divider_data pll1_obsclk_data = { + .div_reg = DAVINCI_PLL1_BASE + OSCDIV1, + .width = 5, +}; + +static struct davinci_clk pll1_clkout0 = { + .name = "clkout0", +
[PATCH v1 12/12] ARM: davinci - switch to common clk framework
This patch switches the dm644x SoC code to use common clk framwork. Currently it comments the other DM devices in the Makefile to allow building of dm644x using davinci_all_defconfig. Signed-off-by: Murali Karicheri diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5f9ae5..4611987 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -967,6 +967,7 @@ config ARCH_DAVINCI select ARCH_REQUIRE_GPIOLIB select ZONE_DMA select HAVE_IDE + select COMMON_CLK select CLKDEV_LOOKUP select GENERIC_ALLOCATOR select GENERIC_IRQ_CHIP diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index ab99c3c..eb5c3eb 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -19,11 +19,15 @@ config ARCH_DAVINCI_DM644x bool "DaVinci 644x based system" select AINTC select ARCH_DAVINCI_DMx + select CLK_DAVINCI_PLL + select DAVINCI_CLKS config ARCH_DAVINCI_DM355 bool "DaVinci 355 based system" select AINTC select ARCH_DAVINCI_DMx + select CLK_DAVINCI_PLL + select DAVINCI_CLKS config ARCH_DAVINCI_DM646x bool "DaVinci 646x based system" @@ -50,6 +54,8 @@ config ARCH_DAVINCI_DM365 bool "DaVinci 365 based system" select AINTC select ARCH_DAVINCI_DMx + select CLK_DAVINCI_PLL + select DAVINCI_CLKS config ARCH_DAVINCI_TNETV107X select CPU_V6 diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 2227eff..fc88858 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -4,18 +4,25 @@ # # Common objects +ifndef CONFIG_COMMON_CLK obj-y := time.o clock.o serial.o psc.o \ dma.o usb.o common.o sram.o aemif.o +else +obj-y := time.o serial.o \ + dma.o usb.o common.o sram.o aemif.o +endif obj-$(CONFIG_DAVINCI_MUX) += mux.o # Chip specific obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o devices.o obj-$(CONFIG_ARCH_DAVINCI_DM355)+= dm355.o devices.o -obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o obj-$(CONFIG_ARCH_DAVINCI_DM365) += dm365.o devices.o +ifndef CONFIG_COMMON_CLK +obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o obj-$(CONFIG_ARCH_DAVINCI_DA830)+= da830.o devices-da8xx.o obj-$(CONFIG_ARCH_DAVINCI_DA850)+= da850.o devices-da8xx.o +endif obj-$(CONFIG_ARCH_DAVINCI_TNETV107X)+= tnetv107x.o devices-tnetv107x.o obj-$(CONFIG_AINTC)+= irq.o @@ -23,6 +30,7 @@ obj-$(CONFIG_CP_INTC) += cp_intc.o # Board specific obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o +ifndef CONFIG_COMMON_CLK obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o obj-$(CONFIG_MACH_NEUROS_OSD2) += board-neuros-osd2.o obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-dm355-evm.o @@ -31,6 +39,7 @@ obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o cdce949.o obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o +endif obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o obj-$(CONFIG_MACH_MITYOMAPL138)+= board-mityomapl138.o obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v2 00/13] Use common clk drivers for DaVinci
This is v2 of the patch series for implementing clock tree for DaVinci SoCs using common clk framework. supported platforms: DM644x, DM355 and DM365. The patch series is split in two parts:- patch 1-5 for clk drivers patch 6-13 for davinci machine specific code. revision history: - updates in v2: - updates to davinci_clk to use union for clk driver platform data - Fixed Linus Walleij' comment on code comment - added code clean up that takes out the ifdef used in previous patches updates in v1: - Added DM365 and DM355 - updates to davinci_clk struct to accomodate clk-fixed-factor data initial version:- Currently arch/arm/mach-davinci/clock.c and arch/arm/mach-davinci/psc.c implements clock drivers for DaVinci. This patch makes these code obsolete and migrate the SoC code to use the common clk based drivers. This adds two clk drivers specific to DaVinci and Keystone (found in c6x arch such as C6678) devices. Some of the existing clk drivers such as clk-fixed-rate, clk-divider, and clk-mux are re-used in addition to the DaVinci specific drivers to initialize the clock tree for the SoCs. Please refer chapter 6 of http://www.ti.com/lit/ug/sprue14c/sprue14c.pdf for details of the PLL hardware in DM6446 and chapter 7 for defails of the PSC hardware. There are two Main PLLs in DM644x. PLL1 and PLL2. Each of these generate different clocks in the DM device through PLL dividers. Figure above shows this for PLL1. Similar hardware exists for PLL2 and the related output clocks. The hardware is similar in most of the DM SoCs. Some of the recent Keystone devices (c6678 under c6x architecture) include a slight variant of the PLL that implemented different registers for the multipliers and dividers. All of these devices include PLL dividers (PLLDIVx) and Power Sleep controllers (PSC). The SoCs defines various Power Domains and Clock domains and there are PSC modules that controls power and clocks to various hardware IPs of the SoC. Following drivers are used for various clock hardware blocks:- CLKIN and OSCIN - clk-fixed-rate (existing driver) MUX - clk-mux (existing driver) PLLDIVx - clk-divider (existing driver) PLL mult/div - clk-davinci-pll (new driver) clk-keystone-pll (new driver) PSC - clk-davinci-psc.c (new driver Please note that initially only platforms listed above are supported. The idea is to review the initial patch set and get a feedback on the overall structure of the code organization. The other SoCs will be added in subsequent patch revisions. The driver code implements the features needed to support the platforms listed above. It is expected that these drivers get updated in subsequent patch revisions to support additional SoCs. I have boot tested this on DM6446 EVM. Also verified reboot command works and the clock rates are set as before. The patches depends on the following patches that I had sent for review earlier: davinci spi driver preparation @ https://patchwork.kernel.org/patch/1389321/ davinci watchdog driver preparation @ https://lkml.org/lkml/2012/9/7/634 davinci nand driver preparation @ https://lkml.org/lkml/2012/9/7/635 davinci i2c driver preparation @ https://patchwork.kernel.org/patch/1388841/ davinci gpio driver preparation @ https://lkml.org/lkml/2012/8/31/341 [RFC - PATCH] base:pm: prepare driver for common clock framework ISSUES to discuss - Following are to be discussed as part of this patch review. 1. arch/arm/pm.c. This is configuring PLL controller registers for suspend and resume. It appears that we need to move this code to clk-davinci-pll.c. But I can't find APIs for suspend and resume in the common clk framework. How is this expected to work? Currently i have kept the code ASIS. 2. There are usecount=1 in the old clock implementation for dsp, vicp and timer2 clocks. CLK_IGNORE_UNUSED flag is used currently to implement the same as disabling these unused clocks causes issues in boot up, HELP NEEDED!!: -- I am doing this work as a background activity and hence the progress will be slow. Please volunteer to help me in this effort by offering to test or migrating other devices to this framework. Murali Karicheri (13): clk: davinci - add Main PLL clock driver clk: davinci - add PSC clock driver clk: keystone - add Main PLL clock driver clk: davinci - common clk driver initialization clk: davinci - add build infrastructure ARM: davinci - restructure header files for common clk migration ARM: davinci - adding new type for cpu_clks in soc_info ARM: davinci - migrating to use davinci_common_clk_init ARM: davinci - update the dm644x soc code to use common clk drivers ARM: davinci - update the dm355 soc code to use common clk drivers ARM: davinci - update the dm365 soc code to use common clk drivers ARM: davinci - switch to common clk framework ARM: davinci - clean up the code of old dav
[PATCH 02/13] clk: davinci - add PSC clock driver
This is the driver for the Power Sleep Controller (PSC) hardware found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed code from arch/arm/mach-davinci/psc.c and implemented the driver as per common clock provider API. The PSC module is responsible for enabling/disabling the Power Domain and Clock domain for different IPs present in the SoC. The driver is configured through the platform data structure struct clk_davinci_psc_data. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/davinci/clk-davinci-psc.c b/drivers/clk/davinci/clk-davinci-psc.c new file mode 100644 index 000..b7aa332 --- /dev/null +++ b/drivers/clk/davinci/clk-davinci-psc.c @@ -0,0 +1,197 @@ +/* + * PSC clk driver for DaVinci devices + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include + +/* PSC register offsets */ +#define EPCPR 0x070 +#define PTCMD 0x120 +#define PTSTAT 0x128 +#define PDSTAT 0x200 +#define PDCTL 0x300 +#define MDSTAT 0x800 +#define MDCTL 0xA00 + +/* PSC module states */ +#define PSC_STATE_SWRSTDISABLE 0 +#define PSC_STATE_SYNCRST 1 +#define PSC_STATE_DISABLE 2 +#define PSC_STATE_ENABLE 3 + +#define MDSTAT_STATE_MASK 0x3f +#define PDSTAT_STATE_MASK 0x1f +#define MDCTL_FORCEBIT(31) +#define PDCTL_NEXT BIT(0) +#define PDCTL_EPCGOOD BIT(8) + +/* PSC flags */ +#define PSC_SWRSTDISABLE BIT(0) /* Disable state is SwRstDisable */ +#define PSC_FORCE BIT(1) /* Force module state transtition */ +#define PSC_HAS_EXT_POWER_CNTL BIT(2) /* PSC has external power control + * available (for DM6446 SoC) */ +/** + * struct clk_psc - DaVinci PSC clock + * @hw: clk_hw for the psc + * @psc_data: PSC driver specific data + * @lock: Spinlock used by the driver + */ +struct clk_psc { + struct clk_hw hw; + struct clk_davinci_psc_data *psc_data; + spinlock_t *lock; +}; + +#define to_clk_psc(_hw) container_of(_hw, struct clk_psc, hw) + +/* Enable or disable a PSC domain */ +static void clk_psc_config(void __iomem *base, unsigned int domain, + unsigned int id, bool enable, u32 flags) +{ + u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl; + u32 next_state = PSC_STATE_ENABLE; + void __iomem *psc_base = base; + + if (!enable) { + if (flags & 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); + + if (flags & PSC_HAS_EXT_POWER_CNTL) { + do { + epcpr = __raw_readl(psc_base + EPCPR); + } while epcpr >> domain) & 1) == 0)); + } + + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); + pdctl |= 0x100; + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); + + 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)); +} + +static int clk_psc_is_enabled(struct clk_hw *hw) +{ + struct clk_psc *psc = to_clk_psc(hw); + struct clk_davinci_psc_data *psc_data = psc->psc_data; + u32 mdstat; + + mdstat = __raw_readl(psc_data->base + MDSTAT + 4 * psc_data->lpsc); + /* if clocked, state can be "Enable" or "SyncReset" */ +
[PATCH 03/13] clk: keystone - add Main PLL clock driver
This is the driver for the main PLL clock hardware found on Keystone devices (c6x such as C6678). This driver is implemented as per common clock provider API. The main PLL hardware typically has a multiplier, and a divider. struct clk_keystone_pll_data is used to configure the driver for a specific platform. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/keystone/clk-keystone-pll.c b/drivers/clk/keystone/clk-keystone-pll.c new file mode 100644 index 000..0e1a1c4 --- /dev/null +++ b/drivers/clk/keystone/clk-keystone-pll.c @@ -0,0 +1,94 @@ +/* + * Main PLL clk driver for Keystone devices + * + * Copyright (C) 2012 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * struct clk_pll - DaVinci Main pll clock + * @hw: clk_hw for the pll + * @pll_data: PLL driver specific data + */ +struct clk_pll { + struct clk_hw hw; + struct clk_keystone_pll_data *pll_data; +}; + +#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw) + +static unsigned long clk_pllclk_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pll *pll = to_clk_pll(hw); + struct clk_keystone_pll_data *pll_data = pll->pll_data; + unsigned long rate = parent_rate; + u32 pllm, plld, postdiv, val; + + /* get bit0-5 of PLLM from PLLM PLL control register */ + val = __raw_readl(pll_data->pllm); + pllm = (val & pll_data->pllm_lower_mask); + + /* bit6-12 of PLLM is in Main PLL control register */ + val = __raw_readl(pll_data->main_pll_ctl0); + pllm |= ((val & pll_data->pllm_upper_mask) + >> pll_data->pllm_upper_shift); + plld = (val & pll_data->plld_mask); + postdiv = pll_data->fixed_postdiv; + + rate /= (plld + 1); + rate = (rate * (pllm + 1)); + rate /= postdiv; + + pr_notice("main_pll_clk rate is %ld, postdiv = %d, pllm = %d," \ + "plld = %d\n", rate, postdiv, pllm, plld); + return rate; +} + +static const struct clk_ops clk_pll_ops = { + .recalc_rate = clk_pllclk_recalc, +}; + +struct clk *clk_register_keystone_pll(struct device *dev, const char *name, + const char *parent_name, + struct clk_keystone_pll_data *pll_data) +{ + struct clk_init_data init; + struct clk_pll *pll; + struct clk *clk; + + if (!pll_data) + return ERR_PTR(-ENODEV); + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &clk_pll_ops; + init.flags = 0; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + pll->pll_data = pll_data; + pll->hw.init = &init; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) + kfree(pll); + + return clk; +} diff --git a/include/linux/platform_data/clk-keystone-pll.h b/include/linux/platform_data/clk-keystone-pll.h new file mode 100644 index 000..5d8f8a5 --- /dev/null +++ b/include/linux/platform_data/clk-keystone-pll.h @@ -0,0 +1,37 @@ +/* + * TI Keyston clk-pll driver platform data definitions + * + * Copyright (C) 2012 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __CLK_KEYSTONE_PLL_H +#define __CLK_KEYSTONE_PLL_H + +struct clk_keystone_pll_data { + /* register holds lower bits of PLLM */ + u32 phy_pllm; + /* holds upper bits of PLLM */ + u32 phy_main_pll_ctl0; + /* mapped addresses. should be initialized by */ + void __iomem *pllm; + void __iomem *main_pll_ctl0; + u32 pllm_lower_mask; + u32 pllm_upper_mask; + u32 pllm_upper_shift; + u32 plld_mask; + /* use this value for postdiv */ + u32 fixed_postdiv; +}; + +extern struct clk *clk_register_keystone_pll(struct device *dev, + const char *name, const char *parent_name, + struct clk_keystone_pll_data *pll_data); +#endif /* CLK_KEYSTONE_PLL_H */ -- 1.7.9.5 ___
[PATCH 06/13] ARM: davinci - restructure header files for common clk migration
As part of migrating to common clk framework usage in DaVinci SoCs, clock.h and clock.c are being deprecated as the pll and psc clock drivers are moved to drivers/clk/davinci. The relevant PLL defines are moved to include/mach/pll.h and will be used by SoC specific code instead of using clock.h. The psc.c code is being deprecated as the psc specific code is moved to the drivers/clk/davinci. So the extern definitions are not used anymore and is now conditionally included. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/include/mach/pll.h b/arch/arm/mach-davinci/include/mach/pll.h new file mode 100644 index 000..d21e5b9 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/pll.h @@ -0,0 +1,82 @@ +/* + * TI DaVinci PLL definitions + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __ASM_ARCH_PLL_H +#define __ASM_ARCH_PLL_H + +#define DAVINCI_PLL1_BASE 0x01c40800 +#define DAVINCI_PLL2_BASE 0x01c40c00 +#define MAX_PLL 2 + +/* PLL/Reset register offsets */ +#define PLLCTL 0x100 +#define PLLCTL_PLLENBIT(0) +#define PLLCTL_PLLPWRDNBIT(1) +#define PLLCTL_PLLRST BIT(3) +#define PLLCTL_PLLDIS BIT(4) +#define PLLCTL_PLLENSRCBIT(5) +#define PLLCTL_CLKMODE BIT(8) + +#define PLLCTL_CLKMODE_SHIFT 8 +#define PLLCTL_CLKMODE_WIDTH 1 +#define PLLCTL_PLLEN_SHIFT 0 +#define PLLCTL_PLLEN_WIDTH 1 + +#define PLLDIV1 0x118 +#define PLLDIV2 0x11c +#define PLLDIV3 0x120 +#define OSCDIV1 0x124 +#define BPDIV 0x12c +#define PLLCMD 0x138 +#define PLLSTAT0x13c +#define PLLALNCTL 0x140 +#define PLLDCHANGE 0x144 +#define PLLCKEN0x148 +#define PLLCKSTAT 0x14c +#define PLLSYSTAT 0x150 +#define PLLDIV4 0x160 +#define PLLDIV5 0x164 +#define PLLDIV6 0x168 +#define PLLDIV7 0x16c +#define PLLDIV8 0x170 +#define PLLDIV9 0x174 +#define PLLDIV100x178 +#define PLLDIV110x17c +#define PLLDIV120x180 +#define PLLDIV130x184 +#define PLLDIV140x188 +#define PLLDIV150x18c +#define PLLDIV160x190 +#define PLLDIV_RATIO_MASK 0x1f +#define PLLDIV_EN BIT(15) + +/* + * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN + * cycles to ensure that the PLLC has switched to bypass mode. Delay of 1us + * ensures we are good for all > 4MHz OSCIN/CLKIN inputs. Typically the input + * is ~25MHz. Units are micro seconds. + */ +#define PLL_BYPASS_TIME1 +/* From OMAP-L138 datasheet table 6-4. Units are micro seconds */ +#define PLL_RESET_TIME 1 +/* + * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4 + * Units are micro seconds. + */ +#define PLL_LOCK_TIME 20 +#define PLLSTAT_GOSTAT BIT(0) +#define PLLCMD_GOSET BIT(0) + +#endif /* __ASM_ARCH_PLL_H */ diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index 405318e..6abb94c 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h @@ -251,9 +251,11 @@ #ifndef __ASSEMBLER__ +#ifndef CONFIG_COMMON_CLK extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id); extern void davinci_psc_config(unsigned int domain, unsigned int ctlr, unsigned int id, bool enable, u32 flags); +#endif #endif diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h index 1c971d8..7faa530 100644 --- a/arch/arm/mach-davinci/include/mach/time.h +++ b/arch/arm/mach-davinci/include/mach/time.h @@ -31,5 +31,7 @@ enum { #define ID_TO_TIMER(id)(IS_TIMER1(id) != 0) extern struct davinci_timer_instance davinci_timer_instance[]; - +#ifdef CONFIG_COMMON_CLK +extern void davinci_watchdog_reset(struct platform_device *); +#endif #endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */ -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 08/13] ARM: davinci - migrating to use davinci_common_clk_init
The common clk code uses a new function davinci_common_clk_init() defined in drivers/clk/davinci/davinci-clock.c to initialize the clk drivers. This function is now invoked in time.c as part of davinci_timer_init(). Currently davinci_clk_init() is called from davinci_common_init() which is too early to initialize common clk drivers. Also include pll.h instead of clock.h in some of the source files. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index 64b0f65..f854296 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -20,7 +20,9 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#endif struct davinci_soc_info davinci_soc_info; EXPORT_SYMBOL(davinci_soc_info); @@ -106,7 +108,9 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) goto err; if (davinci_soc_info.cpu_clks) { +#ifndef CONFIG_COMMON_CLK ret = davinci_clk_init(davinci_soc_info.cpu_clks); +#endif if (ret != 0) goto err; @@ -122,5 +126,7 @@ void __init davinci_init_late(void) { davinci_cpufreq_init(); davinci_pm_init(); +#ifndef CONFIG_COMMON_CLK davinci_clk_disable_unused(); +#endif } diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index d2f96662..96ee175 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -24,7 +24,9 @@ #include #include "davinci.h" +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#endif #define DAVINCI_I2C_BASE0x01C21000 #define DAVINCI_ATA_BASE0x01C66000 diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c index eb8360b..8802fdc 100644 --- a/arch/arm/mach-davinci/pm.c +++ b/arch/arm/mach-davinci/pm.c @@ -23,7 +23,11 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#else +#include +#endif #define DEEPSLEEP_SLEEPCOUNT_MASK 0x diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S index d4e9316..5c04a7c 100644 --- a/arch/arm/mach-davinci/sleep.S +++ b/arch/arm/mach-davinci/sleep.S @@ -24,7 +24,11 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#else +#include +#endif /* Arbitrary, hardware currently does not update PHYRDY correctly */ #define PHYRDY_CYCLES 0x1000 @@ -183,6 +187,7 @@ ENDPROC(davinci_cpu_suspend) * r1: contains virtual base for DDR2 Power and Sleep controller (PSC) * r2: contains PSC number for DDR2 */ + ENTRY(davinci_ddr_psc_config) /* Set next state in mdctl for DDR2 */ mov r6, #MDCTL diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index 9847938..cc3bb96 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -18,6 +18,9 @@ #include #include #include +#ifdef CONFIG_COMMON_CLK +#include +#endif #include #include @@ -27,7 +30,9 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#endif static struct clock_event_device clockevent_davinci; static unsigned int davinci_clock_tick_rate; @@ -347,6 +352,14 @@ static void __init davinci_timer_init(void) "%s: can't register clocksource!\n"; int i; +#ifdef CONFIG_COMMON_CLK + if (davinci_soc_info.cpu_clks) { + davinci_common_clk_init(davinci_soc_info.cpu_clks, + davinci_soc_info.dev_clk_lookups, + davinci_soc_info.psc_bases_num, + davinci_soc_info.psc_bases); + } +#endif clockevent_id = soc_info->timer_info->clockevent_id; clocksource_id = soc_info->timer_info->clocksource_id; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 01/13] clk: davinci - add Main PLL clock driver
This is the driver for the main PLL clock hardware found on DM SoCs. This driver borrowed code from arch/arm/mach-davinci/clock.c and implemented the driver as per common clock provider API. The main PLL hardware typically has a multiplier, a pre-divider and a post-divider. Some of the SoCs has the divider fixed meaning they can not be configured through a register. HAS_PREDIV and HAS_POSTDIV flags are used to tell the driver if a hardware has these dividers present or not. Driver is configured through the structure clk_davinci_pll_data that has the platform data for the driver. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/davinci/clk-davinci-pll.c b/drivers/clk/davinci/clk-davinci-pll.c new file mode 100644 index 000..13e1690 --- /dev/null +++ b/drivers/clk/davinci/clk-davinci-pll.c @@ -0,0 +1,128 @@ +/* + * PLL clk driver DaVinci devices + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * TODO - Add set_parent_rate() + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +#define PLLM 0x110 +#define PLLM_PLLM_MASK 0xff +#define PREDIV 0x114 +#define POSTDIV 0x128 +#define PLLDIV_EN BIT(15) + +/** + * struct clk_davinci_pll - DaVinci Main pll clock + * @hw: clk_hw for the pll + * @pll_data: PLL driver specific data + */ +struct clk_davinci_pll { + struct clk_hw hw; + struct clk_davinci_pll_data *pll_data; +}; + +#define to_clk_pll(_hw) container_of(_hw, struct clk_davinci_pll, hw) + +static unsigned long clk_pllclk_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_davinci_pll *pll = to_clk_pll(hw); + struct clk_davinci_pll_data *pll_data = pll->pll_data; + u32 mult = 1, prediv = 1, postdiv = 1; + unsigned long rate = parent_rate; + + /* If there is a device specific recalc defined invoke it. Otherwise +* fallback to default one +*/ + mult = __raw_readl(pll_data->pllm); + if (pll_data->pllm_multiplier) + mult = pll_data->pllm_multiplier * + (mult & pll_data->pllm_mask); + else + mult = (mult & pll_data->pllm_mask) + 1; + + if (pll_data->flags & CLK_DAVINCI_PLL_HAS_PREDIV) { + /* pre-divider is fixed, take prediv value from pll_data */ + if (pll_data->fixed_prediv) + prediv = pll_data->fixed_prediv; + else { + prediv = __raw_readl(pll_data->prediv); + if (prediv & PLLDIV_EN) + prediv = (prediv & pll_data->prediv_mask) + 1; + else + prediv = 1; + } + } + + if (pll_data->flags & CLK_DAVINCI_PLL_HAS_POSTDIV) { + postdiv = __raw_readl(pll_data->postdiv); + if (postdiv & PLLDIV_EN) + postdiv = (postdiv & pll_data->postdiv_mask) + 1; + else + postdiv = 1; + } + + rate /= prediv; + rate *= mult; + rate /= postdiv; + + pr_debug("PLL%d: input = %lu MHz [ ", +pll_data->num, parent_rate / 100); + 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 / 100); + return rate; +} + +static const struct clk_ops clk_pll_ops = { + .recalc_rate = clk_pllclk_recalc, +}; + +struct clk *clk_register_davinci_pll(struct device *dev, const char *name, + const char *parent_name, + struct clk_davinci_pll_data *pll_data) +{ + struct clk_init_data init; + struct clk_davinci_pll *pll; + struct clk *clk; + + if (!pll_data) + return ERR_PTR(-ENODEV); + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + init.name = name; + init.ops = &clk_pll_ops; + init.flags = pll_data->flags; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + pll->pll_data = pll_data; + pll->hw.init = &init; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) + kfree(pll); + +
[PATCH 05/13] clk: davinci - add build infrastructure
Add Makefile and Kconfig for the DaVinci and Keystone clock drivers Signed-off-by: Murali Karicheri diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 7f0b5ca..b732dfd 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -40,4 +40,6 @@ config COMMON_CLK_WM831X Supports the clocking subsystem of the WM831x/2x series of PMICs from Wolfson Microlectronics. +source "drivers/clk/davinci/Kconfig" +source "drivers/clk/keystone/Kconfig" endmenu diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 5869ea3..f469edb 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -13,3 +13,5 @@ obj-$(CONFIG_ARCH_INTEGRATOR) += versatile/ # Chip specific obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o +obj-$(CONFIG_DAVINCI_CLKS) += davinci/ +obj-$(CONFIG_CLK_KEYSTONE_PLL) += keystone/ diff --git a/drivers/clk/davinci/Kconfig b/drivers/clk/davinci/Kconfig new file mode 100644 index 000..2202c25 --- /dev/null +++ b/drivers/clk/davinci/Kconfig @@ -0,0 +1,42 @@ +menu "TI DaVinci Clock Drivers" + depends on COMMON_CLK + +config CLK_DAVINCI_PSC + bool "TI DaVici PSC Clock driver" + default n + ---help--- + Selects clock driver for DaVinci PSC clocks. This clock + hardware is found on TI DaVinci SoCs and other SoCs that + uses this hardware IP. This hardware has a local power + sleep control module that gate the clock to the IP. + +config CLK_DAVINCI_PLL + bool "DaVici Main PLL clock" + ---help--- + Selects clock driver for DaVinci Main PLL. This clock + hardware is found on TI DaVinci SoCs. This typically has + a multiplier, a pre divider and post driver. Some of the + SoCs has the the dividers fixed, and others have it + programmable + +config DAVINCI_CLKS + bool "TI DaVinci common clocks" + default n + select CLK_DAVINCI_PSC + select DAVINCI_CLKINIT + ---help--- + Selects common clock drivers for DaVinci. These clocks + are re-used across many TI SoCs that are based on DaVinci and + Keystone (c6x) families. This config option is used to select + the common clock driver for DaVinci based SoCs. SoCs specific + Kconfig option needs to select the driver for clocks specific + to the SoC. + +config DAVINCI_CLKINIT + bool "TI DaVici Clock initialization" + default n + ---help--- + Selects clock driver initialization for DaVinci and Keystone + architectures. +endmenu + diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile new file mode 100644 index 000..420e9c3 --- /dev/null +++ b/drivers/clk/davinci/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_CLK_DAVINCI_PLL) += clk-davinci-pll.o +obj-$(CONFIG_CLK_DAVINCI_PSC) += clk-davinci-psc.o +obj-$(CONFIG_DAVINCI_CLKINIT) += davinci-clock.o diff --git a/drivers/clk/keystone/Kconfig b/drivers/clk/keystone/Kconfig new file mode 100644 index 000..c0ea97a --- /dev/null +++ b/drivers/clk/keystone/Kconfig @@ -0,0 +1,6 @@ +config CLK_KEYSTONE_PLL + bool "Keystone Main PLL clock" + ---help--- + Selects the clock driver for Keystone Main PLL. This clock + hardware is found on TI c6x based SoCs + diff --git a/drivers/clk/keystone/Makefile b/drivers/clk/keystone/Makefile new file mode 100644 index 000..6ae8ae9 --- /dev/null +++ b/drivers/clk/keystone/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_CLK_KEYSTONE_PLL) += clk-keystone-pll.o -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 04/13] clk: davinci - common clk driver initialization
This is the common clk driver initialization function for DaVinci SoCs and other SoCs that uses similar hardware architecture. Different clocks present in the SoC are passed to this function using a clk table and this function initialize the various drivers. Existing driver such as clk-fixed-rate, clk-divider, clk-mux and DaVinci specific clk drivers are initialized by this function. Also adds clock lookup for shared clocks used by various drivers. davinci-clock.h declares the various structures used for defining the DaVinci clocks. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/davinci/davinci-clock.c b/drivers/clk/davinci/davinci-clock.c new file mode 100644 index 000..cbd5201 --- /dev/null +++ b/drivers/clk/davinci/davinci-clock.c @@ -0,0 +1,232 @@ +/* + * Clock initialization code for DaVinci devices + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_SPINLOCK(_lock); + +struct clk *davinci_lookup_clk(struct davinci_clk_lookup *clocks, + const char *con_id) +{ + struct davinci_clk_lookup *c; + + for (c = clocks; c->_clk; c++) { + if (c->con_id && !strcmp(c->con_id, con_id)) + return c->clk; + } + return NULL; +} + +#ifdef CONFIG_CLK_DAVINCI_PLL +static void register_davinci_pll_clk(struct davinci_clk_lookup *c, + struct clk_davinci_pll_data *pll_data) +{ + + WARN_ON(!pll_data->phy_pllm); + pll_data->pllm = ioremap(pll_data->phy_pllm, 4); + WARN_ON(!pll_data->pllm); + if (pll_data->phy_prediv) { + pll_data->prediv = ioremap(pll_data->phy_prediv, 4); + WARN_ON(!pll_data->prediv); + } + if (pll_data->phy_postdiv) { + pll_data->postdiv = ioremap(pll_data->phy_postdiv, 4); + WARN_ON(!pll_data->postdiv); + } + c->clk = clk_register_davinci_pll(NULL, + c->_clk->name, c->_clk->parent->name, + pll_data); +} +#else +static void register_davinci_pll_clk(struct davinci_clk_lookup *c, + struct clk_davinci_pll_data *pll_data) +{ + return; +} +#endif + +#ifdef CONFIG_CLK_KEYSTONE_PLL +static void register_keystone_pll_clk(struct davinci_clk_lookup *c, + struct clk_keystone_pll_data *pll_data) +{ + WARN_ON(!pll_data->phy_pllm); + pll_data->pllm = ioremap(pll_data->phy_pllm, 4); + WARN_ON(!pll_data->pllm); + WARN_ON(!pll_data->phy_main_pll_ctl0); + pll_data->main_pll_ctl0 = + ioremap(pll_data->phy_main_pll_ctl0, 4); + WARN_ON(!pll_data->main_pll_ctl0); + c->clk = clk_register_keystone_pll(NULL, + c->_clk->name, c->_clk->parent->name, +pll_data); +} +#else +static void register_keystone_pll_clk(struct davinci_clk_lookup *c, + struct clk_keystone_pll_data *pll_data) +{ + return; +} +#endif + +int __init davinci_common_clk_init(struct davinci_clk_lookup *clocks, + struct davinci_dev_lookup *dev_clk_lookups, + u8 num_gpscs, u32 *psc_bases) +{ + void __iomem **base = NULL, *reg; + struct davinci_clk_lookup *c; + struct davinci_clk *_clk; + unsigned long rate; + int i, skip; + + WARN_ON(!num_gpscs); + WARN_ON(psc_bases == NULL); + + base = kzalloc(sizeof(void __iomem *) * num_gpscs, GFP_KERNEL); + WARN_ON(!base); + for (i = 0; i < num_gpscs; i++) { + base[i] = ioremap(psc_bases[i], SZ_4K); + WARN_ON(!base[i]); + } + + for (c = clocks; c->_clk; c++) { + skip = 0; + _clk = c->_clk; + + WARN_ON(!_clk->clk_data.data); + switch (_clk->type) { + case DAVINCI_FIXED_RATE_CLK: + { + struct clk_fixed_rate_data *data = _clk->clk_data.fixed_rate; + + if (data->recalc) + rate = data->recalc(0); + else + rate = data->rate; + + c->clk = clk_register_fixed_rate(NULL, _clk->name, + NULL, data->flags, rate); + break; + } + case KEYSTONE_MAIN_PLL
[PATCH 09/13] ARM: davinci - update the dm644x soc code to use common clk drivers
The clock tree for dm644x is defined using the new structure davinci_clk. The SoC specific code re-uses clk-fixed-rate, clk-divider and clk-mux drivers in addition to the davinci specific clk drivers, clk-davinci-pll and clk-davinci-psc. Macros are defined to define the various clocks in the SoC. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 0755d46..7a1796e 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -12,6 +12,14 @@ #include #include #include +#ifdef CONFIG_COMMON_CLK +#include +#include +#include +#include +#include +#include +#endif #include @@ -26,9 +34,16 @@ #include #include "davinci.h" -#include "clock.h" #include "mux.h" #include "asp.h" +#ifndef CONFIG_COMMON_CLK +#include "clock.h" +#else +#define PLLM 0x110 +#define PREDIV 0x114 +#define POSTDIV 0x128 +#define PLLM_PLLM_MASK 0xff +#endif /* * Device specific clocks @@ -42,6 +57,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, @@ -324,6 +340,288 @@ static struct clk_lookup dm644x_clks[] = { CLK("watchdog", NULL, &timer2_clk), CLK(NULL, NULL, NULL), }; +#else +static struct clk_davinci_pll_data pll1_data = { + .phy_pllm = DAVINCI_PLL1_BASE + PLLM, + .phy_prediv = DAVINCI_PLL1_BASE + PREDIV, + .phy_postdiv= DAVINCI_PLL1_BASE + POSTDIV, + .pllm_mask = PLLM_PLLM_MASK, + .prediv_mask= PLLDIV_RATIO_MASK, + .postdiv_mask = PLLDIV_RATIO_MASK, + .num= 1, +}; + +static struct clk_fixed_rate_data clkin_data = { + .rate = DM644X_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +static struct davinci_clk ref_clk_clkin = { + .name = "clkin", + .type = DAVINCI_FIXED_RATE_CLK, + .clk_data = { + .data = &clkin_data, + }, +}; + +static struct clk_fixed_rate_data oscin_data = { + .rate = DM644X_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +static struct davinci_clk ref_clk_oscin = { + .name = "oscin", + .type = DAVINCI_FIXED_RATE_CLK, + .clk_data = { + .data = &oscin_data, + }, +}; + +static const char *ref_clk_mux_parents[] = {"clkin", "oscin"}; + +static struct clk_mux_data ref_clk_mux_data = { + .shift = PLLCTL_CLKMODE_SHIFT, + .width = PLLCTL_CLKMODE_WIDTH, + .num_parents= ARRAY_SIZE(ref_clk_mux_parents), + .parents= ref_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk ref_clk_mux = { + .name = "ref_clk_mux", + .parent = &ref_clk_clkin, + .type = DAVINCI_MUX_CLK, + .clk_data = { + .data = &ref_clk_mux_data, + } +}; + +static struct davinci_clk pll1_clk = { + .name = "pll1", + .parent = &ref_clk_mux, + .type = DAVINCI_MAIN_PLL_CLK, + .clk_data = { + .data = &pll1_data, + }, +}; + +static const char *pll1_plldiv_clk_mux_parents[] = { + "ref_clk_mux", "pll1"}; + +static struct clk_mux_data pll1_plldiv_clk_mux_data = { + .shift = PLLCTL_PLLEN_SHIFT, + .width = PLLCTL_PLLEN_WIDTH, + .num_parents= ARRAY_SIZE(pll1_plldiv_clk_mux_parents), + .parents= pll1_plldiv_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk pll1_plldiv_clk_mux = { + .name = "pll1_plldiv_clk_mux", + .parent = &pll1_clk, + .type = DAVINCI_MUX_CLK, + .clk_data = { + .data = &pll1_plldiv_clk_mux_data, + }, +}; + +#define define_pll1_div_clk(__pll, __div, __name) \ + static struct clk_divider_data pll1_div_data##__div = { \ + .div_reg= DAVINCI_PLL1_BASE + PLLDIV##__div,\ + .width = 5,\ + }; \ + \ + static struct davinci_clk __name = {\ + .name = #__name, \ + .parent = &__pll,
[PATCH 07/13] ARM: davinci - adding new type for cpu_clks in soc_info
To define the clock nodes available on a SoC, a new structure is defined that will be used by SoC specific code to define the clock table. This table is used by davinci_common_clk_init() to initialize the clk drivers. Also added a new field dev_clk_lookups to define clock aliases for devices that share same clocks. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index bdc4aa8..8abee09 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -54,7 +54,12 @@ struct davinci_soc_info { u32 jtag_id_reg; struct davinci_id *ids; unsigned long ids_num; +#ifdef CONFIG_COMMON_CLK + struct davinci_clk_lookup *cpu_clks; + struct davinci_dev_lookup *dev_clk_lookups; +#else struct clk_lookup *cpu_clks; +#endif u32 *psc_bases; unsigned long psc_bases_num; u32 pinmux_base; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH 10/13] ARM: davinci - update the dm355 soc code to use common clk drivers
The clock tree for dm355 is defined using the new structure davinci_clk. The SoC specific code re-uses clk-fixed-rate, clk-divider, clk-fixed-factor and clk-mux drivers in addition to the davinci specific clk drivers, clk-davinci-pll and clk-davinci-psc. Macros are used to define the various clocks in the SoC. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index e47a3f0..2f398ae 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -13,8 +13,15 @@ #include #include #include - #include +#ifdef CONFIG_COMMON_CLK +#include +#include +#include +#include +#include +#include +#endif #include @@ -30,17 +37,24 @@ #include #include "davinci.h" -#include "clock.h" #include "mux.h" #include "asp.h" +#ifndef CONFIG_COMMON_CLK +#include "clock.h" +#else +#define PLLM 0x110 +#define PREDIV 0x114 +#define POSTDIV 0x128 +#define PLLM_PLLM_MASK 0xff +#endif #define DM355_UART2_BASE (IO_PHYS + 0x206000) - /* * Device specific clocks */ #define DM355_REF_FREQ 2400/* 24 or 36 MHz */ +#ifndef CONFIG_COMMON_CLK static struct pll_data pll1_data = { .num = 1, .phys_base = DAVINCI_PLL1_BASE, @@ -380,6 +394,334 @@ static struct clk_lookup dm355_clks[] = { CLK(NULL, "usb", &usb_clk), CLK(NULL, NULL, NULL), }; +#else +static struct clk_davinci_pll_data pll1_data = { + .phy_pllm = DAVINCI_PLL1_BASE + PLLM, + .phy_prediv = DAVINCI_PLL1_BASE + PREDIV, + .phy_postdiv= DAVINCI_PLL1_BASE + POSTDIV, + .pllm_mask = PLLM_PLLM_MASK, + .prediv_mask= PLLDIV_RATIO_MASK, + .postdiv_mask = PLLDIV_RATIO_MASK, + .num= 1, + .pll_flags = CLK_DAVINCI_PLL_HAS_PREDIV | +CLK_DAVINCI_PLL_HAS_POSTDIV, + .fixed_prediv = 8, +}; + +static struct clk_fixed_rate_data clkin_data = { + /* FIXME -- crystal rate is board-specific */ + .rate = DM355_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +static struct davinci_clk ref_clk_clkin = { + .name = "clkin", + .type = DAVINCI_FIXED_RATE_CLK, + .clk_data = { + .data = &clkin_data, + }, +}; + +static struct clk_fixed_rate_data oscin_data = { + /* FIXME -- crystal rate is board-specific */ + .rate = DM355_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +static struct davinci_clk ref_clk_oscin = { + .name = "oscin", + .type = DAVINCI_FIXED_RATE_CLK, + .clk_data = { + .data = &oscin_data, + }, +}; + +static const char *ref_clk_mux_parents[] = {"clkin", "oscin"}; + +static struct clk_mux_data ref_clk_mux_data = { + .shift = PLLCTL_CLKMODE_SHIFT, + .width = PLLCTL_CLKMODE_WIDTH, + .num_parents= ARRAY_SIZE(ref_clk_mux_parents), + .parents= ref_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk ref_clk_mux = { + .name = "ref_clk_mux", + .parent = &ref_clk_clkin, + .type = DAVINCI_MUX_CLK, + .clk_data = { + .data = &ref_clk_mux_data, + } +}; + +static struct davinci_clk pll1_clk = { + .name = "pll1", + .parent = &ref_clk_mux, + .type = DAVINCI_MAIN_PLL_CLK, + .clk_data = { + .data = &pll1_data, + }, +}; + +static const char *pll1_plldiv_clk_mux_parents[] = { + "ref_clk_mux", "pll1"}; + +static struct clk_mux_data pll1_plldiv_clk_mux_data = { + .shift = PLLCTL_PLLEN_SHIFT, + .width = PLLCTL_PLLEN_WIDTH, + .num_parents= ARRAY_SIZE(pll1_plldiv_clk_mux_parents), + .parents= pll1_plldiv_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk pll1_plldiv_clk_mux = { + .name = "pll1_plldiv_clk_mux", + .parent = &pll1_clk, + .type = DAVINCI_MUX_CLK, + .clk_data = { + .data = &pll1_plldiv_clk_mux_data, + }, +}; + +#define define_pll1_div_clk(__pll, __div, __name) \ + static struct clk_divider_data pll1_div_data##__div = { \ + .div_reg= DAVINCI_PLL1_BASE + PLLDIV##__div,\ + .width = 5,\ + }; \ +
[PATCH 11/13] ARM: davinci - update the dm365 soc code to use common clk drivers
The clock tree for dm365 is defined using the structure davinci_clk. The SoC specific code re-uses clk-fixed-rate, clk-divider, clk-fixed-factor and clk-mux drivers in addition to the davinci specific clk drivers, clk-davinci-pll and clk-davinci-psc. Macros are used to define the various clocks in the SoC. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index f473745..15a8264 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -18,6 +18,14 @@ #include #include #include +#ifdef CONFIG_COMMON_CLK +#include +#include +#include +#include +#include +#endif + #include @@ -32,11 +40,21 @@ #include #include #include +#ifdef CONFIG_COMMON_CLK +#include +#endif #include "davinci.h" -#include "clock.h" #include "mux.h" #include "asp.h" +#ifndef CONFIG_COMMON_CLK +#include "clock.h" +#else +#define PLLM 0x110 +#define PREDIV 0x114 +#define POSTDIV 0x128 +#define PLLM_PLLM_MASK 0xff +#endif #define DM365_REF_FREQ 2400/* 24 MHz on the DM365 EVM */ @@ -56,6 +74,7 @@ #define DM365_EMAC_CNTRL_RAM_OFFSET0x1000 #define DM365_EMAC_CNTRL_RAM_SIZE 0x2000 +#ifndef CONFIG_COMMON_CLK static struct pll_data pll1_data = { .num= 1, .phys_base = DAVINCI_PLL1_BASE, @@ -479,6 +498,344 @@ static struct clk_lookup dm365_clks[] = { CLK(NULL, "mjcp", &mjcp_clk), CLK(NULL, NULL, NULL), }; +#else +static struct clk_fixed_rate_data oscin_data = { + .rate = DM365_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +/* oscillator in as well as aux clock domain */ +static struct davinci_clk ref_clk_oscin = { + .name = "oscin", + .type = DAVINCI_FIXED_RATE_CLK, + .clk_data = { + .data = &oscin_data, + }, +}; + +static struct clk_davinci_pll_data pll1_data = { + .phy_pllm = DAVINCI_PLL1_BASE + PLLM, + .phy_prediv = DAVINCI_PLL1_BASE + PREDIV, + .phy_postdiv= DAVINCI_PLL1_BASE + POSTDIV, + .pllm_mask = PLLM_PLLM_MASK, + .prediv_mask= PLLDIV_RATIO_MASK, + .postdiv_mask = PLLDIV_RATIO_MASK, + .num= 1, + .pll_flags = CLK_DAVINCI_PLL_HAS_PREDIV | +CLK_DAVINCI_PLL_HAS_POSTDIV, +}; + +static struct davinci_clk pll1_clk = { + .name = "pll1", + .parent = &ref_clk_oscin, + .type = DAVINCI_MAIN_PLL_CLK, + .clk_data = { + .data = &pll1_data, + }, +}; + +static const char *pll1_plldiv_clk_mux_parents[] = { + "oscin", "pll1"}; + +static struct clk_mux_data pll1_plldiv_clk_mux_data = { + .shift = PLLCTL_PLLEN_SHIFT, + .width = PLLCTL_PLLEN_WIDTH, + .num_parents= ARRAY_SIZE(pll1_plldiv_clk_mux_parents), + .parents= pll1_plldiv_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk pll1_plldiv_clk_mux = { + .name = "pll1_plldiv_clk_mux", + .parent = &pll1_clk, + .type = DAVINCI_MUX_CLK, + .clk_data = { + .data = &pll1_plldiv_clk_mux_data, + }, +}; + +#define define_pll1_div_clk(__pll, __div, __name) \ + static struct clk_divider_data pll1_div_data##__div = { \ + .div_reg= DAVINCI_PLL1_BASE + PLLDIV##__div,\ + .width = 5,\ + }; \ + \ + static struct davinci_clk __name = {\ + .name = #__name, \ + .parent = &__pll, \ + .type = DAVINCI_PRG_DIV_CLK, \ + .clk_data = { \ + .data = &pll1_div_data##__div, \ + }, \ + }; + +static struct clk_fixed_factor_data fixed_clk_data = { + .mult = 1, + .div= 1, +}; + +static struct davinci_clk pll1_aux_clk = { + .name = "pll1_aux_clk", + .parent = &ref_clk_oscin, + .type = DAVINCI_FIXED_FACTOR_CLK, + .clk_data = { + .fixed_factor = &fixed_clk_data, + }, +}; + +static struct clk_divider_data pll1_sysclkbp_data = { + .div_reg= DAVINCI_PLL2_BASE + BPDIV, + .width
[PATCH 12/13] ARM: davinci - switch to common clk framework
This patch switches the dm644x SoC code to use common clk framwork. Currently it comments the other DM devices in the Makefile to allow building of dm644x using davinci_all_defconfig. Signed-off-by: Murali Karicheri diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5f9ae5..4611987 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -967,6 +967,7 @@ config ARCH_DAVINCI select ARCH_REQUIRE_GPIOLIB select ZONE_DMA select HAVE_IDE + select COMMON_CLK select CLKDEV_LOOKUP select GENERIC_ALLOCATOR select GENERIC_IRQ_CHIP diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index ab99c3c..eb5c3eb 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -19,11 +19,15 @@ config ARCH_DAVINCI_DM644x bool "DaVinci 644x based system" select AINTC select ARCH_DAVINCI_DMx + select CLK_DAVINCI_PLL + select DAVINCI_CLKS config ARCH_DAVINCI_DM355 bool "DaVinci 355 based system" select AINTC select ARCH_DAVINCI_DMx + select CLK_DAVINCI_PLL + select DAVINCI_CLKS config ARCH_DAVINCI_DM646x bool "DaVinci 646x based system" @@ -50,6 +54,8 @@ config ARCH_DAVINCI_DM365 bool "DaVinci 365 based system" select AINTC select ARCH_DAVINCI_DMx + select CLK_DAVINCI_PLL + select DAVINCI_CLKS config ARCH_DAVINCI_TNETV107X select CPU_V6 diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 2227eff..fc88858 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -4,18 +4,25 @@ # # Common objects +ifndef CONFIG_COMMON_CLK obj-y := time.o clock.o serial.o psc.o \ dma.o usb.o common.o sram.o aemif.o +else +obj-y := time.o serial.o \ + dma.o usb.o common.o sram.o aemif.o +endif obj-$(CONFIG_DAVINCI_MUX) += mux.o # Chip specific obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o devices.o obj-$(CONFIG_ARCH_DAVINCI_DM355)+= dm355.o devices.o -obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o obj-$(CONFIG_ARCH_DAVINCI_DM365) += dm365.o devices.o +ifndef CONFIG_COMMON_CLK +obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o obj-$(CONFIG_ARCH_DAVINCI_DA830)+= da830.o devices-da8xx.o obj-$(CONFIG_ARCH_DAVINCI_DA850)+= da850.o devices-da8xx.o +endif obj-$(CONFIG_ARCH_DAVINCI_TNETV107X)+= tnetv107x.o devices-tnetv107x.o obj-$(CONFIG_AINTC)+= irq.o @@ -23,6 +30,7 @@ obj-$(CONFIG_CP_INTC) += cp_intc.o # Board specific obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o +ifndef CONFIG_COMMON_CLK obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o obj-$(CONFIG_MACH_NEUROS_OSD2) += board-neuros-osd2.o obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-dm355-evm.o @@ -31,6 +39,7 @@ obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o cdce949.o obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o +endif obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o obj-$(CONFIG_MACH_MITYOMAPL138)+= board-mityomapl138.o obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v2 01/13] clk: davinci - add Main PLL clock driver
This is the driver for the main PLL clock hardware found on DM SoCs. This driver borrowed code from arch/arm/mach-davinci/clock.c and implemented the driver as per common clock provider API. The main PLL hardware typically has a multiplier, a pre-divider and a post-divider. Some of the SoCs has the divider fixed meaning they can not be configured through a register. HAS_PREDIV and HAS_POSTDIV flags are used to tell the driver if a hardware has these dividers present or not. Driver is configured through the structure clk_davinci_pll_data that has the platform data for the driver. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/davinci/clk-davinci-pll.c b/drivers/clk/davinci/clk-davinci-pll.c new file mode 100644 index 000..13e1690 --- /dev/null +++ b/drivers/clk/davinci/clk-davinci-pll.c @@ -0,0 +1,128 @@ +/* + * PLL clk driver DaVinci devices + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * TODO - Add set_parent_rate() + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +#define PLLM 0x110 +#define PLLM_PLLM_MASK 0xff +#define PREDIV 0x114 +#define POSTDIV 0x128 +#define PLLDIV_EN BIT(15) + +/** + * struct clk_davinci_pll - DaVinci Main pll clock + * @hw: clk_hw for the pll + * @pll_data: PLL driver specific data + */ +struct clk_davinci_pll { + struct clk_hw hw; + struct clk_davinci_pll_data *pll_data; +}; + +#define to_clk_pll(_hw) container_of(_hw, struct clk_davinci_pll, hw) + +static unsigned long clk_pllclk_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_davinci_pll *pll = to_clk_pll(hw); + struct clk_davinci_pll_data *pll_data = pll->pll_data; + u32 mult = 1, prediv = 1, postdiv = 1; + unsigned long rate = parent_rate; + + /* If there is a device specific recalc defined invoke it. Otherwise +* fallback to default one +*/ + mult = __raw_readl(pll_data->pllm); + if (pll_data->pllm_multiplier) + mult = pll_data->pllm_multiplier * + (mult & pll_data->pllm_mask); + else + mult = (mult & pll_data->pllm_mask) + 1; + + if (pll_data->flags & CLK_DAVINCI_PLL_HAS_PREDIV) { + /* pre-divider is fixed, take prediv value from pll_data */ + if (pll_data->fixed_prediv) + prediv = pll_data->fixed_prediv; + else { + prediv = __raw_readl(pll_data->prediv); + if (prediv & PLLDIV_EN) + prediv = (prediv & pll_data->prediv_mask) + 1; + else + prediv = 1; + } + } + + if (pll_data->flags & CLK_DAVINCI_PLL_HAS_POSTDIV) { + postdiv = __raw_readl(pll_data->postdiv); + if (postdiv & PLLDIV_EN) + postdiv = (postdiv & pll_data->postdiv_mask) + 1; + else + postdiv = 1; + } + + rate /= prediv; + rate *= mult; + rate /= postdiv; + + pr_debug("PLL%d: input = %lu MHz [ ", +pll_data->num, parent_rate / 100); + 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 / 100); + return rate; +} + +static const struct clk_ops clk_pll_ops = { + .recalc_rate = clk_pllclk_recalc, +}; + +struct clk *clk_register_davinci_pll(struct device *dev, const char *name, + const char *parent_name, + struct clk_davinci_pll_data *pll_data) +{ + struct clk_init_data init; + struct clk_davinci_pll *pll; + struct clk *clk; + + if (!pll_data) + return ERR_PTR(-ENODEV); + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + init.name = name; + init.ops = &clk_pll_ops; + init.flags = pll_data->flags; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + pll->pll_data = pll_data; + pll->hw.init = &init; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) + kfree(pll); + +
[PATCH v2 02/13] clk: davinci - add PSC clock driver
This is the driver for the Power Sleep Controller (PSC) hardware found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed code from arch/arm/mach-davinci/psc.c and implemented the driver as per common clock provider API. The PSC module is responsible for enabling/disabling the Power Domain and Clock domain for different IPs present in the SoC. The driver is configured through the platform data structure struct clk_davinci_psc_data. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/davinci/clk-davinci-psc.c b/drivers/clk/davinci/clk-davinci-psc.c new file mode 100644 index 000..b7aa332 --- /dev/null +++ b/drivers/clk/davinci/clk-davinci-psc.c @@ -0,0 +1,197 @@ +/* + * PSC clk driver for DaVinci devices + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include + +/* PSC register offsets */ +#define EPCPR 0x070 +#define PTCMD 0x120 +#define PTSTAT 0x128 +#define PDSTAT 0x200 +#define PDCTL 0x300 +#define MDSTAT 0x800 +#define MDCTL 0xA00 + +/* PSC module states */ +#define PSC_STATE_SWRSTDISABLE 0 +#define PSC_STATE_SYNCRST 1 +#define PSC_STATE_DISABLE 2 +#define PSC_STATE_ENABLE 3 + +#define MDSTAT_STATE_MASK 0x3f +#define PDSTAT_STATE_MASK 0x1f +#define MDCTL_FORCEBIT(31) +#define PDCTL_NEXT BIT(0) +#define PDCTL_EPCGOOD BIT(8) + +/* PSC flags */ +#define PSC_SWRSTDISABLE BIT(0) /* Disable state is SwRstDisable */ +#define PSC_FORCE BIT(1) /* Force module state transtition */ +#define PSC_HAS_EXT_POWER_CNTL BIT(2) /* PSC has external power control + * available (for DM6446 SoC) */ +/** + * struct clk_psc - DaVinci PSC clock + * @hw: clk_hw for the psc + * @psc_data: PSC driver specific data + * @lock: Spinlock used by the driver + */ +struct clk_psc { + struct clk_hw hw; + struct clk_davinci_psc_data *psc_data; + spinlock_t *lock; +}; + +#define to_clk_psc(_hw) container_of(_hw, struct clk_psc, hw) + +/* Enable or disable a PSC domain */ +static void clk_psc_config(void __iomem *base, unsigned int domain, + unsigned int id, bool enable, u32 flags) +{ + u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl; + u32 next_state = PSC_STATE_ENABLE; + void __iomem *psc_base = base; + + if (!enable) { + if (flags & 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); + + if (flags & PSC_HAS_EXT_POWER_CNTL) { + do { + epcpr = __raw_readl(psc_base + EPCPR); + } while epcpr >> domain) & 1) == 0)); + } + + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); + pdctl |= 0x100; + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); + + 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)); +} + +static int clk_psc_is_enabled(struct clk_hw *hw) +{ + struct clk_psc *psc = to_clk_psc(hw); + struct clk_davinci_psc_data *psc_data = psc->psc_data; + u32 mdstat; + + mdstat = __raw_readl(psc_data->base + MDSTAT + 4 * psc_data->lpsc); + /* if clocked, state can be "Enable" or "SyncReset" */ +
[PATCH v2 04/13] clk: davinci - common clk driver initialization
This is the common clk driver initialization function for DaVinci SoCs and other SoCs that uses similar hardware architecture. Different clocks present in the SoC are passed to this function using a clk table and this function initialize the various drivers. Existing driver such as clk-fixed-rate, clk-divider, clk-mux and DaVinci specific clk drivers are initialized by this function. Also adds clock lookup for shared clocks used by various drivers. davinci-clock.h declares the various structures used for defining the DaVinci clocks. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/davinci/davinci-clock.c b/drivers/clk/davinci/davinci-clock.c new file mode 100644 index 000..cbd5201 --- /dev/null +++ b/drivers/clk/davinci/davinci-clock.c @@ -0,0 +1,232 @@ +/* + * Clock initialization code for DaVinci devices + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_SPINLOCK(_lock); + +struct clk *davinci_lookup_clk(struct davinci_clk_lookup *clocks, + const char *con_id) +{ + struct davinci_clk_lookup *c; + + for (c = clocks; c->_clk; c++) { + if (c->con_id && !strcmp(c->con_id, con_id)) + return c->clk; + } + return NULL; +} + +#ifdef CONFIG_CLK_DAVINCI_PLL +static void register_davinci_pll_clk(struct davinci_clk_lookup *c, + struct clk_davinci_pll_data *pll_data) +{ + + WARN_ON(!pll_data->phy_pllm); + pll_data->pllm = ioremap(pll_data->phy_pllm, 4); + WARN_ON(!pll_data->pllm); + if (pll_data->phy_prediv) { + pll_data->prediv = ioremap(pll_data->phy_prediv, 4); + WARN_ON(!pll_data->prediv); + } + if (pll_data->phy_postdiv) { + pll_data->postdiv = ioremap(pll_data->phy_postdiv, 4); + WARN_ON(!pll_data->postdiv); + } + c->clk = clk_register_davinci_pll(NULL, + c->_clk->name, c->_clk->parent->name, + pll_data); +} +#else +static void register_davinci_pll_clk(struct davinci_clk_lookup *c, + struct clk_davinci_pll_data *pll_data) +{ + return; +} +#endif + +#ifdef CONFIG_CLK_KEYSTONE_PLL +static void register_keystone_pll_clk(struct davinci_clk_lookup *c, + struct clk_keystone_pll_data *pll_data) +{ + WARN_ON(!pll_data->phy_pllm); + pll_data->pllm = ioremap(pll_data->phy_pllm, 4); + WARN_ON(!pll_data->pllm); + WARN_ON(!pll_data->phy_main_pll_ctl0); + pll_data->main_pll_ctl0 = + ioremap(pll_data->phy_main_pll_ctl0, 4); + WARN_ON(!pll_data->main_pll_ctl0); + c->clk = clk_register_keystone_pll(NULL, + c->_clk->name, c->_clk->parent->name, +pll_data); +} +#else +static void register_keystone_pll_clk(struct davinci_clk_lookup *c, + struct clk_keystone_pll_data *pll_data) +{ + return; +} +#endif + +int __init davinci_common_clk_init(struct davinci_clk_lookup *clocks, + struct davinci_dev_lookup *dev_clk_lookups, + u8 num_gpscs, u32 *psc_bases) +{ + void __iomem **base = NULL, *reg; + struct davinci_clk_lookup *c; + struct davinci_clk *_clk; + unsigned long rate; + int i, skip; + + WARN_ON(!num_gpscs); + WARN_ON(psc_bases == NULL); + + base = kzalloc(sizeof(void __iomem *) * num_gpscs, GFP_KERNEL); + WARN_ON(!base); + for (i = 0; i < num_gpscs; i++) { + base[i] = ioremap(psc_bases[i], SZ_4K); + WARN_ON(!base[i]); + } + + for (c = clocks; c->_clk; c++) { + skip = 0; + _clk = c->_clk; + + WARN_ON(!_clk->clk_data.data); + switch (_clk->type) { + case DAVINCI_FIXED_RATE_CLK: + { + struct clk_fixed_rate_data *data = _clk->clk_data.fixed_rate; + + if (data->recalc) + rate = data->recalc(0); + else + rate = data->rate; + + c->clk = clk_register_fixed_rate(NULL, _clk->name, + NULL, data->flags, rate); + break; + } + case KEYSTONE_MAIN_PLL
[PATCH v2 00/13] Use common clk drivers for DaVinci
Resending to add revision in all patches This is v2 of the patch series for implementing clock tree for DaVinci SoCs using common clk framework. supported platforms: DM644x, DM355 and DM365. The patch series is split in two parts:- patch 1-5 for clk drivers patch 6-13 for davinci machine specific code. revision history: - updates in v2: - updates to davinci_clk to use union for clk driver platform data - Fixed Linus Walleij' comment on code comment - added code clean up that takes out the ifdef used in previous patches updates in v1: - Added DM365 and DM355 - updates to davinci_clk struct to accomodate clk-fixed-factor data initial version:- Currently arch/arm/mach-davinci/clock.c and arch/arm/mach-davinci/psc.c implements clock drivers for DaVinci. This patch makes these code obsolete and migrate the SoC code to use the common clk based drivers. This adds two clk drivers specific to DaVinci and Keystone (found in c6x arch such as C6678) devices. Some of the existing clk drivers such as clk-fixed-rate, clk-divider, and clk-mux are re-used in addition to the DaVinci specific drivers to initialize the clock tree for the SoCs. Please refer chapter 6 of http://www.ti.com/lit/ug/sprue14c/sprue14c.pdf for details of the PLL hardware in DM6446 and chapter 7 for defails of the PSC hardware. There are two Main PLLs in DM644x. PLL1 and PLL2. Each of these generate different clocks in the DM device through PLL dividers. Figure above shows this for PLL1. Similar hardware exists for PLL2 and the related output clocks. The hardware is similar in most of the DM SoCs. Some of the recent Keystone devices (c6678 under c6x architecture) include a slight variant of the PLL that implemented different registers for the multipliers and dividers. All of these devices include PLL dividers (PLLDIVx) and Power Sleep controllers (PSC). The SoCs defines various Power Domains and Clock domains and there are PSC modules that controls power and clocks to various hardware IPs of the SoC. Following drivers are used for various clock hardware blocks:- CLKIN and OSCIN - clk-fixed-rate (existing driver) MUX - clk-mux (existing driver) PLLDIVx - clk-divider (existing driver) PLL mult/div - clk-davinci-pll (new driver) clk-keystone-pll (new driver) PSC - clk-davinci-psc.c (new driver Please note that initially only platforms listed above are supported. The idea is to review the initial patch set and get a feedback on the overall structure of the code organization. The other SoCs will be added in subsequent patch revisions. The driver code implements the features needed to support the platforms listed above. It is expected that these drivers get updated in subsequent patch revisions to support additional SoCs. I have boot tested this on DM6446 EVM. Also verified reboot command works and the clock rates are set as before. The patches depends on the following patches that I had sent for review earlier: davinci spi driver preparation @ https://patchwork.kernel.org/patch/1389321/ davinci watchdog driver preparation @ https://lkml.org/lkml/2012/9/7/634 davinci nand driver preparation @ https://lkml.org/lkml/2012/9/7/635 davinci i2c driver preparation @ https://patchwork.kernel.org/patch/1388841/ davinci gpio driver preparation @ https://lkml.org/lkml/2012/8/31/341 [RFC - PATCH] base:pm: prepare driver for common clock framework ISSUES to discuss - Following are to be discussed as part of this patch review. 1. arch/arm/pm.c. This is configuring PLL controller registers for suspend and resume. It appears that we need to move this code to clk-davinci-pll.c. But I can't find APIs for suspend and resume in the common clk framework. How is this expected to work? Currently i have kept the code ASIS. 2. There are usecount=1 in the old clock implementation for dsp, vicp and timer2 clocks. CLK_IGNORE_UNUSED flag is used currently to implement the same as disabling these unused clocks causes issues in boot up, HELP NEEDED!!: -- I am doing this work as a background activity and hence the progress will be slow. Please volunteer to help me in this effort by offering to test or migrating other devices to this framework. Murali Karicheri (13): clk: davinci - add Main PLL clock driver clk: davinci - add PSC clock driver clk: keystone - add Main PLL clock driver clk: davinci - common clk driver initialization clk: davinci - add build infrastructure ARM: davinci - restructure header files for common clk migration ARM: davinci - adding new type for cpu_clks in soc_info ARM: davinci - migrating to use davinci_common_clk_init ARM: davinci - update the dm644x soc code to use common clk drivers ARM: davinci - update the dm355 soc code to use common clk drivers ARM: davinci - update the dm365 soc code to use common clk drivers ARM: davinci - switch to common clk frame
[PATCH v2 03/13] clk: keystone - add Main PLL clock driver
This is the driver for the main PLL clock hardware found on Keystone devices (c6x such as C6678). This driver is implemented as per common clock provider API. The main PLL hardware typically has a multiplier, and a divider. struct clk_keystone_pll_data is used to configure the driver for a specific platform. Signed-off-by: Murali Karicheri diff --git a/drivers/clk/keystone/clk-keystone-pll.c b/drivers/clk/keystone/clk-keystone-pll.c new file mode 100644 index 000..0e1a1c4 --- /dev/null +++ b/drivers/clk/keystone/clk-keystone-pll.c @@ -0,0 +1,94 @@ +/* + * Main PLL clk driver for Keystone devices + * + * Copyright (C) 2012 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * struct clk_pll - DaVinci Main pll clock + * @hw: clk_hw for the pll + * @pll_data: PLL driver specific data + */ +struct clk_pll { + struct clk_hw hw; + struct clk_keystone_pll_data *pll_data; +}; + +#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw) + +static unsigned long clk_pllclk_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pll *pll = to_clk_pll(hw); + struct clk_keystone_pll_data *pll_data = pll->pll_data; + unsigned long rate = parent_rate; + u32 pllm, plld, postdiv, val; + + /* get bit0-5 of PLLM from PLLM PLL control register */ + val = __raw_readl(pll_data->pllm); + pllm = (val & pll_data->pllm_lower_mask); + + /* bit6-12 of PLLM is in Main PLL control register */ + val = __raw_readl(pll_data->main_pll_ctl0); + pllm |= ((val & pll_data->pllm_upper_mask) + >> pll_data->pllm_upper_shift); + plld = (val & pll_data->plld_mask); + postdiv = pll_data->fixed_postdiv; + + rate /= (plld + 1); + rate = (rate * (pllm + 1)); + rate /= postdiv; + + pr_notice("main_pll_clk rate is %ld, postdiv = %d, pllm = %d," \ + "plld = %d\n", rate, postdiv, pllm, plld); + return rate; +} + +static const struct clk_ops clk_pll_ops = { + .recalc_rate = clk_pllclk_recalc, +}; + +struct clk *clk_register_keystone_pll(struct device *dev, const char *name, + const char *parent_name, + struct clk_keystone_pll_data *pll_data) +{ + struct clk_init_data init; + struct clk_pll *pll; + struct clk *clk; + + if (!pll_data) + return ERR_PTR(-ENODEV); + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &clk_pll_ops; + init.flags = 0; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + pll->pll_data = pll_data; + pll->hw.init = &init; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) + kfree(pll); + + return clk; +} diff --git a/include/linux/platform_data/clk-keystone-pll.h b/include/linux/platform_data/clk-keystone-pll.h new file mode 100644 index 000..5d8f8a5 --- /dev/null +++ b/include/linux/platform_data/clk-keystone-pll.h @@ -0,0 +1,37 @@ +/* + * TI Keyston clk-pll driver platform data definitions + * + * Copyright (C) 2012 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __CLK_KEYSTONE_PLL_H +#define __CLK_KEYSTONE_PLL_H + +struct clk_keystone_pll_data { + /* register holds lower bits of PLLM */ + u32 phy_pllm; + /* holds upper bits of PLLM */ + u32 phy_main_pll_ctl0; + /* mapped addresses. should be initialized by */ + void __iomem *pllm; + void __iomem *main_pll_ctl0; + u32 pllm_lower_mask; + u32 pllm_upper_mask; + u32 pllm_upper_shift; + u32 plld_mask; + /* use this value for postdiv */ + u32 fixed_postdiv; +}; + +extern struct clk *clk_register_keystone_pll(struct device *dev, + const char *name, const char *parent_name, + struct clk_keystone_pll_data *pll_data); +#endif /* CLK_KEYSTONE_PLL_H */ -- 1.7.9.5 ___
[PATCH v2 05/13] clk: davinci - add build infrastructure
Add Makefile and Kconfig for the DaVinci and Keystone clock drivers Signed-off-by: Murali Karicheri diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 7f0b5ca..b732dfd 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -40,4 +40,6 @@ config COMMON_CLK_WM831X Supports the clocking subsystem of the WM831x/2x series of PMICs from Wolfson Microlectronics. +source "drivers/clk/davinci/Kconfig" +source "drivers/clk/keystone/Kconfig" endmenu diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 5869ea3..f469edb 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -13,3 +13,5 @@ obj-$(CONFIG_ARCH_INTEGRATOR) += versatile/ # Chip specific obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o +obj-$(CONFIG_DAVINCI_CLKS) += davinci/ +obj-$(CONFIG_CLK_KEYSTONE_PLL) += keystone/ diff --git a/drivers/clk/davinci/Kconfig b/drivers/clk/davinci/Kconfig new file mode 100644 index 000..2202c25 --- /dev/null +++ b/drivers/clk/davinci/Kconfig @@ -0,0 +1,42 @@ +menu "TI DaVinci Clock Drivers" + depends on COMMON_CLK + +config CLK_DAVINCI_PSC + bool "TI DaVici PSC Clock driver" + default n + ---help--- + Selects clock driver for DaVinci PSC clocks. This clock + hardware is found on TI DaVinci SoCs and other SoCs that + uses this hardware IP. This hardware has a local power + sleep control module that gate the clock to the IP. + +config CLK_DAVINCI_PLL + bool "DaVici Main PLL clock" + ---help--- + Selects clock driver for DaVinci Main PLL. This clock + hardware is found on TI DaVinci SoCs. This typically has + a multiplier, a pre divider and post driver. Some of the + SoCs has the the dividers fixed, and others have it + programmable + +config DAVINCI_CLKS + bool "TI DaVinci common clocks" + default n + select CLK_DAVINCI_PSC + select DAVINCI_CLKINIT + ---help--- + Selects common clock drivers for DaVinci. These clocks + are re-used across many TI SoCs that are based on DaVinci and + Keystone (c6x) families. This config option is used to select + the common clock driver for DaVinci based SoCs. SoCs specific + Kconfig option needs to select the driver for clocks specific + to the SoC. + +config DAVINCI_CLKINIT + bool "TI DaVici Clock initialization" + default n + ---help--- + Selects clock driver initialization for DaVinci and Keystone + architectures. +endmenu + diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile new file mode 100644 index 000..420e9c3 --- /dev/null +++ b/drivers/clk/davinci/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_CLK_DAVINCI_PLL) += clk-davinci-pll.o +obj-$(CONFIG_CLK_DAVINCI_PSC) += clk-davinci-psc.o +obj-$(CONFIG_DAVINCI_CLKINIT) += davinci-clock.o diff --git a/drivers/clk/keystone/Kconfig b/drivers/clk/keystone/Kconfig new file mode 100644 index 000..c0ea97a --- /dev/null +++ b/drivers/clk/keystone/Kconfig @@ -0,0 +1,6 @@ +config CLK_KEYSTONE_PLL + bool "Keystone Main PLL clock" + ---help--- + Selects the clock driver for Keystone Main PLL. This clock + hardware is found on TI c6x based SoCs + diff --git a/drivers/clk/keystone/Makefile b/drivers/clk/keystone/Makefile new file mode 100644 index 000..6ae8ae9 --- /dev/null +++ b/drivers/clk/keystone/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_CLK_KEYSTONE_PLL) += clk-keystone-pll.o -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v2 09/13] ARM: davinci - update the dm644x soc code to use common clk drivers
The clock tree for dm644x is defined using the new structure davinci_clk. The SoC specific code re-uses clk-fixed-rate, clk-divider and clk-mux drivers in addition to the davinci specific clk drivers, clk-davinci-pll and clk-davinci-psc. Macros are defined to define the various clocks in the SoC. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 0755d46..7a1796e 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -12,6 +12,14 @@ #include #include #include +#ifdef CONFIG_COMMON_CLK +#include +#include +#include +#include +#include +#include +#endif #include @@ -26,9 +34,16 @@ #include #include "davinci.h" -#include "clock.h" #include "mux.h" #include "asp.h" +#ifndef CONFIG_COMMON_CLK +#include "clock.h" +#else +#define PLLM 0x110 +#define PREDIV 0x114 +#define POSTDIV 0x128 +#define PLLM_PLLM_MASK 0xff +#endif /* * Device specific clocks @@ -42,6 +57,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, @@ -324,6 +340,288 @@ static struct clk_lookup dm644x_clks[] = { CLK("watchdog", NULL, &timer2_clk), CLK(NULL, NULL, NULL), }; +#else +static struct clk_davinci_pll_data pll1_data = { + .phy_pllm = DAVINCI_PLL1_BASE + PLLM, + .phy_prediv = DAVINCI_PLL1_BASE + PREDIV, + .phy_postdiv= DAVINCI_PLL1_BASE + POSTDIV, + .pllm_mask = PLLM_PLLM_MASK, + .prediv_mask= PLLDIV_RATIO_MASK, + .postdiv_mask = PLLDIV_RATIO_MASK, + .num= 1, +}; + +static struct clk_fixed_rate_data clkin_data = { + .rate = DM644X_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +static struct davinci_clk ref_clk_clkin = { + .name = "clkin", + .type = DAVINCI_FIXED_RATE_CLK, + .clk_data = { + .data = &clkin_data, + }, +}; + +static struct clk_fixed_rate_data oscin_data = { + .rate = DM644X_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +static struct davinci_clk ref_clk_oscin = { + .name = "oscin", + .type = DAVINCI_FIXED_RATE_CLK, + .clk_data = { + .data = &oscin_data, + }, +}; + +static const char *ref_clk_mux_parents[] = {"clkin", "oscin"}; + +static struct clk_mux_data ref_clk_mux_data = { + .shift = PLLCTL_CLKMODE_SHIFT, + .width = PLLCTL_CLKMODE_WIDTH, + .num_parents= ARRAY_SIZE(ref_clk_mux_parents), + .parents= ref_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk ref_clk_mux = { + .name = "ref_clk_mux", + .parent = &ref_clk_clkin, + .type = DAVINCI_MUX_CLK, + .clk_data = { + .data = &ref_clk_mux_data, + } +}; + +static struct davinci_clk pll1_clk = { + .name = "pll1", + .parent = &ref_clk_mux, + .type = DAVINCI_MAIN_PLL_CLK, + .clk_data = { + .data = &pll1_data, + }, +}; + +static const char *pll1_plldiv_clk_mux_parents[] = { + "ref_clk_mux", "pll1"}; + +static struct clk_mux_data pll1_plldiv_clk_mux_data = { + .shift = PLLCTL_PLLEN_SHIFT, + .width = PLLCTL_PLLEN_WIDTH, + .num_parents= ARRAY_SIZE(pll1_plldiv_clk_mux_parents), + .parents= pll1_plldiv_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk pll1_plldiv_clk_mux = { + .name = "pll1_plldiv_clk_mux", + .parent = &pll1_clk, + .type = DAVINCI_MUX_CLK, + .clk_data = { + .data = &pll1_plldiv_clk_mux_data, + }, +}; + +#define define_pll1_div_clk(__pll, __div, __name) \ + static struct clk_divider_data pll1_div_data##__div = { \ + .div_reg= DAVINCI_PLL1_BASE + PLLDIV##__div,\ + .width = 5,\ + }; \ + \ + static struct davinci_clk __name = {\ + .name = #__name, \ + .parent = &__pll,
[PATCH v2 08/13] ARM: davinci - migrating to use davinci_common_clk_init
The common clk code uses a new function davinci_common_clk_init() defined in drivers/clk/davinci/davinci-clock.c to initialize the clk drivers. This function is now invoked in time.c as part of davinci_timer_init(). Currently davinci_clk_init() is called from davinci_common_init() which is too early to initialize common clk drivers. Also include pll.h instead of clock.h in some of the source files. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index 64b0f65..f854296 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -20,7 +20,9 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#endif struct davinci_soc_info davinci_soc_info; EXPORT_SYMBOL(davinci_soc_info); @@ -106,7 +108,9 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) goto err; if (davinci_soc_info.cpu_clks) { +#ifndef CONFIG_COMMON_CLK ret = davinci_clk_init(davinci_soc_info.cpu_clks); +#endif if (ret != 0) goto err; @@ -122,5 +126,7 @@ void __init davinci_init_late(void) { davinci_cpufreq_init(); davinci_pm_init(); +#ifndef CONFIG_COMMON_CLK davinci_clk_disable_unused(); +#endif } diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index d2f96662..96ee175 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -24,7 +24,9 @@ #include #include "davinci.h" +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#endif #define DAVINCI_I2C_BASE0x01C21000 #define DAVINCI_ATA_BASE0x01C66000 diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c index eb8360b..8802fdc 100644 --- a/arch/arm/mach-davinci/pm.c +++ b/arch/arm/mach-davinci/pm.c @@ -23,7 +23,11 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#else +#include +#endif #define DEEPSLEEP_SLEEPCOUNT_MASK 0x diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S index d4e9316..5c04a7c 100644 --- a/arch/arm/mach-davinci/sleep.S +++ b/arch/arm/mach-davinci/sleep.S @@ -24,7 +24,11 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#else +#include +#endif /* Arbitrary, hardware currently does not update PHYRDY correctly */ #define PHYRDY_CYCLES 0x1000 @@ -183,6 +187,7 @@ ENDPROC(davinci_cpu_suspend) * r1: contains virtual base for DDR2 Power and Sleep controller (PSC) * r2: contains PSC number for DDR2 */ + ENTRY(davinci_ddr_psc_config) /* Set next state in mdctl for DDR2 */ mov r6, #MDCTL diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index 9847938..cc3bb96 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -18,6 +18,9 @@ #include #include #include +#ifdef CONFIG_COMMON_CLK +#include +#endif #include #include @@ -27,7 +30,9 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#endif static struct clock_event_device clockevent_davinci; static unsigned int davinci_clock_tick_rate; @@ -347,6 +352,14 @@ static void __init davinci_timer_init(void) "%s: can't register clocksource!\n"; int i; +#ifdef CONFIG_COMMON_CLK + if (davinci_soc_info.cpu_clks) { + davinci_common_clk_init(davinci_soc_info.cpu_clks, + davinci_soc_info.dev_clk_lookups, + davinci_soc_info.psc_bases_num, + davinci_soc_info.psc_bases); + } +#endif clockevent_id = soc_info->timer_info->clockevent_id; clocksource_id = soc_info->timer_info->clocksource_id; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v2 11/13] ARM: davinci - update the dm365 soc code to use common clk drivers
The clock tree for dm365 is defined using the structure davinci_clk. The SoC specific code re-uses clk-fixed-rate, clk-divider, clk-fixed-factor and clk-mux drivers in addition to the davinci specific clk drivers, clk-davinci-pll and clk-davinci-psc. Macros are used to define the various clocks in the SoC. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index f473745..15a8264 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -18,6 +18,14 @@ #include #include #include +#ifdef CONFIG_COMMON_CLK +#include +#include +#include +#include +#include +#endif + #include @@ -32,11 +40,21 @@ #include #include #include +#ifdef CONFIG_COMMON_CLK +#include +#endif #include "davinci.h" -#include "clock.h" #include "mux.h" #include "asp.h" +#ifndef CONFIG_COMMON_CLK +#include "clock.h" +#else +#define PLLM 0x110 +#define PREDIV 0x114 +#define POSTDIV 0x128 +#define PLLM_PLLM_MASK 0xff +#endif #define DM365_REF_FREQ 2400/* 24 MHz on the DM365 EVM */ @@ -56,6 +74,7 @@ #define DM365_EMAC_CNTRL_RAM_OFFSET0x1000 #define DM365_EMAC_CNTRL_RAM_SIZE 0x2000 +#ifndef CONFIG_COMMON_CLK static struct pll_data pll1_data = { .num= 1, .phys_base = DAVINCI_PLL1_BASE, @@ -479,6 +498,344 @@ static struct clk_lookup dm365_clks[] = { CLK(NULL, "mjcp", &mjcp_clk), CLK(NULL, NULL, NULL), }; +#else +static struct clk_fixed_rate_data oscin_data = { + .rate = DM365_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +/* oscillator in as well as aux clock domain */ +static struct davinci_clk ref_clk_oscin = { + .name = "oscin", + .type = DAVINCI_FIXED_RATE_CLK, + .clk_data = { + .data = &oscin_data, + }, +}; + +static struct clk_davinci_pll_data pll1_data = { + .phy_pllm = DAVINCI_PLL1_BASE + PLLM, + .phy_prediv = DAVINCI_PLL1_BASE + PREDIV, + .phy_postdiv= DAVINCI_PLL1_BASE + POSTDIV, + .pllm_mask = PLLM_PLLM_MASK, + .prediv_mask= PLLDIV_RATIO_MASK, + .postdiv_mask = PLLDIV_RATIO_MASK, + .num= 1, + .pll_flags = CLK_DAVINCI_PLL_HAS_PREDIV | +CLK_DAVINCI_PLL_HAS_POSTDIV, +}; + +static struct davinci_clk pll1_clk = { + .name = "pll1", + .parent = &ref_clk_oscin, + .type = DAVINCI_MAIN_PLL_CLK, + .clk_data = { + .data = &pll1_data, + }, +}; + +static const char *pll1_plldiv_clk_mux_parents[] = { + "oscin", "pll1"}; + +static struct clk_mux_data pll1_plldiv_clk_mux_data = { + .shift = PLLCTL_PLLEN_SHIFT, + .width = PLLCTL_PLLEN_WIDTH, + .num_parents= ARRAY_SIZE(pll1_plldiv_clk_mux_parents), + .parents= pll1_plldiv_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk pll1_plldiv_clk_mux = { + .name = "pll1_plldiv_clk_mux", + .parent = &pll1_clk, + .type = DAVINCI_MUX_CLK, + .clk_data = { + .data = &pll1_plldiv_clk_mux_data, + }, +}; + +#define define_pll1_div_clk(__pll, __div, __name) \ + static struct clk_divider_data pll1_div_data##__div = { \ + .div_reg= DAVINCI_PLL1_BASE + PLLDIV##__div,\ + .width = 5,\ + }; \ + \ + static struct davinci_clk __name = {\ + .name = #__name, \ + .parent = &__pll, \ + .type = DAVINCI_PRG_DIV_CLK, \ + .clk_data = { \ + .data = &pll1_div_data##__div, \ + }, \ + }; + +static struct clk_fixed_factor_data fixed_clk_data = { + .mult = 1, + .div= 1, +}; + +static struct davinci_clk pll1_aux_clk = { + .name = "pll1_aux_clk", + .parent = &ref_clk_oscin, + .type = DAVINCI_FIXED_FACTOR_CLK, + .clk_data = { + .fixed_factor = &fixed_clk_data, + }, +}; + +static struct clk_divider_data pll1_sysclkbp_data = { + .div_reg= DAVINCI_PLL2_BASE + BPDIV, + .width
[PATCH v2 07/13] ARM: davinci - adding new type for cpu_clks in soc_info
To define the clock nodes available on a SoC, a new structure is defined that will be used by SoC specific code to define the clock table. This table is used by davinci_common_clk_init() to initialize the clk drivers. Also added a new field dev_clk_lookups to define clock aliases for devices that share same clocks. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index bdc4aa8..8abee09 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -54,7 +54,12 @@ struct davinci_soc_info { u32 jtag_id_reg; struct davinci_id *ids; unsigned long ids_num; +#ifdef CONFIG_COMMON_CLK + struct davinci_clk_lookup *cpu_clks; + struct davinci_dev_lookup *dev_clk_lookups; +#else struct clk_lookup *cpu_clks; +#endif u32 *psc_bases; unsigned long psc_bases_num; u32 pinmux_base; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v2 06/13] ARM: davinci - restructure header files for common clk migration
As part of migrating to common clk framework usage in DaVinci SoCs, clock.h and clock.c are being deprecated as the pll and psc clock drivers are moved to drivers/clk/davinci. The relevant PLL defines are moved to include/mach/pll.h and will be used by SoC specific code instead of using clock.h. The psc.c code is being deprecated as the psc specific code is moved to the drivers/clk/davinci. So the extern definitions are not used anymore and is now conditionally included. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/include/mach/pll.h b/arch/arm/mach-davinci/include/mach/pll.h new file mode 100644 index 000..d21e5b9 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/pll.h @@ -0,0 +1,82 @@ +/* + * TI DaVinci PLL definitions + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __ASM_ARCH_PLL_H +#define __ASM_ARCH_PLL_H + +#define DAVINCI_PLL1_BASE 0x01c40800 +#define DAVINCI_PLL2_BASE 0x01c40c00 +#define MAX_PLL 2 + +/* PLL/Reset register offsets */ +#define PLLCTL 0x100 +#define PLLCTL_PLLENBIT(0) +#define PLLCTL_PLLPWRDNBIT(1) +#define PLLCTL_PLLRST BIT(3) +#define PLLCTL_PLLDIS BIT(4) +#define PLLCTL_PLLENSRCBIT(5) +#define PLLCTL_CLKMODE BIT(8) + +#define PLLCTL_CLKMODE_SHIFT 8 +#define PLLCTL_CLKMODE_WIDTH 1 +#define PLLCTL_PLLEN_SHIFT 0 +#define PLLCTL_PLLEN_WIDTH 1 + +#define PLLDIV1 0x118 +#define PLLDIV2 0x11c +#define PLLDIV3 0x120 +#define OSCDIV1 0x124 +#define BPDIV 0x12c +#define PLLCMD 0x138 +#define PLLSTAT0x13c +#define PLLALNCTL 0x140 +#define PLLDCHANGE 0x144 +#define PLLCKEN0x148 +#define PLLCKSTAT 0x14c +#define PLLSYSTAT 0x150 +#define PLLDIV4 0x160 +#define PLLDIV5 0x164 +#define PLLDIV6 0x168 +#define PLLDIV7 0x16c +#define PLLDIV8 0x170 +#define PLLDIV9 0x174 +#define PLLDIV100x178 +#define PLLDIV110x17c +#define PLLDIV120x180 +#define PLLDIV130x184 +#define PLLDIV140x188 +#define PLLDIV150x18c +#define PLLDIV160x190 +#define PLLDIV_RATIO_MASK 0x1f +#define PLLDIV_EN BIT(15) + +/* + * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN + * cycles to ensure that the PLLC has switched to bypass mode. Delay of 1us + * ensures we are good for all > 4MHz OSCIN/CLKIN inputs. Typically the input + * is ~25MHz. Units are micro seconds. + */ +#define PLL_BYPASS_TIME1 +/* From OMAP-L138 datasheet table 6-4. Units are micro seconds */ +#define PLL_RESET_TIME 1 +/* + * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4 + * Units are micro seconds. + */ +#define PLL_LOCK_TIME 20 +#define PLLSTAT_GOSTAT BIT(0) +#define PLLCMD_GOSET BIT(0) + +#endif /* __ASM_ARCH_PLL_H */ diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index 405318e..6abb94c 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h @@ -251,9 +251,11 @@ #ifndef __ASSEMBLER__ +#ifndef CONFIG_COMMON_CLK extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id); extern void davinci_psc_config(unsigned int domain, unsigned int ctlr, unsigned int id, bool enable, u32 flags); +#endif #endif diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h index 1c971d8..7faa530 100644 --- a/arch/arm/mach-davinci/include/mach/time.h +++ b/arch/arm/mach-davinci/include/mach/time.h @@ -31,5 +31,7 @@ enum { #define ID_TO_TIMER(id)(IS_TIMER1(id) != 0) extern struct davinci_timer_instance davinci_timer_instance[]; - +#ifdef CONFIG_COMMON_CLK +extern void davinci_watchdog_reset(struct platform_device *); +#endif #endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */ -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v2 12/13] ARM: davinci - switch to common clk framework
This patch switches the dm644x SoC code to use common clk framwork. Currently it comments the other DM devices in the Makefile to allow building of dm644x using davinci_all_defconfig. Signed-off-by: Murali Karicheri diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5f9ae5..4611987 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -967,6 +967,7 @@ config ARCH_DAVINCI select ARCH_REQUIRE_GPIOLIB select ZONE_DMA select HAVE_IDE + select COMMON_CLK select CLKDEV_LOOKUP select GENERIC_ALLOCATOR select GENERIC_IRQ_CHIP diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index ab99c3c..eb5c3eb 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -19,11 +19,15 @@ config ARCH_DAVINCI_DM644x bool "DaVinci 644x based system" select AINTC select ARCH_DAVINCI_DMx + select CLK_DAVINCI_PLL + select DAVINCI_CLKS config ARCH_DAVINCI_DM355 bool "DaVinci 355 based system" select AINTC select ARCH_DAVINCI_DMx + select CLK_DAVINCI_PLL + select DAVINCI_CLKS config ARCH_DAVINCI_DM646x bool "DaVinci 646x based system" @@ -50,6 +54,8 @@ config ARCH_DAVINCI_DM365 bool "DaVinci 365 based system" select AINTC select ARCH_DAVINCI_DMx + select CLK_DAVINCI_PLL + select DAVINCI_CLKS config ARCH_DAVINCI_TNETV107X select CPU_V6 diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 2227eff..fc88858 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -4,18 +4,25 @@ # # Common objects +ifndef CONFIG_COMMON_CLK obj-y := time.o clock.o serial.o psc.o \ dma.o usb.o common.o sram.o aemif.o +else +obj-y := time.o serial.o \ + dma.o usb.o common.o sram.o aemif.o +endif obj-$(CONFIG_DAVINCI_MUX) += mux.o # Chip specific obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o devices.o obj-$(CONFIG_ARCH_DAVINCI_DM355)+= dm355.o devices.o -obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o obj-$(CONFIG_ARCH_DAVINCI_DM365) += dm365.o devices.o +ifndef CONFIG_COMMON_CLK +obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o obj-$(CONFIG_ARCH_DAVINCI_DA830)+= da830.o devices-da8xx.o obj-$(CONFIG_ARCH_DAVINCI_DA850)+= da850.o devices-da8xx.o +endif obj-$(CONFIG_ARCH_DAVINCI_TNETV107X)+= tnetv107x.o devices-tnetv107x.o obj-$(CONFIG_AINTC)+= irq.o @@ -23,6 +30,7 @@ obj-$(CONFIG_CP_INTC) += cp_intc.o # Board specific obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o +ifndef CONFIG_COMMON_CLK obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o obj-$(CONFIG_MACH_NEUROS_OSD2) += board-neuros-osd2.o obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-dm355-evm.o @@ -31,6 +39,7 @@ obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o cdce949.o obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o +endif obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o obj-$(CONFIG_MACH_MITYOMAPL138)+= board-mityomapl138.o obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v2 10/13] ARM: davinci - update the dm355 soc code to use common clk drivers
The clock tree for dm355 is defined using the new structure davinci_clk. The SoC specific code re-uses clk-fixed-rate, clk-divider, clk-fixed-factor and clk-mux drivers in addition to the davinci specific clk drivers, clk-davinci-pll and clk-davinci-psc. Macros are used to define the various clocks in the SoC. Signed-off-by: Murali Karicheri diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index e47a3f0..2f398ae 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -13,8 +13,15 @@ #include #include #include - #include +#ifdef CONFIG_COMMON_CLK +#include +#include +#include +#include +#include +#include +#endif #include @@ -30,17 +37,24 @@ #include #include "davinci.h" -#include "clock.h" #include "mux.h" #include "asp.h" +#ifndef CONFIG_COMMON_CLK +#include "clock.h" +#else +#define PLLM 0x110 +#define PREDIV 0x114 +#define POSTDIV 0x128 +#define PLLM_PLLM_MASK 0xff +#endif #define DM355_UART2_BASE (IO_PHYS + 0x206000) - /* * Device specific clocks */ #define DM355_REF_FREQ 2400/* 24 or 36 MHz */ +#ifndef CONFIG_COMMON_CLK static struct pll_data pll1_data = { .num = 1, .phys_base = DAVINCI_PLL1_BASE, @@ -380,6 +394,334 @@ static struct clk_lookup dm355_clks[] = { CLK(NULL, "usb", &usb_clk), CLK(NULL, NULL, NULL), }; +#else +static struct clk_davinci_pll_data pll1_data = { + .phy_pllm = DAVINCI_PLL1_BASE + PLLM, + .phy_prediv = DAVINCI_PLL1_BASE + PREDIV, + .phy_postdiv= DAVINCI_PLL1_BASE + POSTDIV, + .pllm_mask = PLLM_PLLM_MASK, + .prediv_mask= PLLDIV_RATIO_MASK, + .postdiv_mask = PLLDIV_RATIO_MASK, + .num= 1, + .pll_flags = CLK_DAVINCI_PLL_HAS_PREDIV | +CLK_DAVINCI_PLL_HAS_POSTDIV, + .fixed_prediv = 8, +}; + +static struct clk_fixed_rate_data clkin_data = { + /* FIXME -- crystal rate is board-specific */ + .rate = DM355_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +static struct davinci_clk ref_clk_clkin = { + .name = "clkin", + .type = DAVINCI_FIXED_RATE_CLK, + .clk_data = { + .data = &clkin_data, + }, +}; + +static struct clk_fixed_rate_data oscin_data = { + /* FIXME -- crystal rate is board-specific */ + .rate = DM355_REF_FREQ, + .flags = CLK_IS_ROOT, +}; + +static struct davinci_clk ref_clk_oscin = { + .name = "oscin", + .type = DAVINCI_FIXED_RATE_CLK, + .clk_data = { + .data = &oscin_data, + }, +}; + +static const char *ref_clk_mux_parents[] = {"clkin", "oscin"}; + +static struct clk_mux_data ref_clk_mux_data = { + .shift = PLLCTL_CLKMODE_SHIFT, + .width = PLLCTL_CLKMODE_WIDTH, + .num_parents= ARRAY_SIZE(ref_clk_mux_parents), + .parents= ref_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk ref_clk_mux = { + .name = "ref_clk_mux", + .parent = &ref_clk_clkin, + .type = DAVINCI_MUX_CLK, + .clk_data = { + .data = &ref_clk_mux_data, + } +}; + +static struct davinci_clk pll1_clk = { + .name = "pll1", + .parent = &ref_clk_mux, + .type = DAVINCI_MAIN_PLL_CLK, + .clk_data = { + .data = &pll1_data, + }, +}; + +static const char *pll1_plldiv_clk_mux_parents[] = { + "ref_clk_mux", "pll1"}; + +static struct clk_mux_data pll1_plldiv_clk_mux_data = { + .shift = PLLCTL_PLLEN_SHIFT, + .width = PLLCTL_PLLEN_WIDTH, + .num_parents= ARRAY_SIZE(pll1_plldiv_clk_mux_parents), + .parents= pll1_plldiv_clk_mux_parents, + .phys_base = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static struct davinci_clk pll1_plldiv_clk_mux = { + .name = "pll1_plldiv_clk_mux", + .parent = &pll1_clk, + .type = DAVINCI_MUX_CLK, + .clk_data = { + .data = &pll1_plldiv_clk_mux_data, + }, +}; + +#define define_pll1_div_clk(__pll, __div, __name) \ + static struct clk_divider_data pll1_div_data##__div = { \ + .div_reg= DAVINCI_PLL1_BASE + PLLDIV##__div,\ + .width = 5,\ + }; \ +
[RESEND-PATCH] media:davinci: clk - {prepare/unprepare} for common clk
As a first step towards migrating davinci platforms to use common clock framework, replace all instances of clk_enable() with clk_prepare_enable() and clk_disable() with clk_disable_unprepare(). Also fixes some issues related to clk clean up in the driver Signed-off-by: Murali Karicheri --- rebased to v3.7-rc1 drivers/media/platform/davinci/dm355_ccdc.c |8 ++-- drivers/media/platform/davinci/dm644x_ccdc.c | 16 ++-- drivers/media/platform/davinci/isif.c|5 - drivers/media/platform/davinci/vpbe.c| 10 +++--- drivers/media/platform/davinci/vpif.c|8 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c index ce0e413..030950d 100644 --- a/drivers/media/platform/davinci/dm355_ccdc.c +++ b/drivers/media/platform/davinci/dm355_ccdc.c @@ -1003,7 +1003,7 @@ static int __devinit dm355_ccdc_probe(struct platform_device *pdev) status = PTR_ERR(ccdc_cfg.mclk); goto fail_nomap; } - if (clk_enable(ccdc_cfg.mclk)) { + if (clk_prepare_enable(ccdc_cfg.mclk)) { status = -ENODEV; goto fail_mclk; } @@ -1014,7 +1014,7 @@ static int __devinit dm355_ccdc_probe(struct platform_device *pdev) status = PTR_ERR(ccdc_cfg.sclk); goto fail_mclk; } - if (clk_enable(ccdc_cfg.sclk)) { + if (clk_prepare_enable(ccdc_cfg.sclk)) { status = -ENODEV; goto fail_sclk; } @@ -1034,8 +1034,10 @@ static int __devinit dm355_ccdc_probe(struct platform_device *pdev) printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name); return 0; fail_sclk: + clk_disable_unprepare(ccdc_cfg.sclk); clk_put(ccdc_cfg.sclk); fail_mclk: + clk_disable_unprepare(ccdc_cfg.mclk); clk_put(ccdc_cfg.mclk); fail_nomap: iounmap(ccdc_cfg.base_addr); @@ -1050,6 +1052,8 @@ static int dm355_ccdc_remove(struct platform_device *pdev) { struct resource *res; + clk_disable_unprepare(ccdc_cfg.sclk); + clk_disable_unprepare(ccdc_cfg.mclk); clk_put(ccdc_cfg.mclk); clk_put(ccdc_cfg.sclk); iounmap(ccdc_cfg.base_addr); diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c index ee7942b..0215ab6 100644 --- a/drivers/media/platform/davinci/dm644x_ccdc.c +++ b/drivers/media/platform/davinci/dm644x_ccdc.c @@ -994,7 +994,7 @@ static int __devinit dm644x_ccdc_probe(struct platform_device *pdev) status = PTR_ERR(ccdc_cfg.mclk); goto fail_nomap; } - if (clk_enable(ccdc_cfg.mclk)) { + if (clk_prepare_enable(ccdc_cfg.mclk)) { status = -ENODEV; goto fail_mclk; } @@ -1005,7 +1005,7 @@ static int __devinit dm644x_ccdc_probe(struct platform_device *pdev) status = PTR_ERR(ccdc_cfg.sclk); goto fail_mclk; } - if (clk_enable(ccdc_cfg.sclk)) { + if (clk_prepare_enable(ccdc_cfg.sclk)) { status = -ENODEV; goto fail_sclk; } @@ -1013,8 +1013,10 @@ static int __devinit dm644x_ccdc_probe(struct platform_device *pdev) printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name); return 0; fail_sclk: + clk_disable_unprepare(ccdc_cfg.sclk); clk_put(ccdc_cfg.sclk); fail_mclk: + clk_disable_unprepare(ccdc_cfg.mclk); clk_put(ccdc_cfg.mclk); fail_nomap: iounmap(ccdc_cfg.base_addr); @@ -1029,6 +1031,8 @@ static int dm644x_ccdc_remove(struct platform_device *pdev) { struct resource *res; + clk_disable_unprepare(ccdc_cfg.mclk); + clk_disable_unprepare(ccdc_cfg.sclk); clk_put(ccdc_cfg.mclk); clk_put(ccdc_cfg.sclk); iounmap(ccdc_cfg.base_addr); @@ -1046,8 +1050,8 @@ static int dm644x_ccdc_suspend(struct device *dev) /* Disable CCDC */ ccdc_enable(0); /* Disable both master and slave clock */ - clk_disable(ccdc_cfg.mclk); - clk_disable(ccdc_cfg.sclk); + clk_disable_unprepare(ccdc_cfg.mclk); + clk_disable_unprepare(ccdc_cfg.sclk); return 0; } @@ -1055,8 +1059,8 @@ static int dm644x_ccdc_suspend(struct device *dev) static int dm644x_ccdc_resume(struct device *dev) { /* Enable both master and slave clock */ - clk_enable(ccdc_cfg.mclk); - clk_enable(ccdc_cfg.sclk); + clk_prepare_enable(ccdc_cfg.mclk); + clk_prepare_enable(ccdc_cfg.sclk); /* Restore CCDC context */ ccdc_restore_context(); diff --git a/drivers/media/platform/davinci/isif.c b/drivers/media/platform/davinci/isif.c index b99d542..2c26c3e 100644 --- a/drivers/media/platform/davinci/isif.c +++ b/drivers/media/platform/davin
[PATCH v3 01/11] clk: davinci - add main PLL clock driver
This is the driver for the main PLL clock hardware found on DM SoCs. This driver borrowed code from arch/arm/mach-davinci/clock.c and implemented the driver as per common clock provider API. The main PLL hardware typically has a multiplier, a pre-divider and a post-divider. Some of the SoCs has the divider fixed meaning they can not be configured through a register. HAS_PREDIV and HAS_POSTDIV flags are used to tell the driver if a hardware has these dividers present or not. Driver is configured through the struct clk_pll_data that has the SoC specific clock data. Signed-off-by: Murali Karicheri --- drivers/clk/davinci/clk-pll.c | 146 + drivers/clk/davinci/clk-pll.h | 57 2 files changed, 203 insertions(+) create mode 100644 drivers/clk/davinci/clk-pll.c create mode 100644 drivers/clk/davinci/clk-pll.h diff --git a/drivers/clk/davinci/clk-pll.c b/drivers/clk/davinci/clk-pll.c new file mode 100644 index 000..337e9af --- /dev/null +++ b/drivers/clk/davinci/clk-pll.c @@ -0,0 +1,146 @@ +/* + * DaVinci main pll clk driver + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * DaVinci PLL clk driver implementation + * + * TODO - Add set_parent_rate() + */ +#include +#include +#include +#include +#include +#include + +#include "clk-pll.h" + +#define PLLDIV_EN BIT(15) + +/** + * struct clk_pll - DaVinci main pll clock + * @hw: clk_hw for the pll + * @pll_data: ptr to driver specific data + */ +struct clk_pll { + struct clk_hw hw; + struct clk_pll_data *pll_data; +}; + +#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw) + +/** + * clk_pllclk_recalc() - function to calculate rate + * + * @hw: clk_hw for the pll + * @parent_rate: Parent clk rate + */ +static unsigned long clk_pllclk_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pll *pll = to_clk_pll(hw); + struct clk_pll_data *pll_data = pll->pll_data; + u32 mult = 1, prediv = 1, postdiv = 1; + unsigned long rate = parent_rate; + + mult = readl(pll_data->reg_pllm); + + /* +* if fixed_multiplier is non zero, multiply pllm value by this +* value. +*/ + if (pll_data->fixed_multiplier) + mult = pll_data->fixed_multiplier * + (mult & pll_data->pllm_mask); + else + mult = (mult & pll_data->pllm_mask) + 1; + + if (pll_data->pll_flags & CLK_DAVINCI_PLL_HAS_PREDIV) { + /* +* prediv register is not present, take fixed_prediv value from +* pll_data for prediv +*/ + if (pll_data->fixed_prediv) { + prediv = pll_data->fixed_prediv; + } else { + prediv = readl(pll_data->reg_prediv); + if (prediv & PLLDIV_EN) + prediv = (prediv & pll_data->prediv_mask) + 1; + else + prediv = 1; + } + } + + if (pll_data->pll_flags & CLK_DAVINCI_PLL_HAS_POSTDIV) { + postdiv = readl(pll_data->reg_postdiv); + if (postdiv & PLLDIV_EN) + postdiv = (postdiv & pll_data->postdiv_mask) + 1; + else + postdiv = 1; + } + + rate /= prediv; + rate *= mult; + rate /= postdiv; + + pr_debug("PLL%d: input = %lu MHz [ ", +pll_data->num, parent_rate / 100); + 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 / 100); + + return rate; +} + +static const struct clk_ops clk_pll_ops = { + .recalc_rate = clk_pllclk_recalc, +}; + +/** + * clk_register_davinci_pll() - register function for DaVinci main pll clk + * + * @dev: device ptr + * @name: name of the clk + * @parent_name: name of the parent clk + * @pll_data: ptr to pll clk data + */ +struct clk *clk_register_davinci_pll(struct device *dev, const char *name, + const char *parent_name, + struct clk_pll_data *pll_data) +{ + struct clk_init_data init; + struct clk_pll *pll; + struct clk *clk; + + if (!pll_data) + return ERR_PTR(-ENODEV); + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); +
[PATCH v3 00/11] common clk drivers migration for DaVinci SoCs
igrating other devices to this framework. Murali Karicheri (11): clk: davinci - add main PLL clock driver clk: davinci - add PSC clock driver clk: davinci - common clk utilities to init clk driver clk: davinci - add pll divider clock driver clk: davinci - add dm644x clock initialization clk: davinci - add build infrastructure for DaVinci clock drivers ARM: davinci - restructure header files for common clock migration ARM: davinci - migrating to use common clock init code ARM: davinci - dm644x: update SoC code to remove the clock data ARM: davinci - migrate to common clock ARM: davinci - common clock migration: clean up the old code arch/arm/Kconfig|1 + arch/arm/mach-davinci/Kconfig |2 + arch/arm/mach-davinci/Makefile | 15 +- arch/arm/mach-davinci/clock.c | 669 --- arch/arm/mach-davinci/clock.h | 135 -- arch/arm/mach-davinci/common.c | 10 - arch/arm/mach-davinci/cpufreq.c |2 - arch/arm/mach-davinci/davinci.h |3 + arch/arm/mach-davinci/devices.c |1 - arch/arm/mach-davinci/dm644x.c | 302 +--- arch/arm/mach-davinci/include/mach/clock.h | 21 - arch/arm/mach-davinci/include/mach/common.h | 10 +- arch/arm/mach-davinci/include/mach/pll.h| 46 ++ arch/arm/mach-davinci/include/mach/psc.h| 209 - arch/arm/mach-davinci/include/mach/time.h |2 +- arch/arm/mach-davinci/pm.c |3 +- arch/arm/mach-davinci/psc.c | 112 - arch/arm/mach-davinci/sleep.S |3 +- arch/arm/mach-davinci/time.c|6 +- drivers/clk/Kconfig |2 + drivers/clk/Makefile|1 + drivers/clk/davinci/Kconfig | 44 ++ drivers/clk/davinci/Makefile|5 + drivers/clk/davinci/clk-div.c | 124 + drivers/clk/davinci/clk-div.h | 42 ++ drivers/clk/davinci/clk-pll.c | 146 ++ drivers/clk/davinci/clk-pll.h | 57 +++ drivers/clk/davinci/clk-psc.c | 207 + drivers/clk/davinci/clk-psc.h | 46 ++ drivers/clk/davinci/clock.c | 112 + drivers/clk/davinci/clock.h | 80 drivers/clk/davinci/dm644x-clock.c | 304 drivers/clk/davinci/pll.h | 83 drivers/clk/davinci/psc.h | 215 + 34 files changed, 1530 insertions(+), 1490 deletions(-) delete mode 100644 arch/arm/mach-davinci/clock.c delete mode 100644 arch/arm/mach-davinci/clock.h delete mode 100644 arch/arm/mach-davinci/include/mach/clock.h create mode 100644 arch/arm/mach-davinci/include/mach/pll.h delete mode 100644 arch/arm/mach-davinci/psc.c create mode 100644 drivers/clk/davinci/Kconfig create mode 100644 drivers/clk/davinci/Makefile create mode 100644 drivers/clk/davinci/clk-div.c create mode 100644 drivers/clk/davinci/clk-div.h create mode 100644 drivers/clk/davinci/clk-pll.c create mode 100644 drivers/clk/davinci/clk-pll.h create mode 100644 drivers/clk/davinci/clk-psc.c create mode 100644 drivers/clk/davinci/clk-psc.h create mode 100644 drivers/clk/davinci/clock.c create mode 100644 drivers/clk/davinci/clock.h create mode 100644 drivers/clk/davinci/dm644x-clock.c create mode 100644 drivers/clk/davinci/pll.h create mode 100644 drivers/clk/davinci/psc.h -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v3 04/11] clk: davinci - add pll divider clock driver
pll dividers are present in the pll controller of DaVinci and Other SoCs that re-uses the same hardware IP. This has a enable bit for bypass the divider or enable the driver. This is a sub class of the clk-divider clock checks the enable bit to calculare the rate and invoke the recalculate() function of the clk-divider if enabled. Signed-off-by: Murali Karicheri --- drivers/clk/davinci/clk-div.c | 124 + drivers/clk/davinci/clk-div.h | 42 ++ 2 files changed, 166 insertions(+) create mode 100644 drivers/clk/davinci/clk-div.c create mode 100644 drivers/clk/davinci/clk-div.h diff --git a/drivers/clk/davinci/clk-div.c b/drivers/clk/davinci/clk-div.c new file mode 100644 index 000..8147d99 --- /dev/null +++ b/drivers/clk/davinci/clk-div.c @@ -0,0 +1,124 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2012 Texas instuments + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + */ + +#include +#include +#include +#include +#include + +#include "clk-div.h" + +/** + * struct clk_div - DaVinci integer pll divider clock + * + * @divider: the parent class + * @ops: pointer to clk_ops of parent class + * @reg: register address + * @en_id: enable bit id + * + * The DaVinci pll divider clock is a subclass of basic clk_divider with + * an additional enable bit + */ +struct clk_div { + struct clk_divider divider; + const struct clk_ops *ops; + void __iomem *reg; + u8 en_id; +}; + +static inline struct clk_div *to_clk_div(struct clk_hw *hw) +{ + struct clk_divider *divider = container_of(hw, struct clk_divider, hw); + + return container_of(divider, struct clk_div, divider); +} + +static unsigned long clk_div_recalc_rate(struct clk_hw *hw, +unsigned long parent_rate) +{ + struct clk_div *div = to_clk_div(hw); + u32 val; + + val = readl(div->reg); + if (val & BIT(div->en_id)) + return div->ops->recalc_rate(&div->divider.hw, parent_rate); + + /* pll divider bypassed, return parent rate */ + return parent_rate; +} + +static long clk_div_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct clk_div *div = to_clk_div(hw); + + return div->ops->round_rate(&div->divider.hw, rate, prate); +} + +static int clk_div_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_div *div = to_clk_div(hw); + + return div->ops->set_rate(&div->divider.hw, rate, parent_rate); +} + +static struct clk_ops clk_div_ops = { + .recalc_rate = clk_div_recalc_rate, + .round_rate = clk_div_round_rate, + .set_rate = clk_div_set_rate, +}; + +/** + * clk_register_davinci_plldiv - register function for DaVinci PLL divider clk + * + * @dev: device ptr + * @name: name of the clock + * @parent_name: name of parent clock + * @plldiv_data: ptr to pll divider data + * @lock: ptr to spinlock passed to divider clock + */ +struct clk *clk_register_davinci_plldiv(struct device *dev, + const char *name, const char *parent_name, + struct clk_plldiv_data *plldiv_data, + spinlock_t *lock) +{ + struct clk_div *div; + struct clk *clk; + struct clk_init_data init; + + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &clk_div_ops; + init.flags = plldiv_data->flags; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + div->reg = plldiv_data->reg; + div->en_id = plldiv_data->en_id; + + div->divider.reg = plldiv_data->reg; + div->divider.shift = plldiv_data->shift; + div->divider.width = plldiv_data->width; + div->divider.flags = plldiv_data->divider_flags; + div->divider.lock = lock; + div->divider.hw.init = &init; + div->ops = &clk_divider_ops; + + clk = clk_register(NULL, &div->divider.hw); + if (IS_ERR(clk)) + kfree(div); + + return clk; +} diff --git a/drivers/clk/davinci/clk-div.h b/drivers/clk/davinci/clk-div.h new file mode 100644 index 000..0e3708c --- /dev/null +++ b/drivers/clk/davinci/clk-div.h @@ -0,0 +1,42 @@ +/* + * Header file for DaVinci pll divider clk driver + * + * Copyright (C) 2006-2012 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publish
[PATCH v3 06/11] clk: davinci - add build infrastructure for DaVinci clock drivers
This updates clk Makefile and Kconfig to integrate the DaVinci specific clock drivers. Also add new Kconfig and Makefile for these drivers. Signed-off-by: Murali Karicheri --- drivers/clk/Kconfig |2 ++ drivers/clk/Makefile |1 + drivers/clk/davinci/Kconfig | 44 ++ drivers/clk/davinci/Makefile |5 + 4 files changed, 52 insertions(+) create mode 100644 drivers/clk/davinci/Kconfig create mode 100644 drivers/clk/davinci/Makefile diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 7f0b5ca..1ad2ab0 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -33,6 +33,8 @@ config COMMON_CLK_DEBUG clk_flags, clk_prepare_count, clk_enable_count & clk_notifier_count. +source "drivers/clk/davinci/Kconfig" + config COMMON_CLK_WM831X tristate "Clock driver for WM831x/2x PMICs" depends on MFD_WM831X diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 5869ea3..b127b6f 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_ARCH_SOCFPGA)+= socfpga/ obj-$(CONFIG_PLAT_SPEAR) += spear/ obj-$(CONFIG_ARCH_U300)+= clk-u300.o obj-$(CONFIG_ARCH_INTEGRATOR) += versatile/ +obj-$(CONFIG_DAVINCI_CLKS) += davinci/ # Chip specific obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o diff --git a/drivers/clk/davinci/Kconfig b/drivers/clk/davinci/Kconfig new file mode 100644 index 000..e53bbc3 --- /dev/null +++ b/drivers/clk/davinci/Kconfig @@ -0,0 +1,44 @@ +menu "TI DaVinci Clock drivers" + depends on COMMON_CLK + +config CLK_DAVINCI_PSC + bool "TI DaVici PSC clock driver" + default n + ---help--- + Selects clock driver for DaVinci PSC clocks. This clock + hardware is found on TI DaVinci SoCs and other SoCs that + uses this hardware IP. This hardware has a local power + sleep control module that gate the clock to the IP. + +config CLK_DAVINCI_PLL + bool "DaVici main PLL clock" + ---help--- + Selects clock driver for DaVinci main PLL. This clock + hardware is found on TI DaVinci SoCs. This typically has + a multiplier, a pre divider and post driver. Some of the + SoCs has the the dividers fixed, and others have it + programmable + +config CLK_DAVINCI_PLLDIV + bool "DaVici PLL divider clock" + ---help--- + Selects clock driver for DaVinci PLL divider. This clock + hardware is found on TI DaVinci SoCs. This typically has + a divider and an enable bit to bypass or enable the + divider. + +config DAVINCI_CLKS + bool "TI DaVinci common clocks" + default n + select CLK_DAVINCI_PSC + select CLK_DAVINCI_PLLDIV + ---help--- + Selects common clock drivers for DaVinci. These clocks + are re-used across many TI SoCs that are based on DaVinci and + Keystone (c6x) families. This config option is used to select + the common clock driver for DaVinci based SoCs. SoCs specific + Kconfig option needs to select the driver for clocks specific + to the SoC. + +endmenu + diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile new file mode 100644 index 000..0e13986 --- /dev/null +++ b/drivers/clk/davinci/Makefile @@ -0,0 +1,5 @@ +obj-$(CONFIG_CLK_DAVINCI_PLL) += clk-pll.o +obj-$(CONFIG_CLK_DAVINCI_PLLDIV) += clk-div.o +obj-$(CONFIG_CLK_DAVINCI_PSC) += clk-psc.o +obj-$(CONFIG_DAVINCI_CLKS) += clock.o +obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x-clock.o -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v3 10/11] ARM: davinci - migrate to common clock
Currently migrate only DM644x as this is being reviewed. Once all platforms are migrated, the Makefile will be cleaned up to remove obsoleted files clock.o and psc.o Signed-off-by: Murali Karicheri --- arch/arm/Kconfig |1 + arch/arm/mach-davinci/Kconfig |2 ++ arch/arm/mach-davinci/Makefile | 11 ++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5f9ae5..4611987 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -967,6 +967,7 @@ config ARCH_DAVINCI select ARCH_REQUIRE_GPIOLIB select ZONE_DMA select HAVE_IDE + select COMMON_CLK select CLKDEV_LOOKUP select GENERIC_ALLOCATOR select GENERIC_IRQ_CHIP diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index ab99c3c..ab414b4 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -19,6 +19,8 @@ config ARCH_DAVINCI_DM644x bool "DaVinci 644x based system" select AINTC select ARCH_DAVINCI_DMx + select DAVINCI_CLKS + select CLK_DAVINCI_PLL config ARCH_DAVINCI_DM355 bool "DaVinci 355 based system" diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 2227eff..5a5b3dc 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -4,18 +4,25 @@ # # Common objects +ifndef CONFIG_COMMON_CLK obj-y := time.o clock.o serial.o psc.o \ dma.o usb.o common.o sram.o aemif.o +else +obj-y := time.o serial.o \ + dma.o usb.o common.o sram.o aemif.o +endif obj-$(CONFIG_DAVINCI_MUX) += mux.o # Chip specific obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o devices.o +ifndef CONFIG_COMMON_CLK obj-$(CONFIG_ARCH_DAVINCI_DM355)+= dm355.o devices.o -obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o obj-$(CONFIG_ARCH_DAVINCI_DM365) += dm365.o devices.o +obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o obj-$(CONFIG_ARCH_DAVINCI_DA830)+= da830.o devices-da8xx.o obj-$(CONFIG_ARCH_DAVINCI_DA850)+= da850.o devices-da8xx.o +endif obj-$(CONFIG_ARCH_DAVINCI_TNETV107X)+= tnetv107x.o devices-tnetv107x.o obj-$(CONFIG_AINTC)+= irq.o @@ -23,6 +30,7 @@ obj-$(CONFIG_CP_INTC) += cp_intc.o # Board specific obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o +ifndef CONFIG_COMMON_CLK obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o obj-$(CONFIG_MACH_NEUROS_OSD2) += board-neuros-osd2.o obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-dm355-evm.o @@ -31,6 +39,7 @@ obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o cdce949.o obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o +endif obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o obj-$(CONFIG_MACH_MITYOMAPL138)+= board-mityomapl138.o obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v3 09/11] ARM: davinci - dm644x: update SoC code to remove the clock data
As part of the migration, the clock data is now moved to the driver/clk/ davinci/dm644x-clock.c. Currently the clock data is placed under ifndef CONFIG_COMMON_CLK directive and will be removed in a subsequent patch. Signed-off-by: Murali Karicheri --- arch/arm/mach-davinci/davinci.h |3 +++ arch/arm/mach-davinci/dm644x.c | 28 ++-- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h index 8661b20..ae9b1af 100644 --- a/arch/arm/mach-davinci/davinci.h +++ b/arch/arm/mach-davinci/davinci.h @@ -100,4 +100,7 @@ int __init dm646x_init_edma(struct edma_rsv_info *rsv); void dm646x_video_init(void); void dm646x_setup_vpif(struct vpif_display_config *, struct vpif_capture_config *); + +extern void __init dm644x_clk_init(void); + #endif /*__DAVINCI_H */ diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 0755d46..bf64b75 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -9,7 +9,9 @@ * or implied. */ #include +#ifndef CONFIG_COMMON_CLK #include +#endif #include #include @@ -18,7 +20,9 @@ #include #include #include +#ifndef CONFIG_COMMON_CLK #include +#endif #include #include #include @@ -26,14 +30,11 @@ #include #include "davinci.h" -#include "clock.h" #include "mux.h" #include "asp.h" - -/* - * Device specific clocks - */ -#define DM644X_REF_FREQ2700 +#ifndef CONFIG_COMMON_CLK +#include "clock.h" +#endif #define DM644X_EMAC_BASE 0x01c8 #define DM644X_EMAC_MDIO_BASE (DM644X_EMAC_BASE + 0x4000) @@ -42,6 +43,12 @@ #define DM644X_EMAC_CNTRL_RAM_OFFSET 0x2000 #define DM644X_EMAC_CNTRL_RAM_SIZE 0x2000 +#ifndef CONFIG_COMMON_CLK +/* + * Device specific clocks + */ +#define DM644X_REF_FREQ2700 + static struct pll_data pll1_data = { .num = 1, .phys_base = DAVINCI_PLL1_BASE, @@ -324,6 +331,7 @@ static struct clk_lookup dm644x_clks[] = { CLK("watchdog", NULL, &timer2_clk), CLK(NULL, NULL, NULL), }; +#endif static struct emac_platform_data dm644x_emac_pdata = { .ctrl_reg_offset= DM644X_EMAC_CNTRL_OFFSET, @@ -821,7 +829,9 @@ static struct davinci_id dm644x_ids[] = { }, }; +#ifndef CONFIG_COMMON_CLK static u32 dm644x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE }; +#endif /* * T0_BOT: Timer 0, bottom: clockevent source for hrtimers @@ -879,9 +889,13 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .jtag_id_reg= 0x01c40028, .ids= dm644x_ids, .ids_num= ARRAY_SIZE(dm644x_ids), +#ifdef CONFIG_COMMON_CLK + .clk_init = dm644x_clk_init, +#else .cpu_clks = dm644x_clks, .psc_bases = dm644x_psc_bases, .psc_bases_num = ARRAY_SIZE(dm644x_psc_bases), +#endif .pinmux_base= DAVINCI_SYSTEM_MODULE_BASE, .pinmux_pins= dm644x_pins, .pinmux_pins_num= ARRAY_SIZE(dm644x_pins), @@ -923,11 +937,13 @@ int __init dm644x_init_video(struct vpfe_config *vpfe_cfg, dm644x_vpfe_dev.dev.platform_data = vpfe_cfg; platform_device_register(&dm644x_ccdc_dev); platform_device_register(&dm644x_vpfe_dev); +#ifndef CONFIG_COMMON_CLK /* Add ccdc clock aliases */ clk_add_alias("master", dm644x_ccdc_dev.name, "vpss_master", NULL); clk_add_alias("slave", dm644x_ccdc_dev.name, "vpss_slave", NULL); +#endif } if (vpbe_cfg) { -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v3 11/11] ARM: davinci - common clock migration: clean up the old code
This patch clean up the obsoleted code after migrating to the common clock framwork based code. Currently only dm644x is supported as part of davinci_all_defconfig and other davinci variants may not be buildable. But once all SoCs and machines are migrated, some of these changes will be removed. However this shows how the migration will happen. Signed-off-by: Murali Karicheri --- arch/arm/mach-davinci/Makefile | 22 - arch/arm/mach-davinci/clock.c | 669 --- arch/arm/mach-davinci/clock.h | 135 -- arch/arm/mach-davinci/common.c | 16 - arch/arm/mach-davinci/cpufreq.c |2 - arch/arm/mach-davinci/devices.c |3 - arch/arm/mach-davinci/dm644x.c | 316 - arch/arm/mach-davinci/include/mach/clock.h | 21 - arch/arm/mach-davinci/include/mach/common.h | 12 - arch/arm/mach-davinci/include/mach/psc.h| 213 - arch/arm/mach-davinci/include/mach/time.h |2 - arch/arm/mach-davinci/pm.c |5 - arch/arm/mach-davinci/psc.c | 112 - arch/arm/mach-davinci/sleep.S |5 - arch/arm/mach-davinci/time.c|7 +- 15 files changed, 1 insertion(+), 1539 deletions(-) delete mode 100644 arch/arm/mach-davinci/clock.c delete mode 100644 arch/arm/mach-davinci/clock.h delete mode 100644 arch/arm/mach-davinci/include/mach/clock.h delete mode 100644 arch/arm/mach-davinci/psc.c diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 5a5b3dc..e0f7b6c 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -4,25 +4,13 @@ # # Common objects -ifndef CONFIG_COMMON_CLK -obj-y := time.o clock.o serial.o psc.o \ - dma.o usb.o common.o sram.o aemif.o -else obj-y := time.o serial.o \ dma.o usb.o common.o sram.o aemif.o -endif obj-$(CONFIG_DAVINCI_MUX) += mux.o # Chip specific obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o devices.o -ifndef CONFIG_COMMON_CLK -obj-$(CONFIG_ARCH_DAVINCI_DM355)+= dm355.o devices.o -obj-$(CONFIG_ARCH_DAVINCI_DM365) += dm365.o devices.o -obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o -obj-$(CONFIG_ARCH_DAVINCI_DA830)+= da830.o devices-da8xx.o -obj-$(CONFIG_ARCH_DAVINCI_DA850)+= da850.o devices-da8xx.o -endif obj-$(CONFIG_ARCH_DAVINCI_TNETV107X)+= tnetv107x.o devices-tnetv107x.o obj-$(CONFIG_AINTC)+= irq.o @@ -30,16 +18,6 @@ obj-$(CONFIG_CP_INTC)+= cp_intc.o # Board specific obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o -ifndef CONFIG_COMMON_CLK -obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o -obj-$(CONFIG_MACH_NEUROS_OSD2) += board-neuros-osd2.o -obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-dm355-evm.o -obj-$(CONFIG_MACH_DM355_LEOPARD) += board-dm355-leopard.o -obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o cdce949.o -obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o -obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o -obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o -endif obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o obj-$(CONFIG_MACH_MITYOMAPL138)+= board-mityomapl138.o obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c deleted file mode 100644 index 34668ea..000 --- a/arch/arm/mach-davinci/clock.c +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Clock and PLL control for DaVinci devices - * - * Copyright (C) 2006-2007 Texas Instruments. - * Copyright (C) 2008-2009 Deep Root Systems, LLC - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include "clock.h" - -static LIST_HEAD(clocks); -static DEFINE_MUTEX(clocks_mutex); -static DEFINE_SPINLOCK(clockfw_lock); - -static void __clk_enable(struct clk *clk) -{ - if (clk->parent) - __clk_enable(clk->parent); - if (clk->usecount++ == 0 && (clk->flags & CLK_PSC)) - davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc, - true, clk->flags); -} - -static void __clk_disable(struct clk *clk) -{ - if (WARN_ON(clk->usecount == 0)) - return; - if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) && - (clk->flags &a
[PATCH v3 02/11] clk: davinci - add PSC clock driver
This is the driver for the Power Sleep Controller (PSC) hardware found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed code from arch/arm/mach-davinci/psc.c and implemented the driver as per common clock provider API. The PSC module is responsible for enabling/disabling the Power Domain and Clock domain for different IPs present in the SoC. The driver is configured through the clock data passed to the driver through struct clk_psc_data. Signed-off-by: Murali Karicheri --- drivers/clk/davinci/clk-psc.c | 207 + drivers/clk/davinci/clk-psc.h | 46 + 2 files changed, 253 insertions(+) create mode 100644 drivers/clk/davinci/clk-psc.c create mode 100644 drivers/clk/davinci/clk-psc.h diff --git a/drivers/clk/davinci/clk-psc.c b/drivers/clk/davinci/clk-psc.c new file mode 100644 index 000..40d5f06 --- /dev/null +++ b/drivers/clk/davinci/clk-psc.c @@ -0,0 +1,207 @@ +/* + * PSC clk driver for DaVinci devices + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include + +#include "clk-psc.h" + +/* PSC register offsets */ +#define EPCPR 0x070 +#define PTCMD 0x120 +#define PTSTAT 0x128 +#define PDSTAT 0x200 +#define PDCTL 0x300 +#define MDSTAT 0x800 +#define MDCTL 0xA00 + +/* PSC module states */ +#define PSC_STATE_SWRSTDISABLE 0 +#define PSC_STATE_SYNCRST 1 +#define PSC_STATE_DISABLE 2 +#define PSC_STATE_ENABLE 3 + +#define MDSTAT_STATE_MASK 0x3f +#define PDSTAT_STATE_MASK 0x1f +#define MDCTL_FORCEBIT(31) +#define PDCTL_NEXT BIT(0) +#define PDCTL_EPCGOOD BIT(8) + +/** + * struct clk_psc - DaVinci PSC clock driver data + * + * @hw: clk_hw for the psc + * @psc_data: Driver specific data + */ +struct clk_psc { + struct clk_hw hw; + struct clk_psc_data *psc_data; + spinlock_t *lock; +}; + +#define to_clk_psc(_hw) container_of(_hw, struct clk_psc, hw) + +/** + * clk_psc_config() - configure psc hardware + * + * @base: io mapped base address of the psc + * @domain: Power Domain id of the module + * @id: lpsc id + * @enable: 1 - enable psc, 0 - disable psc + * @flags: psc driver specific flags + */ +static void clk_psc_config(void __iomem *base, unsigned int domain, + unsigned int id, bool enable, u32 flags) +{ + u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl; + u32 next_state = PSC_STATE_ENABLE; + void __iomem *psc_base = base; + + if (!enable) { + if (flags & CLK_PSC_SWRSTDISABLE) + next_state = PSC_STATE_SWRSTDISABLE; + else + next_state = PSC_STATE_DISABLE; + } + + mdctl = readl(psc_base + MDCTL + 4 * id); + mdctl &= ~MDSTAT_STATE_MASK; + mdctl |= next_state; + if (flags & CLK_PSC_FORCE) + mdctl |= MDCTL_FORCE; + writel(mdctl, psc_base + MDCTL + 4 * id); + + pdstat = readl(psc_base + PDSTAT + 4 * domain); + if ((pdstat & PDSTAT_STATE_MASK) == 0) { + pdctl = readl(psc_base + PDCTL + 4 * domain); + pdctl |= PDCTL_NEXT; + writel(pdctl, psc_base + PDCTL + 4 * domain); + + ptcmd = 1 << domain; + writel(ptcmd, psc_base + PTCMD); + + if (flags & CLK_PSC_HAS_EXT_POWER_CNTL) { + do { + epcpr = readl(psc_base + EPCPR); + } while epcpr >> domain) & 1) == 0)); + } + + pdctl = readl(psc_base + PDCTL + 4 * domain); + pdctl |= 0x100; + writel(pdctl, psc_base + PDCTL + 4 * domain); + + pdctl = readl(psc_base + PDCTL + 4 * domain); + pdctl |= PDCTL_EPCGOOD; + writel(pdctl, psc_base + PDCTL + 4 * domain); + } else { + ptcmd = 1 << domain; + writel(ptcmd, psc_base + PTCMD); + } + + do { + ptstat = readl(psc_base + PTSTAT); + } while (!(((ptstat >> domain) & 1) == 0)); + + do { + mdstat = readl(psc_base + MDSTAT + 4 * id); + } while (!((mdstat & MDSTAT_STATE_MASK) == next_state)); +} + +/** + * clk_psc_is_enabled() - Is psc clock enabled + * + * @hw: clk hw for the psc + */ +static int cl
[PATCH v3 03/11] clk: davinci - common clk utilities to init clk driver
This is the common clk driver initialization functions for DaVinci SoCs and other SoCs that uses similar hardware architecture. clock.h also defines struct types for clock definitions in a SoC and clock data type for configuring clk-mux. The initialization functions are used by clock initialization code in a specific platform/SoC. Signed-off-by: Murali Karicheri --- drivers/clk/davinci/clock.c | 112 +++ drivers/clk/davinci/clock.h | 80 +++ 2 files changed, 192 insertions(+) create mode 100644 drivers/clk/davinci/clock.c create mode 100644 drivers/clk/davinci/clock.h diff --git a/drivers/clk/davinci/clock.c b/drivers/clk/davinci/clock.c new file mode 100644 index 000..ad02149 --- /dev/null +++ b/drivers/clk/davinci/clock.c @@ -0,0 +1,112 @@ +/* + * clock.c - davinci clock initialization functions for various clocks + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include + +#include "clk-pll.h" +#include "clk-psc.h" +#include "clk-div.h" +#include "clock.h" + +static DEFINE_SPINLOCK(_lock); + +#ifdef CONFIG_CLK_DAVINCI_PLL +struct clk *davinci_pll_clk(const char *name, const char *parent, + u32 phys_pllm, u32 phys_prediv, u32 phys_postdiv, + struct clk_pll_data *pll_data) +{ + struct clk *clkp = NULL; + + pll_data->reg_pllm = ioremap(phys_pllm, 4); + if (WARN_ON(!pll_data->reg_pllm)) + return clkp; + + pll_data->reg_prediv = ioremap(phys_prediv, 4); + if (WARN_ON(!pll_data->reg_prediv)) + goto error1; + + pll_data->reg_postdiv = ioremap(phys_postdiv, 4); + if (WARN_ON(!pll_data->reg_postdiv)) + goto error2; + + return clk_register_davinci_pll(NULL, name, parent, pll_data); +error1: + iounmap(pll_data->reg_pllm); +error2: + iounmap(pll_data->reg_prediv); + return clkp; +} +#else +struct clk *davinci_pll_clk(const char *name, const char *parent, + u32 phys_pllm, u32 phys_prediv, u32 phys_postdiv, + struct clk_pll_data *pll_data) +{ + return NULL; +} +#endif + +struct clk *davinci_mux_clk(const char *name, u8 num_parents, + const char **parents, struct clk_mux_data *data) + +{ + void __iomem *reg; + + reg = ioremap(data->phys_reg, 4); + if (WARN_ON(!reg)) + return NULL; + + return clk_register_mux(NULL, name, parents, num_parents, data->flags, + reg, data->shift, data->width, data->mux_flags, +&_lock); +} + +struct clk *davinci_plldiv_clk(const char *name, const char *parent, + struct clk_plldiv_data *data) +{ + /* +* This is a PLL divider clock with divider specified by +* div_reg in pll_div_data. +*/ + data->reg = ioremap(data->phys_div_reg, 4); + if (WARN_ON(!data->reg)) + return NULL; + + return clk_register_davinci_plldiv(NULL, name, parent, data, &_lock); +} + +inline struct clk *davinci_fixed_factor_clk(const char *name, + const char *parent, unsigned long flags, + unsigned int mult, unsigned int div) +{ + if (WARN_ON(!mult)) + return NULL; + + if (WARN_ON(!div)) + return NULL; + + return clk_register_fixed_factor(NULL, name, parent, flags, mult, div); +} + +inline struct clk *davinci_fixed_ref_clk(const char *name, + unsigned long rate) +{ + return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate); +} + +inline struct clk *davinci_psc_clk(const char *name, const char *parent, +struct clk_psc_data *data) +{ + return clk_register_davinci_psc(NULL, name, parent, data); +} diff --git a/drivers/clk/davinci/clock.h b/drivers/clk/davinci/clock.h new file mode 100644 index 000..73204b8 --- /dev/null +++ b/drivers/clk/davinci/clock.h @@ -0,0 +1,80 @@ +/* + * TI DaVinci Clock definitions - Contains Macros and Types used for + * defining various clocks on a DaVinci SoC + * + * Copyright (C) 2012 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; with
[PATCH v3 08/11] ARM: davinci - migrating to use common clock init code
A clk_init function pointer is added to davinci_soc_info to allow SoC code to specify a clock init function for the SoC. Also cpu_clks, psc_bases and psc_bases_num are being obsoleted as part of the migration. clk_init() is now called from davinci_timer_init() as the davinci_common_init() is too early to call this function. Signed-off-by: Murali Karicheri --- arch/arm/mach-davinci/common.c |6 ++ arch/arm/mach-davinci/include/mach/common.h |4 arch/arm/mach-davinci/time.c|7 +++ 3 files changed, 17 insertions(+) diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index 64b0f65..039494e 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -20,7 +20,9 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#endif struct davinci_soc_info davinci_soc_info; EXPORT_SYMBOL(davinci_soc_info); @@ -105,12 +107,14 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) if (ret < 0) goto err; +#ifndef CONFIG_COMMON_CLK if (davinci_soc_info.cpu_clks) { ret = davinci_clk_init(davinci_soc_info.cpu_clks); if (ret != 0) goto err; } +#endif return; @@ -122,5 +126,7 @@ void __init davinci_init_late(void) { davinci_cpufreq_init(); davinci_pm_init(); +#ifndef CONFIG_COMMON_CLK davinci_clk_disable_unused(); +#endif } diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index bdc4aa8..040db17 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -54,9 +54,13 @@ struct davinci_soc_info { u32 jtag_id_reg; struct davinci_id *ids; unsigned long ids_num; +#ifdef CONFIG_COMMON_CLK + void(*clk_init)(void); +#else struct clk_lookup *cpu_clks; u32 *psc_bases; unsigned long psc_bases_num; +#endif u32 pinmux_base; const struct mux_config *pinmux_pins; unsigned long pinmux_pins_num; diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index 9847938..01467d8 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -27,7 +27,9 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#endif static struct clock_event_device clockevent_davinci; static unsigned int davinci_clock_tick_rate; @@ -347,6 +349,11 @@ static void __init davinci_timer_init(void) "%s: can't register clocksource!\n"; int i; +#ifdef CONFIG_COMMON_CLK + /* invoke clk init function specific to a SoC */ + if (davinci_soc_info.clk_init) + davinci_soc_info.clk_init(); +#endif clockevent_id = soc_info->timer_info->clockevent_id; clocksource_id = soc_info->timer_info->clocksource_id; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v3 07/11] ARM: davinci - restructure header files for common clock migration
pll.h is added to migrate some of the PLL controller defines for sleep.S. psc.h is modified to keep only PSC modules definitions needed by sleep.S after migrating to common clock. The definitions under ifdef CONFIG_COMMON_CLK will be removed in a subsequent patch. davinci_watchdog_reset prototype is moved to time.h as clock.h is being obsoleted. sleep.S and pm.c is modified to include the new header file replacements. Signed-off-by: Murali Karicheri --- arch/arm/mach-davinci/devices.c |2 ++ arch/arm/mach-davinci/include/mach/pll.h | 46 + arch/arm/mach-davinci/include/mach/psc.h |4 +++ arch/arm/mach-davinci/include/mach/time.h |4 ++- arch/arm/mach-davinci/pm.c|4 +++ arch/arm/mach-davinci/sleep.S |4 +++ 6 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-davinci/include/mach/pll.h diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index d2f96662..96ee175 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -24,7 +24,9 @@ #include #include "davinci.h" +#ifndef CONFIG_COMMON_CLK #include "clock.h" +#endif #define DAVINCI_I2C_BASE0x01C21000 #define DAVINCI_ATA_BASE0x01C66000 diff --git a/arch/arm/mach-davinci/include/mach/pll.h b/arch/arm/mach-davinci/include/mach/pll.h new file mode 100644 index 000..fa51bc4 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/pll.h @@ -0,0 +1,46 @@ +/* + * TI DaVinci PLL definitions + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __ASM_ARCH_PLL_H +#define __ASM_ARCH_PLL_H + +/* PLL/Reset register offsets */ +#define PLLCTL 0x100 +#define PLLCTL_PLLENBIT(0) +#define PLLCTL_PLLPWRDNBIT(1) +#define PLLCTL_PLLRST BIT(3) +#define PLLCTL_PLLDIS BIT(4) +#define PLLCTL_PLLENSRCBIT(5) +#define PLLCTL_CLKMODE BIT(8) +#define PLLDIV_EN BIT(15) +#define PLLDIV1 0x118 +/* + * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN + * cycles to ensure that the PLLC has switched to bypass mode. Delay of 1us + * ensures we are good for all > 4MHz OSCIN/CLKIN inputs. Typically the input + * is ~25MHz. Units are micro seconds. + */ +#define PLL_BYPASS_TIME1 +/* From OMAP-L138 datasheet table 6-4. Units are micro seconds */ +#define PLL_RESET_TIME 1 +/* + * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4 + * Units are micro seconds. + */ +#define PLL_LOCK_TIME 20 +#define PLLSTAT_GOSTAT BIT(0) +#define PLLCMD_GOSET BIT(0) + +#endif /* __ASM_ARCH_PLL_H */ diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index 405318e..eb464d3 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h @@ -27,6 +27,7 @@ #ifndef __ASM_ARCH_PSC_H #define __ASM_ARCH_PSC_H +#ifndef CONFIG_COMMON_CLK #defineDAVINCI_PWR_SLEEP_CNTRL_BASE0x01C41000 /* Power and Sleep Controller (PSC) Domains */ @@ -227,6 +228,7 @@ #define TNETV107X_LPSC_DDR2_EMIF1_VRST 42 #define TNETV107X_LPSC_DDR2_EMIF2_VCTL_RST 43 #define TNETV107X_LPSC_MAX 44 +#endif /* PSC register offsets */ #define EPCPR 0x070 @@ -251,9 +253,11 @@ #ifndef __ASSEMBLER__ +#ifndef CONFIG_COMMON_CLK extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id); extern void davinci_psc_config(unsigned int domain, unsigned int ctlr, unsigned int id, bool enable, u32 flags); +#endif #endif diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h index 1c971d8..7faa530 100644 --- a/arch/arm/mach-davinci/include/mach/time.h +++ b/arch/arm/mach-davinci/include/mach/time.h @@ -31,5 +31,7 @@ enum { #define ID_TO_TIMER(id)(IS_TIMER1(id) != 0) extern struct davinci_timer_instance davinci_timer_instance[]; - +#ifdef CONFIG_COMMON_CLK +extern void davinci_watchdog_reset(struct platform_device *); +#endif #endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */ diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c index eb8360b..8802fdc 100644 --- a/arch/arm/mach-davinci/pm.c +++ b/arch/arm/mach-davinci/pm.c @@ -23,7 +23,11 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include "clock.h
[PATCH v3 05/11] clk: davinci - add dm644x clock initialization
This patch adds dm644x clock initialization code that consists of clocks data for various clocks and clock register callouts to various clock drivers. It uses following clk drivers for this 1. clk-fixed-rate - for ref clock 2. clk-mux - for mux at the input and output of main pll 3. davinci specific clk-pll for main pll clock 4. davinci specific clk-div for pll divider clock 5. clk-fixed-factor for fixed factor clock such as auxclk 6. davinci specific clk-psc for psc clocks This patch also moves all of the PLL and PSC register definitions from clock.h and psc.h under davinci to the clk/davinci folder so that various soc specific clock initialization code can share these definitions. Signed-off-by: Murali Karicheri --- drivers/clk/davinci/dm644x-clock.c | 304 drivers/clk/davinci/pll.h | 83 ++ drivers/clk/davinci/psc.h | 215 + 3 files changed, 602 insertions(+) create mode 100644 drivers/clk/davinci/dm644x-clock.c create mode 100644 drivers/clk/davinci/pll.h create mode 100644 drivers/clk/davinci/psc.h diff --git a/drivers/clk/davinci/dm644x-clock.c b/drivers/clk/davinci/dm644x-clock.c new file mode 100644 index 000..8f74f72 --- /dev/null +++ b/drivers/clk/davinci/dm644x-clock.c @@ -0,0 +1,304 @@ +/* + * DM644x clock initialization + * + * Copyright (C) 2012 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include + +#include "clk-pll.h" +#include "clk-psc.h" +#include "clk-div.h" +#include "clock.h" +#include "pll.h" +#include "psc.h" + +#define DM644X_CLKIN_FREQ 2700 +#define DM644X_OSCIN_FREQ 2700 + +/* all clocks available in DM644x SoCs */ +enum dm644x_clk { + clkin, oscin, ref_clk_mux, pll1, pll1_plldiv_clk_mux, auxclk, + clk_pll1_sysclk1, clk_pll1_sysclk2, clk_pll1_sysclk3, clk_pll1_sysclk4, + clk_pll1_sysclk5, clk_pll1_sysclkbp, pll2, pll2_plldiv_clk_mux, + clk_pll2_sysclk1, clk_pll2_sysclk2, clk_pll2_sysclkbp, dsp, arm, vicp, + vpss_master, vpss_slave, uart0, uart1, uart2, emac, i2c, ide, asp, + mmcsd, spi, gpio, usb, vlynq, aemif, pwm0, pwm1, pwm2, timer0, timer1, + timer2, clk_max +}; + +static struct clk *clks[clk_max]; + +static u32 dm644x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE }; + +static const char *ref_clk_mux_parents[] = {"clkin", "oscin"}; + +static struct clk_mux_data ref_clk_mux_data = { + .shift = PLLCTL_CLKMODE_SHIFT, + .width = PLLCTL_CLKMODE_WIDTH, + .phys_reg = DAVINCI_PLL1_BASE + PLLCTL, +}; + +static const char *pll1_plldiv_clk_mux_parents[] = { + "ref_clk_mux", "pll1"}; + +static struct clk_pll_data pll1_data = { + .pllm_mask = PLLM_PLLM_MASK, + .prediv_mask= PLLDIV_RATIO_MASK, + .postdiv_mask = PLLDIV_RATIO_MASK, + .num= 1, +}; + +static struct clk_mux_data pll1_plldiv_clk_mux_data = { + .shift = PLLCTL_PLLEN_SHIFT, + .width = PLLCTL_PLLEN_WIDTH, + .phys_reg = DAVINCI_PLL1_BASE + PLLCTL, +}; + +#define define_pll1_div_clk(__name, __parent_name, __div) \ + static struct clk_plldiv_data pll1_div_data##__div = { \ + .phys_div_reg = DAVINCI_PLL1_BASE + PLLDIV##__div,\ + .width = 5,\ + .en_id = 15, \ + }; \ + \ + static struct davinci_clk __name = {\ + .name = #__name, \ + .parent = #__parent_name, \ + .data = &pll1_div_data##__div, \ + }; + +define_pll1_div_clk(pll1_sysclk1, pll1_plldiv_clk_mux, 1); +define_pll1_div_clk(pll1_sysclk2, pll1_plldiv_clk_mux, 2); +define_pll1_div_clk(pll1_sysclk3, pll1_plldiv_clk_mux, 3); +define_pll1_div_clk(pll1_sysclk4, pll1_plldiv_clk_mux, 4); +define_pll1_div_clk(pll1_sysclk5, pll1_plldiv_clk_mux, 5); + +static struct clk_plldiv_data pll1_sysclkbp_data = { + .phys_div_reg = DAVINCI_PLL1_BASE + BPDIV, + .width = 5, + .en_id = 15, +}; + +static struct davinci_clk pll1_sysclkbp = { + .name = "pll1_sysclkbp", + .parent = "ref_clk_mux", + .data = &pll1_sysclkbp_data, +}; + +static struct davinci_clk *pll1_plldiv_clocks[] = { + &pll1_sysc
Re: [RESEND-PATCH] media:davinci: clk - {prepare/unprepare} for common clk
On 10/25/2012 09:12 AM, Prabhakar Lad wrote: Hi Murali, Thanks for the patch. I'll queue this patch for 3.8. Please check with Sekhar as well. This is a preparation patch for common clk framework support. ALso fixes some bugs on the existing code. As the clk patches are dependent on these patches, I would suggest you queue this against 3.7 rcx. Murali On Mon, Oct 22, 2012 at 9:06 PM, Murali Karicheri wrote: As a first step towards migrating davinci platforms to use common clock framework, replace all instances of clk_enable() with clk_prepare_enable() and clk_disable() with clk_disable_unprepare(). Also fixes some issues related to clk clean up in the driver Signed-off-by: Murali Karicheri Acked-by: Lad, Prabhakar Tested-by: Lad, Prabhakar Regards, --Prabhakar --- rebased to v3.7-rc1 drivers/media/platform/davinci/dm355_ccdc.c |8 ++-- drivers/media/platform/davinci/dm644x_ccdc.c | 16 ++-- drivers/media/platform/davinci/isif.c|5 - drivers/media/platform/davinci/vpbe.c| 10 +++--- drivers/media/platform/davinci/vpif.c|8 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c index ce0e413..030950d 100644 --- a/drivers/media/platform/davinci/dm355_ccdc.c +++ b/drivers/media/platform/davinci/dm355_ccdc.c @@ -1003,7 +1003,7 @@ static int __devinit dm355_ccdc_probe(struct platform_device *pdev) status = PTR_ERR(ccdc_cfg.mclk); goto fail_nomap; } - if (clk_enable(ccdc_cfg.mclk)) { + if (clk_prepare_enable(ccdc_cfg.mclk)) { status = -ENODEV; goto fail_mclk; } @@ -1014,7 +1014,7 @@ static int __devinit dm355_ccdc_probe(struct platform_device *pdev) status = PTR_ERR(ccdc_cfg.sclk); goto fail_mclk; } - if (clk_enable(ccdc_cfg.sclk)) { + if (clk_prepare_enable(ccdc_cfg.sclk)) { status = -ENODEV; goto fail_sclk; } @@ -1034,8 +1034,10 @@ static int __devinit dm355_ccdc_probe(struct platform_device *pdev) printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name); return 0; fail_sclk: + clk_disable_unprepare(ccdc_cfg.sclk); clk_put(ccdc_cfg.sclk); fail_mclk: + clk_disable_unprepare(ccdc_cfg.mclk); clk_put(ccdc_cfg.mclk); fail_nomap: iounmap(ccdc_cfg.base_addr); @@ -1050,6 +1052,8 @@ static int dm355_ccdc_remove(struct platform_device *pdev) { struct resource *res; + clk_disable_unprepare(ccdc_cfg.sclk); + clk_disable_unprepare(ccdc_cfg.mclk); clk_put(ccdc_cfg.mclk); clk_put(ccdc_cfg.sclk); iounmap(ccdc_cfg.base_addr); diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c index ee7942b..0215ab6 100644 --- a/drivers/media/platform/davinci/dm644x_ccdc.c +++ b/drivers/media/platform/davinci/dm644x_ccdc.c @@ -994,7 +994,7 @@ static int __devinit dm644x_ccdc_probe(struct platform_device *pdev) status = PTR_ERR(ccdc_cfg.mclk); goto fail_nomap; } - if (clk_enable(ccdc_cfg.mclk)) { + if (clk_prepare_enable(ccdc_cfg.mclk)) { status = -ENODEV; goto fail_mclk; } @@ -1005,7 +1005,7 @@ static int __devinit dm644x_ccdc_probe(struct platform_device *pdev) status = PTR_ERR(ccdc_cfg.sclk); goto fail_mclk; } - if (clk_enable(ccdc_cfg.sclk)) { + if (clk_prepare_enable(ccdc_cfg.sclk)) { status = -ENODEV; goto fail_sclk; } @@ -1013,8 +1013,10 @@ static int __devinit dm644x_ccdc_probe(struct platform_device *pdev) printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name); return 0; fail_sclk: + clk_disable_unprepare(ccdc_cfg.sclk); clk_put(ccdc_cfg.sclk); fail_mclk: + clk_disable_unprepare(ccdc_cfg.mclk); clk_put(ccdc_cfg.mclk); fail_nomap: iounmap(ccdc_cfg.base_addr); @@ -1029,6 +1031,8 @@ static int dm644x_ccdc_remove(struct platform_device *pdev) { struct resource *res; + clk_disable_unprepare(ccdc_cfg.mclk); + clk_disable_unprepare(ccdc_cfg.sclk); clk_put(ccdc_cfg.mclk); clk_put(ccdc_cfg.sclk); iounmap(ccdc_cfg.base_addr); @@ -1046,8 +1050,8 @@ static int dm644x_ccdc_suspend(struct device *dev) /* Disable CCDC */ ccdc_enable(0); /* Disable both master and slave clock */ - clk_disable(ccdc_cfg.mclk); - clk_disable(ccdc_cfg.sclk); + clk_disable_unprepare(ccdc_cfg.mclk); + clk_disable_unprepare(ccdc_cfg.sclk); return 0; } @@ -1055,8 +1059,8 @@ static int d
Re: [PATCH v3 04/11] clk: davinci - add pll divider clock driver
On 10/28/2012 03:26 PM, Linus Walleij wrote: On Thu, Oct 25, 2012 at 6:11 PM, Murali Karicheri wrote: pll dividers are present in the pll controller of DaVinci and Other SoCs that re-uses the same hardware IP. This has a enable bit for bypass the divider or enable the driver. This is a sub class of the clk-divider clock checks the enable bit to calculare the rate and invoke the recalculate() function of the clk-divider if enabled. Signed-off-by: Murali Karicheri Looking good, Acked-by: Linus Walleij Yours, Linus Walleij Linus, Thanks. I will add your Acked-by in the next version. Murali ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v3 03/11] clk: davinci - common clk utilities to init clk driver
On 10/28/2012 03:25 PM, Linus Walleij wrote: On Thu, Oct 25, 2012 at 6:11 PM, Murali Karicheri wrote: This is the common clk driver initialization functions for DaVinci SoCs and other SoCs that uses similar hardware architecture. clock.h also defines struct types for clock definitions in a SoC and clock data type for configuring clk-mux. The initialization functions are used by clock initialization code in a specific platform/SoC. Signed-off-by: Murali Karicheri This is looking good. Acked-by: Linus Walleij Yours, Linus Walleij Linus, Thanks. I will add your Acked-by in the next revision of the patch. Murali ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v3 01/11] clk: davinci - add main PLL clock driver
On 10/28/2012 03:18 PM, Linus Walleij wrote: On Thu, Oct 25, 2012 at 6:11 PM, Murali Karicheri wrote: This is the driver for the main PLL clock hardware found on DM SoCs. This driver borrowed code from arch/arm/mach-davinci/clock.c and implemented the driver as per common clock provider API. The main PLL hardware typically has a multiplier, a pre-divider and a post-divider. Some of the SoCs has the divider fixed meaning they can not be configured through a register. HAS_PREDIV and HAS_POSTDIV flags are used to tell the driver if a hardware has these dividers present or not. Driver is configured through the struct clk_pll_data that has the SoC specific clock data. Signed-off-by: Murali Karicheri This looks good to me. Acked-by: Linus Walleij Yours, Linus Walleij Linus, Thanks. I will add your Acked-by in the next revision of the patch. Murali ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v3 02/11] clk: davinci - add PSC clock driver
On 10/28/2012 03:24 PM, Linus Walleij wrote: On Thu, Oct 25, 2012 at 6:11 PM, Murali Karicheri wrote: This is the driver for the Power Sleep Controller (PSC) hardware found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed code from arch/arm/mach-davinci/psc.c and implemented the driver as per common clock provider API. The PSC module is responsible for enabling/disabling the Power Domain and Clock domain for different IPs present in the SoC. The driver is configured through the clock data passed to the driver through struct clk_psc_data. Signed-off-by: Murali Karicheri Acked-by: Linus Walleij Here is some pedantic stuff if you're really bored: diff --git a/drivers/clk/davinci/clk-psc.c b/drivers/clk/davinci/clk-psc.c (...) + ptcmd = 1 << domain; ptcmd = BIT(domain); + pdctl = readl(psc_base + PDCTL + 4 * domain); + pdctl |= 0x100; pdctl |= BIT(8); /* and here a comment explaing what on earth that means */ + } else { + ptcmd = 1 << domain; ptcmd = BIT(domain); Yours, Linus Walleij Linus, Thanks. I will fix the above and add your Acked-by in the next revision of the patch. Murali ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v3 01/11] clk: davinci - add main PLL clock driver
On 10/31/2012 08:29 AM, Sekhar Nori wrote: Hi Murali, On 10/25/2012 9:41 PM, Murali Karicheri wrote: This is the driver for the main PLL clock hardware found on DM SoCs. This driver borrowed code from arch/arm/mach-davinci/clock.c and implemented the driver as per common clock provider API. The main PLL hardware typically has a multiplier, a pre-divider and a post-divider. Some of the SoCs has the divider fixed meaning they can not be configured through a register. HAS_PREDIV and HAS_POSTDIV flags are used to tell the driver if a hardware has these dividers present or not. Driver is configured through the struct clk_pll_data that has the SoC specific clock data. Signed-off-by: Murali Karicheri --- diff --git a/drivers/clk/davinci/clk-pll.c b/drivers/clk/davinci/clk-pll.c +static unsigned long clk_pllclk_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pll *pll = to_clk_pll(hw); + struct clk_pll_data *pll_data = pll->pll_data; + u32 mult = 1, prediv = 1, postdiv = 1; No need to initialize mult here. I gave this comment last time around as well. Yes. I missed it. I will fix it in the next revision. + unsigned long rate = parent_rate; + + mult = readl(pll_data->reg_pllm); + + /* +* if fixed_multiplier is non zero, multiply pllm value by this +* value. +*/ + if (pll_data->fixed_multiplier) + mult = pll_data->fixed_multiplier * + (mult & pll_data->pllm_mask); + else + mult = (mult & pll_data->pllm_mask) + 1; Hmm, this is interpreting the 'mult' register field differently in both cases. In one case it is 'actual multiplier - 1' and in other case it is the 'actual multiplier' itself. Can we be sure that the mult register definition will change whenever there is a fixed multiplier in the PLL block? I don't think any of the existing DaVinci devices have a fixed multiplier. Is this on keystone? Read section 6.4.3 (PLL Mode) in DM365 documentation (SPRUFG5a.pdf) that states PLL multiplies the clock by 2x the value in the PLLM. In the old code this is handled by a if cpu_is_* macro that we can't use in the driver. So this is represented by a fixed_multiplier that can be set to 2 for DM365 and zero on other SoCs. +struct clk *clk_register_davinci_pll(struct device *dev, const char *name, + const char *parent_name, + struct clk_pll_data *pll_data) +{ + struct clk_init_data init; + struct clk_pll *pll; + struct clk *clk; + + if (!pll_data) + return ERR_PTR(-ENODEV); -EINVAL? Clearly you are treating NULL value as an invalid argument here. Ok. Will fix to ERR_PTR(-EINVAL). Thanks, Sekhar ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v3 03/11] clk: davinci - common clk utilities to init clk driver
On 11/01/2012 08:41 AM, Sekhar Nori wrote: On 10/25/2012 9:41 PM, Murali Karicheri wrote: This is the common clk driver initialization functions for DaVinci SoCs and other SoCs that uses similar hardware architecture. clock.h also defines struct types for clock definitions in a SoC and clock data type for configuring clk-mux. The initialization functions are used by clock initialization code in a specific platform/SoC. Signed-off-by: Murali Karicheri +struct clk *davinci_plldiv_clk(const char *name, const char *parent, + struct clk_plldiv_data *data) +{ + /* +* This is a PLL divider clock with divider specified by +* div_reg in pll_div_data. +*/ + data->reg = ioremap(data->phys_div_reg, 4); + if (WARN_ON(!data->reg)) + return NULL; + + return clk_register_davinci_plldiv(NULL, name, parent, data, &_lock); This function does not exist at this point. Looks like you need to swap 3/11 with 4/11. Also, you should also add build infrastructure (makefile, Kconfig) changes in the same patch that creates the file. There is no point in adding those separately. Thanks, Sekhar Sekhar, So the Makefile, Kconfig and new files should be in the same patch. Also will re-order the 3/11 and 4/11 in the next revision. Murali ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v3 04/11] clk: davinci - add pll divider clock driver
On 11/02/2012 07:33 AM, Sekhar Nori wrote: On 10/25/2012 9:41 PM, Murali Karicheri wrote: pll dividers are present in the pll controller of DaVinci and Other SoCs that re-uses the same hardware IP. This has a enable bit for bypass the divider or enable the driver. This is a sub class of the clk-divider clock checks the enable bit to calculare the rate and invoke the recalculate() function of the clk-divider if enabled. Signed-off-by: Murali Karicheri --- drivers/clk/davinci/clk-div.c | 124 + drivers/clk/davinci/clk-div.h | 42 ++ 2 files changed, 166 insertions(+) create mode 100644 drivers/clk/davinci/clk-div.c create mode 100644 drivers/clk/davinci/clk-div.h diff --git a/drivers/clk/davinci/clk-div.c b/drivers/clk/davinci/clk-div.c new file mode 100644 index 000..8147d99 --- /dev/null +++ b/drivers/clk/davinci/clk-div.c @@ -0,0 +1,124 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2012 Texas instuments + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: incomplete sentence. Will fix +/** + * clk_register_davinci_plldiv - register function for DaVinci PLL divider clk + * + * @dev: device ptr + * @name: name of the clock + * @parent_name: name of parent clock + * @plldiv_data: ptr to pll divider data + * @lock: ptr to spinlock passed to divider clock + */ +struct clk *clk_register_davinci_plldiv(struct device *dev, Why do you need a dev pointer here and which device does it point to? In the only usage of this API in the series, you pass a NULL here. I should have probably asked this question on one of the earlier patches itself. I did a grep in the drivers/clk directory. All of the platform drivers are having the device ptr and all of them are called with NULL. I am not sure what is the intent of this arg in the API. As per documentation of the clk_register() API, the device ptr points to the device that is registering this clk. So if a specific device driver ever has to register a PLL div clk, this will be non NULL. In the normal use case, clk is registered in a platform specific code and is always passed NULL. The platform/SoC specific clock initialization code will be using davinci_plldiv_clk() that doesn't have a device ptr arg. So this can be changed in future in sync with other drivers (assuming this will get removed if unused), and changes doesn't impact the platform code that initialize the clock. So IMO, we should keep this arg so that it is in sync with other driver APIs. + const char *name, const char *parent_name, + struct clk_plldiv_data *plldiv_data, + spinlock_t *lock) +{ + struct clk_div *div; + struct clk *clk; + struct clk_init_data init; + + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &clk_div_ops; + init.flags = plldiv_data->flags; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + div->reg = plldiv_data->reg; + div->en_id = plldiv_data->en_id; + + div->divider.reg = plldiv_data->reg; + div->divider.shift = plldiv_data->shift; + div->divider.width = plldiv_data->width; + div->divider.flags = plldiv_data->divider_flags; + div->divider.lock = lock; + div->divider.hw.init = &init; + div->ops = &clk_divider_ops; + + clk = clk_register(NULL, &div->divider.hw); Shouldn't you be calling clk_register_divider() here which in turn will do clk_register()? As stated in the top of the file, this is a subclass driver of clk-div similar in line with mxs/clk-div.c. The driver registers the clock instead of calling clk_register_divider() so that it's ops function has a chance to do whatever it wants to do and call the divider ops function after that. Murali Thanks, Sekhar ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[RFC PATCH 2/2] mtd: davinci - remove DaVinci architecture depedency
DaVinci NAND driver is a controller driver based on the AEMIF hardware IP found on TI SoCs. It is also used on SoCs that are not DaVinci based. This patch removes the driver dependency on DaVinci architecture so that it can be used on other architectures such as c6x, keystone etc. Also migrate the driver to use the new AEMIF platform driver API. Signed-off-by: Murali Karicheri --- drivers/mtd/nand/Kconfig |6 +- drivers/mtd/nand/davinci_nand.c| 40 ++--- include/linux/platform_data/davinci-nand.h | 87 3 files changed, 107 insertions(+), 26 deletions(-) create mode 100644 include/linux/platform_data/davinci-nand.h diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 8ca4176..390cc95 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -569,11 +569,11 @@ config MTD_NAND_SH_FLCTL for NAND Flash using FLCTL. config MTD_NAND_DAVINCI -tristate "Support NAND on DaVinci SoC" -depends on ARCH_DAVINCI +tristate "Support NAND on SoCs with AEMIF" + select TI_DAVINCI_AEMIF help Enable the driver for NAND flash chips on Texas Instruments - DaVinci processors. + SoCs that has Asynchronous External Memory Interface (AEMIF). config MTD_NAND_TXX9NDFMC tristate "NAND Flash support for TXx9 SoC" diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 321b053..306959e 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -35,8 +35,8 @@ #include #include -#include -#include +#include +#include /* * This is a device driver for the NAND flash controller found on the @@ -73,7 +73,7 @@ struct davinci_nand_info { uint32_tcore_chipsel; - struct davinci_aemif_timing *timing; + struct davinci_aemif_cs_data*cs_data; }; static DEFINE_SPINLOCK(davinci_nand_lock); @@ -652,7 +652,6 @@ static int __init nand_davinci_probe(struct platform_device *pdev) info->chip.options = pdata->options; info->chip.bbt_td = pdata->bbt_td; info->chip.bbt_md = pdata->bbt_md; - info->timing= pdata->timing; info->ioaddr= (uint32_t __force) vaddr; @@ -731,26 +730,21 @@ static int __init nand_davinci_probe(struct platform_device *pdev) goto err_clk_enable; } - /* -* Setup Async configuration register in case we did not boot from -* NAND and so bootloader did not bother to set it up. -*/ - val = davinci_nand_readl(info, A1CR_OFFSET + info->core_chipsel * 4); - - /* Extended Wait is not valid and Select Strobe mode is not used */ - val &= ~(ACR_ASIZE_MASK | ACR_EW_MASK | ACR_SS_MASK); - if (info->chip.options & NAND_BUSWIDTH_16) - val |= 0x1; + if (info->chip.options & NAND_BUSWIDTH_16) { + info->cs_data = + davinci_aemif_get_abus_params(info->core_chipsel); + if (info->cs_data == NULL) + goto err_bus_config; - davinci_nand_writel(info, A1CR_OFFSET + info->core_chipsel * 4, val); + /* asize = 1 for 16bit bus */ + info->cs_data->asize = 1; + ret = davinci_aemif_set_abus_params(info->core_chipsel, + info->cs_data); - ret = 0; - if (info->timing) - ret = davinci_aemif_setup_timing(info->timing, info->base, - info->core_chipsel); - if (ret < 0) { - dev_dbg(&pdev->dev, "NAND timing values setup fail\n"); - goto err_timing; + if (ret < 0) { + dev_dbg(&pdev->dev, "NAND timing values setup fail\n"); + goto err_bus_config; + } } spin_lock_irq(&davinci_nand_lock); @@ -841,7 +835,7 @@ syndrome_done: return 0; err_scan: -err_timing: +err_bus_config: clk_disable_unprepare(info->clk); err_clk_enable: diff --git a/include/linux/platform_data/davinci-nand.h b/include/linux/platform_data/davinci-nand.h new file mode 100644 index 000..df1fc66 --- /dev/null +++ b/include/linux/platform_data/davinci-nand.h @@ -0,0 +1,87 @@ +/* + * mach-davinci/nand.h + * + * Copyright © 2006 Texas Instruments. + * + * Ported to 2.6.23 Copyright © 2008 by + * Sander Huijsen + * Troy Kisky + * Dirk Behme + * + * -- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published
[RFC PATCH 1/2] memory: davinci - add aemif controller platform driver
This is a platform driver for asynchronous external memory interface available on TI SoCs. This driver was previously located inside the mach-davinci folder. As this DaVinci IP is re-used across multiple family of devices such as c6x, keystone etc, the driver is moved to drivers. The driver configures async bus parameters associated with a particular chip select. For DaVinci controller driver and driver for other async devices such as NOR flash, ASRAM etc, the bus confuguration is done by this driver at init time. A set of APIs (set/get) provided to update the values based on specific driver usage. Signed-off-by: Murali Karicheri --- .../devicetree/bindings/arm/davinci/aemif.txt | 62 +++ drivers/memory/Kconfig | 10 + drivers/memory/Makefile|1 + drivers/memory/davinci-aemif.c | 397 include/linux/platform_data/davinci-aemif.h| 47 +++ 5 files changed, 517 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/davinci/aemif.txt create mode 100644 drivers/memory/davinci-aemif.c create mode 100644 include/linux/platform_data/davinci-aemif.h diff --git a/Documentation/devicetree/bindings/arm/davinci/aemif.txt b/Documentation/devicetree/bindings/arm/davinci/aemif.txt new file mode 100644 index 000..7d70d42 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/davinci/aemif.txt @@ -0,0 +1,62 @@ +* Texas Instruments Davinci AEMIF bus interface + +This file provides information for the davinci-emif chip select +bindings. + +This is a sub device node inside the davinci-emif device node +to describe a async bus for a specific chip select. For NAND, +CFI flash device bindings described inside an aemif node, +etc, a cs sub node is defined to associate the bus parameter +bindings used by the device. + +Required properties:= +- compatible: "ti,davinci-cs"; +- #address-cells = <1>; +- #size-cells = <1>; +- cs - cs used by the device (NAND, CFI flash etc. values in the range: 2-5 + +Optional properties:- +- asize - asynchronous data bus width (0 - 8bit, 1 - 16 bit) + All of the params below in nanoseconds + +- ta - Minimum turn around time +- rhold - read hold width +- rstobe - read strobe width +- rsetup - read setup width +- whold - write hold width +- wstrobe - write strobe width +- wsetup - write setup width +- ss - enable/disable select strobe (0 - disable, 1 - enable) +- ew - enable/disable extended wait cycles (0 - disable, 1 - enable) + +Example for davinci nand chip select + +aemif@6000 { + + compatible = "ti,davinci-aemif"; + #address-cells = <2>; + #size-cells = <1>; + + nand_cs:cs2@7000 { + compatible = "ti,davinci-cs"; + #address-cells = <1>; + #size-cells = <1>; + cs = <2>; + asize = <1>; + ta = <24>; + rhold = <48>; + rstrobe = <390>; + rsetup = <96>; + whold = <48>; + wstrobe = <390>; + wsetup = <96>; + }; + + nand@2,0 { + + + + }; +}; + + diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig index 067f311..2636a95 100644 --- a/drivers/memory/Kconfig +++ b/drivers/memory/Kconfig @@ -40,4 +40,14 @@ config TEGRA30_MC analysis, especially for IOMMU/SMMU(System Memory Management Unit) module. +config TI_DAVINCI_AEMIF + bool "Texas Instruments DaVinci AEMIF driver" + help + This driver is for the AEMIF module available in Texas Instruments + SoCs. AEMIF stands for Asynchronous External Memory Interface and + is intended to provide a glue-less interface to a variety of + asynchronuous memory devices like ASRAM, NOR and NAND memory. A total + of 256M bytes of any of these memories can be accessed at a given + time via four chip selects with 64M byte access per chip select. + endif diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index 42b3ce9..246aa61 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_TI_EMIF) += emif.o obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o obj-$(CONFIG_TEGRA30_MC) += tegra30-mc.o +obj-$(CONFIG_TI_DAVINCI_AEMIF) += davinci-aemif.o diff --git a/drivers/memory/davinci-aemif.c b/drivers/memory/davinci-aemif.c new file mode 100644 index 000..6c42116 --- /dev/null +++ b/drivers/memory/davinci-aemif.c @@ -0,0 +1,397 @@ +/* + * AEMIF support for DaVinci SoCs + * + * Copyright (C) 2010 Texas Instruments Incorporated. http://www.ti.com/ + * Copyright (C) Heiko Schocher + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as
[RFC PATCH 0/2] - Move AEMIF driver out of DaVinci machine
The DaVinci AEMIF (asynchronous external memory interface) is used on other TI SoCs that are not DaVinci based. So the AEMIF driver is to be moved outside mach-davinci to the drivers folder so that it can be re-used on other TI SoCs. Also migrate the DaVinci NAND driver to use the new aemif API. Some of these code has been borrowed from intial patch from Heiko Schocher . So I have added his name in the Copyright for davinci-aemif.c This is an RFC to get the intial response so that all the platforms can be migrated to use this driver. Murali Karicheri (2): memory: davinci - add aemif controller platform driver mtd: davinci - remove DaVinci architecture depedency .../devicetree/bindings/arm/davinci/aemif.txt | 62 +++ drivers/memory/Kconfig | 10 + drivers/memory/Makefile|1 + drivers/memory/davinci-aemif.c | 397 drivers/mtd/nand/Kconfig |6 +- drivers/mtd/nand/davinci_nand.c| 40 +- include/linux/platform_data/davinci-aemif.h| 47 +++ include/linux/platform_data/davinci-nand.h | 87 + 8 files changed, 624 insertions(+), 26 deletions(-) create mode 100644 Documentation/devicetree/bindings/arm/davinci/aemif.txt create mode 100644 drivers/memory/davinci-aemif.c create mode 100644 include/linux/platform_data/davinci-aemif.h create mode 100644 include/linux/platform_data/davinci-nand.h -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v3 04/11] clk: davinci - add pll divider clock driver
On 11/03/2012 08:03 AM, Sekhar Nori wrote: On 11/2/2012 7:23 PM, Murali Karicheri wrote: On 11/02/2012 07:33 AM, Sekhar Nori wrote: On 10/25/2012 9:41 PM, Murali Karicheri wrote: pll dividers are present in the pll controller of DaVinci and Other SoCs that re-uses the same hardware IP. This has a enable bit for bypass the divider or enable the driver. This is a sub class of the clk-divider clock checks the enable bit to calculare the rate and invoke the recalculate() function of the clk-divider if enabled. Signed-off-by: Murali Karicheri --- +/** + * clk_register_davinci_plldiv - register function for DaVinci PLL divider clk + * + * @dev: device ptr + * @name: name of the clock + * @parent_name: name of parent clock + * @plldiv_data: ptr to pll divider data + * @lock: ptr to spinlock passed to divider clock + */ +struct clk *clk_register_davinci_plldiv(struct device *dev, Why do you need a dev pointer here and which device does it point to? In the only usage of this API in the series, you pass a NULL here. I should have probably asked this question on one of the earlier patches itself. I did a grep in the drivers/clk directory. All of the platform drivers are having the device ptr and all of them are called with NULL. I am not sure what is the intent of this arg in the API. As per documentation of I just took a look at the mxs example you referenced below and it does not take a dev pointer. struct clk *mxs_clk_div(const char *name, const char *parent_name, void __iomem *reg, u8 shift, u8 width, u8 busy) { the clk_register() API, the device ptr points to the device that is registering this clk. So if a specific device driver ever has to register a PLL div clk, this will be non NULL. In the normal use case, clk is registered in a platform specific code and is always passed NULL. The platform/SoC specific clock initialization code will be using davinci_plldiv_clk() that doesn't have a device ptr arg. So this can be changed in future in sync with other drivers (assuming this will get removed if unused), and changes doesn't impact the platform code that initialize the clock. So IMO, we should keep this arg so that it is in sync with other driver APIs. I think you should get rid of this unused arg and introduce it when you actually need it. That way we are clear about why we need it. You are right. I will remove it and for other drivers. +const char *name, const char *parent_name, +struct clk_plldiv_data *plldiv_data, +spinlock_t *lock) +{ +struct clk_div *div; +struct clk *clk; +struct clk_init_data init; + +div = kzalloc(sizeof(*div), GFP_KERNEL); +if (!div) +return ERR_PTR(-ENOMEM); + +init.name = name; +init.ops = &clk_div_ops; +init.flags = plldiv_data->flags; +init.parent_names = (parent_name ? &parent_name : NULL); +init.num_parents = (parent_name ? 1 : 0); + +div->reg = plldiv_data->reg; +div->en_id = plldiv_data->en_id; + +div->divider.reg = plldiv_data->reg; +div->divider.shift = plldiv_data->shift; +div->divider.width = plldiv_data->width; +div->divider.flags = plldiv_data->divider_flags; +div->divider.lock = lock; +div->divider.hw.init = &init; +div->ops = &clk_divider_ops; + +clk = clk_register(NULL, &div->divider.hw); Shouldn't you be calling clk_register_divider() here which in turn will do clk_register()? As stated in the top of the file, this is a subclass driver of clk-div similar in line with mxs/clk-div.c. The driver registers the clock instead of calling clk_register_divider() so that it's ops function has a chance to do whatever it wants to do and call the divider ops function after that. I see that now. I should have paid more attention. Regards, Sekhar ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v3 02/11] clk: davinci - add PSC clock driver
On 11/03/2012 08:07 AM, Sekhar Nori wrote: On 10/25/2012 9:41 PM, Murali Karicheri wrote: This is the driver for the Power Sleep Controller (PSC) hardware found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed code from arch/arm/mach-davinci/psc.c and implemented the driver as per common clock provider API. The PSC module is responsible for enabling/disabling the Power Domain and Clock domain for different IPs present in the SoC. The driver is configured through the clock data passed to the driver through struct clk_psc_data. Signed-off-by: Murali Karicheri --- +/** + * struct clk_psc - DaVinci PSC clock driver data + * + * @hw: clk_hw for the psc + * @psc_data: Driver specific data + */ +struct clk_psc { + struct clk_hw hw; + struct clk_psc_data *psc_data; + spinlock_t *lock; Unused member? I don't see this being used. OK. Will remove. Thanks, Sekhar ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v3 03/11] clk: davinci - common clk utilities to init clk driver
On 11/03/2012 08:35 AM, Sekhar Nori wrote: On 10/25/2012 9:41 PM, Murali Karicheri wrote: This is the common clk driver initialization functions for DaVinci SoCs and other SoCs that uses similar hardware architecture. clock.h also defines struct types for clock definitions in a SoC and clock data type for configuring clk-mux. The initialization functions are used by clock initialization code in a specific platform/SoC. Signed-off-by: Murali Karicheri --- drivers/clk/davinci/clock.c | 112 +++ drivers/clk/davinci/clock.h | 80 +++ 2 files changed, 192 insertions(+) create mode 100644 drivers/clk/davinci/clock.c create mode 100644 drivers/clk/davinci/clock.h diff --git a/drivers/clk/davinci/clock.c b/drivers/clk/davinci/clock.c new file mode 100644 index 000..ad02149 --- /dev/null +++ b/drivers/clk/davinci/clock.c @@ -0,0 +1,112 @@ +/* + * clock.c - davinci clock initialization functions for various clocks + * + * Copyright (C) 2006-2012 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include + +#include "clk-pll.h" +#include "clk-psc.h" +#include "clk-div.h" +#include "clock.h" + +static DEFINE_SPINLOCK(_lock); + +#ifdef CONFIG_CLK_DAVINCI_PLL +struct clk *davinci_pll_clk(const char *name, const char *parent, + u32 phys_pllm, u32 phys_prediv, u32 phys_postdiv, + struct clk_pll_data *pll_data) +{ + struct clk *clkp = NULL; + + pll_data->reg_pllm = ioremap(phys_pllm, 4); + if (WARN_ON(!pll_data->reg_pllm)) + return clkp; I would prefer ERR_PTR(-ENOMEM) here. Same comment applies to other instances elsewhere in the patch. diff --git a/drivers/clk/davinci/clock.h b/drivers/clk/davinci/clock.h new file mode 100644 index 000..73204b8 --- /dev/null +++ b/drivers/clk/davinci/clock.h @@ -0,0 +1,80 @@ +/* + * TI DaVinci Clock definitions - Contains Macros and Types used for + * defining various clocks on a DaVinci SoC + * + * Copyright (C) 2012 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __DAVINCI_CLOCK_H +#define __DAVINCI_CLOCK_H + +#include + +/* general flags: */ +#define ALWAYS_ENABLED BIT(0) This is not used in this patch. Can you add the define along with its usage so it is immediately clear why you need it? This is used on the next patch as this adds a bunch of utilities or types for the platform specific clock code. Do you want to combine this patch with 05/11? It will become a bigger patch then? Is that fine. IMO, this is a logical group that can be a standalone patch than combining with 05/11. +/** + * struct davinci_clk - struct for defining DaVinci clocks for a SoC. + * + * @name: name of the clock + * @parent: name of parent clock + * @flags: General flags for all drivers used by platform clock init code + * @data: data specific to a clock used by the driver + * @dev_id: dev_id used to look up this clock. If this is NULL + * clock name is used for lookup. + */ +struct davinci_clk { + const char *name; + const char *parent; + u32 flags; + void*data; + char*dev_id; Similarly dont see this being used as well. For this and previous one, check lpsc_clk() macro usage. dev_id is used where a specific device id is used to look up the clk as is done for davinci_emac.1, davinci_mmc.0 etc. Thanks, Sekhar ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v3 05/11] clk: davinci - add dm644x clock initialization
On 11/03/2012 09:30 AM, Sekhar Nori wrote: On 10/25/2012 9:41 PM, Murali Karicheri wrote: This patch adds dm644x clock initialization code that consists of clocks data for various clocks and clock register callouts to various clock drivers. It uses following clk drivers for this 1. clk-fixed-rate - for ref clock 2. clk-mux - for mux at the input and output of main pll 3. davinci specific clk-pll for main pll clock 4. davinci specific clk-div for pll divider clock 5. clk-fixed-factor for fixed factor clock such as auxclk 6. davinci specific clk-psc for psc clocks This patch also moves all of the PLL and PSC register definitions from clock.h and psc.h under davinci to the clk/davinci folder so that various soc specific clock initialization code can share these definitions. Except this patch does not move the defines, it creates a copy of them (which is bad since you quickly lose track of which is the correct copy). Is this done to avoid including mach/ header files here? Yes. It will actually be better to include the mach/ files here as a temporary solution and then remove the include mach/ files once all the SoCs have been converted over. I was thinking we are not allowed to include mach/* header files in driver files. But most of the clk drivers such clk-imx28, spear6xx_clock.c. versatile/clk-integrator.c etc are including mach/ headers. One issue is that the definitions in pll.h are re-usable across other machines falling under c6x and Keystone (new device we are working on) as well. Where do we keep includes that can be re-used across different architectures? include/linux/platform_data/ ? I see clk-integrator.h, clk-nomadik.h and clk-u300 sitting there. So I suggest moving any header files that defines utility functions, register definitions across different architectures to include/linux/platform_data. Candidate files would be clock.h, pll.h, clk-psc.h, clk-pll.h and clk-div.h. This way these can be used across the above machines that use the above architectures. Can we do this in my next version? This way we don't have to make another move later. All these CLK IPs are re-used across multiple architectures and make perfect sense to me to move to the above folder. Signed-off-by: Murali Karicheri --- drivers/clk/davinci/dm644x-clock.c | 304 drivers/clk/davinci/pll.h | 83 ++ drivers/clk/davinci/psc.h | 215 + 3 files changed, 602 insertions(+) create mode 100644 drivers/clk/davinci/dm644x-clock.c create mode 100644 drivers/clk/davinci/pll.h create mode 100644 drivers/clk/davinci/psc.h +/* all clocks available in DM644x SoCs */ +enum dm644x_clk { + clkin, oscin, ref_clk_mux, pll1, pll1_plldiv_clk_mux, auxclk, + clk_pll1_sysclk1, clk_pll1_sysclk2, clk_pll1_sysclk3, clk_pll1_sysclk4, + clk_pll1_sysclk5, clk_pll1_sysclkbp, pll2, pll2_plldiv_clk_mux, + clk_pll2_sysclk1, clk_pll2_sysclk2, clk_pll2_sysclkbp, dsp, arm, vicp, + vpss_master, vpss_slave, uart0, uart1, uart2, emac, i2c, ide, asp, + mmcsd, spi, gpio, usb, vlynq, aemif, pwm0, pwm1, pwm2, timer0, timer1, + timer2, clk_max +}; + +static struct davinci_clk *psc_clocks[] = { + &clk_dsp, &clk_arm, &clk_vicp, &clk_vpss_master, &clk_vpss_slave, + &clk_uart0, &clk_uart1, &clk_uart2, &clk_emac, &clk_i2c, &clk_ide, + &clk_asp0, &clk_mmcsd, &clk_spi, &clk_gpio, &clk_usb, &clk_vlynq, + &clk_aemif, &clk_pwm0, &clk_pwm1, &clk_pwm2, &clk_timer0, &clk_timer1, + &clk_timer2 +}; You rely on perfect order between this array and dm644x_clk enum above. Can you initialize this array using the enum as the index so that it is clear. Current method is too error prone. Ok. Will do. Thanks, Sekhar ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v3 10/11] ARM: davinci - migrate to common clock
On 11/04/2012 08:06 AM, Sekhar Nori wrote: On 10/25/2012 9:41 PM, Murali Karicheri wrote: Currently migrate only DM644x as this is being reviewed. Once all platforms are migrated, the Makefile will be cleaned up to remove obsoleted files clock.o and psc.o Signed-off-by: Murali Karicheri --- arch/arm/Kconfig |1 + arch/arm/mach-davinci/Kconfig |2 ++ arch/arm/mach-davinci/Makefile | 11 ++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5f9ae5..4611987 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -967,6 +967,7 @@ config ARCH_DAVINCI select ARCH_REQUIRE_GPIOLIB select ZONE_DMA select HAVE_IDE + select COMMON_CLK select CLKDEV_LOOKUP select GENERIC_ALLOCATOR select GENERIC_IRQ_CHIP This list has to be sorted. Russell has a patch which fixed this all across arch/arm/* which got merged for v3.7. This patch does not apply to v3.7-rc3 anymore due to the same reason. Thanks, Sekhar Ok. Will do. ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v3 06/11] clk: davinci - add build infrastructure for DaVinci clock drivers
On 11/04/2012 08:34 AM, Sekhar Nori wrote: On 10/25/2012 9:41 PM, Murali Karicheri wrote: This updates clk Makefile and Kconfig to integrate the DaVinci specific clock drivers. Also add new Kconfig and Makefile for these drivers. Signed-off-by: Murali Karicheri As mentioned before, this should be folded into previous patches which actually add the particular functionality. Yes. Agreed., --- drivers/clk/Kconfig |2 ++ drivers/clk/Makefile |1 + drivers/clk/davinci/Kconfig | 44 ++ drivers/clk/davinci/Makefile |5 + 4 files changed, 52 insertions(+) create mode 100644 drivers/clk/davinci/Kconfig create mode 100644 drivers/clk/davinci/Makefile diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 7f0b5ca..1ad2ab0 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -33,6 +33,8 @@ config COMMON_CLK_DEBUG clk_flags, clk_prepare_count, clk_enable_count & clk_notifier_count. +source "drivers/clk/davinci/Kconfig" + config COMMON_CLK_WM831X tristate "Clock driver for WM831x/2x PMICs" depends on MFD_WM831X diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 5869ea3..b127b6f 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_ARCH_SOCFPGA)+= socfpga/ obj-$(CONFIG_PLAT_SPEAR) += spear/ obj-$(CONFIG_ARCH_U300) += clk-u300.o obj-$(CONFIG_ARCH_INTEGRATOR) += versatile/ +obj-$(CONFIG_DAVINCI_CLKS) += davinci/ # Chip specific obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o diff --git a/drivers/clk/davinci/Kconfig b/drivers/clk/davinci/Kconfig new file mode 100644 index 000..e53bbc3 --- /dev/null +++ b/drivers/clk/davinci/Kconfig @@ -0,0 +1,44 @@ +menu "TI DaVinci Clock drivers" + depends on COMMON_CLK + +config CLK_DAVINCI_PSC + bool "TI DaVici PSC clock driver" + default n + ---help--- + Selects clock driver for DaVinci PSC clocks. This clock + hardware is found on TI DaVinci SoCs and other SoCs that + uses this hardware IP. This hardware has a local power + sleep control module that gate the clock to the IP. + +config CLK_DAVINCI_PLL + bool "DaVici main PLL clock" + ---help--- + Selects clock driver for DaVinci main PLL. This clock + hardware is found on TI DaVinci SoCs. This typically has + a multiplier, a pre divider and post driver. Some of the + SoCs has the the dividers fixed, and others have it + programmable + +config CLK_DAVINCI_PLLDIV + bool "DaVici PLL divider clock" + ---help--- + Selects clock driver for DaVinci PLL divider. This clock + hardware is found on TI DaVinci SoCs. This typically has + a divider and an enable bit to bypass or enable the + divider. + +config DAVINCI_CLKS + bool "TI DaVinci common clocks" + default n + select CLK_DAVINCI_PSC + select CLK_DAVINCI_PLLDIV + ---help--- + Selects common clock drivers for DaVinci. These clocks + are re-used across many TI SoCs that are based on DaVinci and + Keystone (c6x) families. This config option is used to select + the common clock driver for DaVinci based SoCs. SoCs specific + Kconfig option needs to select the driver for clocks specific + to the SoC. + +endmenu I wonder if all these configurations are really required. For complete clock functionality you anyway require all this functionality so I wonder why anyone would not select any of these. And to differentiate between architecture changes, conditional build based on architecture can be used: I know this is a grey area I need to improve and had a discussion with Mike sometime back. Are you also suggesting including davinci folder unconditionally under drivers/clk/Makefile? I think it will work. And then in clk/davinci/Makefile we can include on a per architecture basis. But I am not sure if calling the folder as davinci make sense and these drivers are used on non DaVinci architectures as well. I had initially named it as "ti" to include all ti drivers. But Mike had commented that current directory structure use platform/arch name instead of vendor name. Also OMAP is going to move the clk drivers to this folder soon. So for now, davinci may be used to house all of the non OMAP drivers. Later we can re-visit this as needed (wouldn't be that hard to do this within the clk driver folder later). We can keep the davinci folder name and unconditionally include it in clk/Makefile. clk/Makefile add obj-y += davinci/ clk/davinci/Makefile obj-$(CONFIG_ARCH_DAVINCI) += clk-pll.o clk-div.o clk-psc.o clock.o obj-$(CONFIG_ARCH_KEYSTONE) += clk-pll-keystone.o clk-div.o clk-psc.o clock.o obj-$(CONFIG_ARCH_DAVINCI_DM644x) += c
Re: [PATCH v3 07/11] ARM: davinci - restructure header files for common clock migration
On 11/04/2012 09:05 AM, Sekhar Nori wrote: On 10/25/2012 9:41 PM, Murali Karicheri wrote: pll.h is added to migrate some of the PLL controller defines for sleep.S. psc.h is modified to keep only PSC modules definitions needed by sleep.S after migrating to common clock. The definitions under ifdef CONFIG_COMMON_CLK will be removed in a subsequent patch. davinci_watchdog_reset prototype is moved to time.h as clock.h is being obsoleted. sleep.S and pm.c is modified to include the new header file replacements. Signed-off-by: Murali Karicheri --- arch/arm/mach-davinci/devices.c |2 ++ arch/arm/mach-davinci/include/mach/pll.h | 46 + arch/arm/mach-davinci/include/mach/psc.h |4 +++ arch/arm/mach-davinci/include/mach/time.h |4 ++- arch/arm/mach-davinci/pm.c|4 +++ arch/arm/mach-davinci/sleep.S |4 +++ 6 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-davinci/include/mach/pll.h With this patch a _third_ copy of PLL definitions is created in kernel sources. The existing PLL definitions in clock.h inside mach-davinci should be moved to mach/pll.h and the pll.h you introduced inside drivers/clk in 5/11 should be removed (this patch should appear before 5/11). The biggest disadvantage of this approach is inclusion of mach/ includes in drivers/clk. But duplicating code is definitely not the fix for this. Anyway, mach/ includes are not uncommon in drivers/clk (they are all probably suffering from the same issue). Sekhar, I have replied to patch 5/11 that also refers to this. The main reason we are not able to do this cleanly is the code in sleep.c and pm.c. That is something related to Power management. Could you take a look and see if you can do some clean up on this code? I believe It is more than just moving the header files. Murali $ grep -rl "include Thanks for offering some help. Yes I can provide you incremental patch. But then could you also help me to squash/rebase and send patches to the list for review? Thanks, Sekhar ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [RFC PATCH 1/2] memory: davinci - add aemif controller platform driver
On 11/04/2012 08:52 AM, Rob Herring wrote: OMAP GPMC Could you send me a link please? Murali ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source