[PATCH 12/19] ARM: S5PC1XX: add support for s5pc110 plls and clocks
Ben Dooks
ben-linux at fluff.org
Wed Nov 18 17:15:11 EST 2009
On Wed, Nov 18, 2009 at 02:33:07PM +0100, Marek Szyprowski wrote:
> From: Kyungmin Park <kyungmin.park at samsung.com>
>
> Samsung S5PC110 SoC are newer Samsung SoCs. Like S5PC100 they are based
> on CortexA8 ARM CPU, but have much more powerfull integrated periperals.
> This patch adds clocks and plls definition for S5PC110 SoCs.
>
> Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>
> Signed-off-by: Marek Szyprowski <m.szyprowski at samsung.com>
>
> ---
> arch/arm/mach-s5pc110/Kconfig | 1 +
> arch/arm/mach-s5pc110/cpu.c | 3 +
> arch/arm/mach-s5pc110/include/plat/regs-clock.h | 347 ++++++
> arch/arm/plat-s5pc1xx/Kconfig | 5 +
> arch/arm/plat-s5pc1xx/Makefile | 1 +
> arch/arm/plat-s5pc1xx/include/plat/pll.h | 8 +-
> arch/arm/plat-s5pc1xx/include/plat/s5pc110.h | 11 +
> arch/arm/plat-s5pc1xx/s5pc100-plls.c | 8 +-
> arch/arm/plat-s5pc1xx/s5pc110-clocks.c | 254 +++++
> arch/arm/plat-s5pc1xx/s5pc110-plls.c | 1292 +++++++++++++++++++++++
Are these files likely to be shared with other SoCs? If not, then they
would be better off going in arch/arm/mach-s5pc110/ instead of here and
just being compiled if the machine support is enabled.
> 10 files changed, 1924 insertions(+), 6 deletions(-)
> create mode 100644 arch/arm/mach-s5pc110/include/plat/regs-clock.h
> create mode 100644 arch/arm/plat-s5pc1xx/s5pc110-clocks.c
> create mode 100644 arch/arm/plat-s5pc1xx/s5pc110-plls.c
>
> diff --git a/arch/arm/mach-s5pc110/Kconfig b/arch/arm/mach-s5pc110/Kconfig
> index fb298e2..420b585 100644
> --- a/arch/arm/mach-s5pc110/Kconfig
> +++ b/arch/arm/mach-s5pc110/Kconfig
> @@ -12,6 +12,7 @@ if ARCH_S5PC110
> config CPU_S5PC110
> bool
> select CPU_S5PC110_INIT
> + select CPU_S5PC110_CLOCK
> help
> Enable S5PC110 CPU support
>
> diff --git a/arch/arm/mach-s5pc110/cpu.c b/arch/arm/mach-s5pc110/cpu.c
> index 1a4a5e4..6c9ebcb 100644
> --- a/arch/arm/mach-s5pc110/cpu.c
> +++ b/arch/arm/mach-s5pc110/cpu.c
> @@ -86,6 +86,9 @@ void __init s5pc110_init_clocks(int xtal)
> {
> printk(KERN_DEBUG "%s: initialising clocks\n", __func__);
> s3c24xx_register_baseclocks(xtal);
> + s5pc1xx_register_clocks();
> + s5pc110_register_clocks();
> + s5pc110_setup_clocks();
> }
>
> void __init s5pc110_init_irq(void)
> diff --git a/arch/arm/mach-s5pc110/include/plat/regs-clock.h b/arch/arm/mach-s5pc110/include/plat/regs-clock.h
> new file mode 100644
> index 0000000..4305a07
> --- /dev/null
> +++ b/arch/arm/mach-s5pc110/include/plat/regs-clock.h
> @@ -0,0 +1,347 @@
> +/* arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
> + *
> + * Copyright 2009 Samsung Electronics Co.
> + * Byungho Min <bhmin at samsung.com>
> + *
> + * S5PC110 clock register definitions
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +#ifndef __PLAT_REGS_CLOCK_H
> +#define __PLAT_REGS_CLOCK_H __FILE__
> +
> +#define S5PC1XX_CLKREG(x) (S5PC1XX_VA_CLK + (x))
> +
> +/* s5pc110 register for clock */
> +#define S5PC110_APLL_LOCK S5PC1XX_CLKREG(0x00)
> +#define S5PC110_MPLL_LOCK S5PC1XX_CLKREG(0x08)
> +#define S5PC110_EPLL_LOCK S5PC1XX_CLKREG(0x10)
> +#define S5PC110_VPLL_LOCK S5PC1XX_CLKREG(0x20)
> +
> +#define S5PC110_APLL_CON S5PC1XX_CLKREG(0x100)
> +#define S5PC110_MPLL_CON S5PC1XX_CLKREG(0x108)
> +#define S5PC110_EPLL_CON S5PC1XX_CLKREG(0x110)
> +#define S5PC110_VPLL_CON S5PC1XX_CLKREG(0x120)
> +
> +#define S5PC110_CLKSRC0 S5PC1XX_CLKREG(0x200)
> +#define S5PC110_CLKSRC1 S5PC1XX_CLKREG(0x204)
> +#define S5PC110_CLKSRC2 S5PC1XX_CLKREG(0x208)
> +#define S5PC110_CLKSRC3 S5PC1XX_CLKREG(0x20C)
> +#define S5PC110_CLKSRC4 S5PC1XX_CLKREG(0x210)
> +#define S5PC110_CLKSRC5 S5PC1XX_CLKREG(0x214)
> +#define S5PC110_CLKSRC6 S5PC1XX_CLKREG(0x218)
> +
> +#define S5PC110_CLKSRC_MASK0 S5PC1XX_CLKREG(0x280)
> +#define S5PC110_CLKSRC_MASK1 S5PC1XX_CLKREG(0x284)
> +
> +#define S5PC110_CLKDIV0 S5PC1XX_CLKREG(0x300)
> +#define S5PC110_CLKDIV1 S5PC1XX_CLKREG(0x304)
> +#define S5PC110_CLKDIV2 S5PC1XX_CLKREG(0x308)
> +#define S5PC110_CLKDIV3 S5PC1XX_CLKREG(0x30C)
> +#define S5PC110_CLKDIV4 S5PC1XX_CLKREG(0x310)
> +#define S5PC110_CLKDIV5 S5PC1XX_CLKREG(0x314)
> +#define S5PC110_CLKDIV6 S5PC1XX_CLKREG(0x318)
> +#define S5PC110_CLKDIV7 S5PC1XX_CLKREG(0x31C)
> +
> +#define S5PC110_CLKGATE_IP0 S5PC1XX_CLKREG(0x460)
> +#define S5PC110_CLKGATE_IP1 S5PC1XX_CLKREG(0x464)
> +#define S5PC110_CLKGATE_IP2 S5PC1XX_CLKREG(0x468)
> +#define S5PC110_CLKGATE_IP3 S5PC1XX_CLKREG(0x46C)
> +#define S5PC110_CLKGATE_IP4 S5PC1XX_CLKREG(0x470)
> +#define S5PC110_CLKGATE_BLOCK S5PC1XX_CLKREG(0x480)
> +#define S5PC110_CLKGATE_BUS0 S5PC1XX_CLKREG(0x484)
> +#define S5PC110_CLKGATE_BUS1 S5PC1XX_CLKREG(0x488)
> +
> +#define S5PC110_CLK_OUT S5PC1XX_CLKREG(0x500)
> +#define S5PC110_MDNIE_SEL S5PC1XX_CLKREG(0x7008)
> +
> +#define S5PC110_CLKDIV_STAT0 S5PC1XX_CLKREG(0x1000)
> +#define S5PC110_CLKDIV_STAT1 S5PC1XX_CLKREG(0x1004)
> +
> +#define S5PC110_CLK_MUX_STAT0 S5PC1XX_CLKREG(0x1100)
> +#define S5PC110_CLK_MUX_STAT1 S5PC1XX_CLKREG(0x1104)
> +
> +#define S5PC110_SWRESET S5PC1XX_CLKREG(0x2000)
> +
> +#define S5PC110_CLKSRC0_APLL_MASK (0x1<<0)
> +#define S5PC110_CLKSRC0_APLL_SHIFT (0)
> +#define S5PC110_CLKSRC0_MPLL_MASK (0x1<<4)
> +#define S5PC110_CLKSRC0_MPLL_SHIFT (4)
> +#define S5PC110_CLKSRC0_EPLL_MASK (0x1<<8)
> +#define S5PC110_CLKSRC0_EPLL_SHIFT (8)
> +#define S5PC110_CLKSRC0_VPLL_MASK (0x1<<12)
> +#define S5PC110_CLKSRC0_VPLL_SHIFT (12)
> +#define S5PC110_CLKSRC0_MUX200_MASK (0x1<<16)
> +#define S5PC110_CLKSRC0_MUX200_SHIFT (16)
> +#define S5PC110_CLKSRC0_MUX166_MASK (0x1<<20)
> +#define S5PC110_CLKSRC0_MUX166_SHIFT (20)
> +#define S5PC110_CLKSRC0_MUX133_MASK (0x1<<24)
> +#define S5PC110_CLKSRC0_MUX133_SHIFT (24)
> +#define S5PC110_CLKSRC0_ONENAND_MASK (0x1<<28)
> +#define S5PC110_CLKSRC0_ONENAND_SHIFT (28)
> +
> +#define S5PC110_CLKSRC1_HDMI_MASK (0x1<<0)
> +#define S5PC110_CLKSRC1_HDMI_SHIFT (0)
> +#define S5PC110_CLKSRC1_MIXER_MASK (0x7<<1)
> +#define S5PC110_CLKSRC1_MIXER_SHIFT (1)
> +#define S5PC110_CLKSRC1_DAC_MASK (0x1<<8)
> +#define S5PC110_CLKSRC1_DAC_SHIFT (8)
> +#define S5PC110_CLKSRC1_CAM0_MASK (0xf<<12)
> +#define S5PC110_CLKSRC1_CAM0_SHIFT (12)
> +#define S5PC110_CLKSRC1_CAM1_MASK (0xf<<16)
> +#define S5PC110_CLKSRC1_CAM1_SHIFT (16)
> +#define S5PC110_CLKSRC1_FIMD_MASK (0xf<<20)
> +#define S5PC110_CLKSRC1_FIMD_SHIFT (20)
> +#define S5PC110_CLKSRC1_CSIS_MASK (0xf<<24)
> +#define S5PC110_CLKSRC1_CSIS_SHIFT (24)
> +#define S5PC110_CLKSRC1_VPLLSRC_MASK (0x1<<28)
> +#define S5PC110_CLKSRC1_VPLLSRC_SHIFT (28)
> +
> +#define S5PC110_CLKSRC2_G3D_MASK (0x3<<0)
> +#define S5PC110_CLKSRC2_G3D_SHIFT (0)
> +#define S5PC110_CLKSRC2_MFC_MASK (0x3<<4)
> +#define S5PC110_CLKSRC2_MFC_SHIFT (4)
> +
> +#define S5PC110_CLKSRC3_MDNIE_MASK (0xf<<0)
> +#define S5PC110_CLKSRC3_MDNIE_SHIFT (0)
> +#define S5PC110_CLKSRC3_MDNIE_PWMCLK_MASK (0xf<<4)
> +#define S5PC110_CLKSRC3_MDNIE_PWMCLK_SHIFT (4)
> +#define S5PC110_CLKSRC3_FIMC0_LCLK_MASK (0xf<<12)
> +#define S5PC110_CLKSRC3_FIMC0_LCLK_SHIFT (12)
> +#define S5PC110_CLKSRC3_FIMC1_LCLK_MASK (0xf<<16)
> +#define S5PC110_CLKSRC3_FIMC1_LCLK_SHIFT (16)
> +#define S5PC110_CLKSRC3_FIMC2_LCLK_MASK (0xf<<20)
> +#define S5PC110_CLKSRC3_FIMC2_LCLK_SHIFT (20)
> +
> +/* CLKSRC4 */
> +#define S5PC110_CLKSRC4_MMC0_MASK (0xf<<0)
> +#define S5PC110_CLKSRC4_MMC0_SHIFT (0)
> +#define S5PC110_CLKSRC4_MMC1_MASK (0xf<<4)
> +#define S5PC110_CLKSRC4_MMC1_SHIFT (4)
> +#define S5PC110_CLKSRC4_MMC2_MASK (0xf<<8)
> +#define S5PC110_CLKSRC4_MMC2_SHIFT (8)
> +#define S5PC110_CLKSRC4_MMC3_MASK (0xf<<12)
> +#define S5PC110_CLKSRC4_MMC3_SHIFT (12)
> +#define S5PC110_CLKSRC4_UART0_MASK (0xf<<16)
> +#define S5PC110_CLKSRC4_UART0_SHIFT (16)
> +#define S5PC110_CLKSRC4_UART1_MASK (0xf<<20)
> +#define S5PC110_CLKSRC4_UART1_SHIFT (20)
> +#define S5PC110_CLKSRC4_UART2_MASK (0xf<<24)
> +#define S5PC110_CLKSRC4_UART2_SHIFT (24)
> +#define S5PC110_CLKSRC4_UART3_MASK (0xf<<28)
> +#define S5PC110_CLKSRC4_UART3_SHIFT (28)
> +
> +/* CLKSRC5 */
> +#define S5PC110_CLKSRC5_SPI0_MASK (0xf<<0)
> +#define S5PC110_CLKSRC5_SPI0_SHIFT (0)
> +#define S5PC110_CLKSRC5_SPI1_MASK (0xf<<4)
> +#define S5PC110_CLKSRC5_SPI1_SHIFT (4)
> +#define S5PC110_CLKSRC5_SPI2_MASK (0xf<<8)
> +#define S5PC110_CLKSRC5_SPI2_SHIFT (8)
> +#define S5PC110_CLKSRC5_PWM_MASK (0xf<<12)
> +#define S5PC110_CLKSRC5_PWM_SHIFT (12)
> +
> +/* CLKSRC6 */
> +#define S5PC110_CLKSRC6_AUDIO0_MASK (0xf<<0)
> +#define S5PC110_CLKSRC6_AUDIO0_SHIFT (0)
> +#define S5PC110_CLKSRC6_AUDIO1_MASK (0xf<<4)
> +#define S5PC110_CLKSRC6_AUDIO1_SHIFT (4)
> +#define S5PC110_CLKSRC6_AUDIO2_MASK (0xf<<8)
> +#define S5PC110_CLKSRC6_AUDIO2_SHIFT (4)
> +#define S5PC110_CLKSRC6_SPDIF_MASK (0x3<<12)
> +#define S5PC110_CLKSRC6_SPDIF_SHIFT (12)
> +#define S5PC110_CLKSRC6_HPM_MASK (0x1<<16)
> +#define S5PC110_CLKSRC6_HPM_SHIFT (16)
> +#define S5PC110_CLKSRC6_PWI_MASK (0xf<<20)
> +#define S5PC110_CLKSRC6_PWI_SHIFT (20)
> +#define S5PC110_CLKSRC6_ONEDRAM_MASK (0x3<<24)
> +#define S5PC110_CLKSRC6_ONEDRAM_SHIFT (24)
> +
> +#define S5PC110_CLKDIV0_APLL_MASK (0x7<<0)
> +#define S5PC110_CLKDIV0_APLL_SHIFT (0)
> +#define S5PC110_CLKDIV0_A2M_MASK (0x7<<4)
> +#define S5PC110_CLKDIV0_A2M_SHIFT (4)
> +#define S5PC110_CLKDIV0_HCLK_MSYS_MASK (0x7<<8)
> +#define S5PC110_CLKDIV0_HCLK_MSYS_SHIFT (8)
> +#define S5PC110_CLKDIV0_PCLK_MSYS_MASK (0x7<<12)
> +#define S5PC110_CLKDIV0_PCLK_MSYS_SHIFT (12)
> +#define S5PC110_CLKDIV0_HCLK_DSYS_MASK (0xf<<16)
> +#define S5PC110_CLKDIV0_HCLK_DSYS_SHIFT (16)
> +#define S5PC110_CLKDIV0_PCLK_DSYS_MASK (0x7<<20)
> +#define S5PC110_CLKDIV0_PCLK_DSYS_SHIFT (20)
> +#define S5PC110_CLKDIV0_HCLK_PSYS_MASK (0xf<<24)
> +#define S5PC110_CLKDIV0_HCLK_PSYS_SHIFT (24)
> +#define S5PC110_CLKDIV0_PCLK_PSYS_MASK (0x7<<28)
> +#define S5PC110_CLKDIV0_PCLK_PSYS_SHIFT (28)
> +
> +#define S5PC110_CLKDIV1_TBLK_MASK (0xf<<0)
> +#define S5PC110_CLKDIV1_TBLK_SHIFT (0)
> +#define S5PC110_CLKDIV1_FIMC_MASK (0xf<<8)
> +#define S5PC110_CLKDIV1_FIMC_SHIFT (8)
> +#define S5PC110_CLKDIV1_CAM0_MASK (0xf<<12)
> +#define S5PC110_CLKDIV1_CAM0_SHIFT (12)
> +#define S5PC110_CLKDIV1_CAM1_MASK (0xf<<16)
> +#define S5PC110_CLKDIV1_CAM1_SHIFT (16)
> +#define S5PC110_CLKDIV1_FIMD_MASK (0xf<<20)
> +#define S5PC110_CLKDIV1_FIMD_SHIFT (20)
> +#define S5PC110_CLKDIV1_CSIS_MASK (0xf<<28)
> +#define S5PC110_CLKDIV1_CSIS_SHIFT (28)
> +
> +#define S5PC110_CLKDIV2_G3D_MASK (0xf<<0)
> +#define S5PC110_CLKDIV2_G3D_SHIFT (0)
> +#define S5PC110_CLKDIV2_MFC_MASK (0xf<<4)
> +#define S5PC110_CLKDIV2_MFC_SHIFT (4)
> +
> +#define S5PC110_CLKDIV3_MDNIE_MASK (0xf<<0)
> +#define S5PC110_CLKDIV3_MDNIE_SHIFT (0)
> +#define S5PC110_CLKDIV3_MDNIE_PWM_MASK (0x7f<<4)
> +#define S5PC110_CLKDIV3_MDNIE_PWM_SHIFT (4)
> +#define S5PC110_CLKDIV3_FIMC0_LCLK_MASK (0xf<<12)
> +#define S5PC110_CLKDIV3_FIMC0_LCLK_SHIFT (12)
> +#define S5PC110_CLKDIV3_FIMC1_LCLK_MASK (0xf<<16)
> +#define S5PC110_CLKDIV3_FIMC1_LCLK_SHIFT (16)
> +#define S5PC110_CLKDIV3_FIMC2_LCLK_MASK (0xf<<20)
> +#define S5PC110_CLKDIV3_FIMC2_LCLK_SHIFT (20)
> +
> +#define S5PC110_CLKDIV4_MMC0_MASK (0xf<<0)
> +#define S5PC110_CLKDIV4_MMC0_SHIFT (0)
> +#define S5PC110_CLKDIV4_MMC1_MASK (0xf<<4)
> +#define S5PC110_CLKDIV4_MMC1_SHIFT (4)
> +#define S5PC110_CLKDIV4_MMC2_MASK (0xf<<8)
> +#define S5PC110_CLKDIV4_MMC2_SHIFT (8)
> +#define S5PC110_CLKDIV4_MMC3_MASK (0xf<<12)
> +#define S5PC110_CLKDIV4_MMC3_SHIFT (12)
> +#define S5PC110_CLKDIV4_UART0_MASK (0xf<<16)
> +#define S5PC110_CLKDIV4_UART0_SHIFT (16)
> +#define S5PC110_CLKDIV4_UART1_MASK (0xf<<20)
> +#define S5PC110_CLKDIV4_UART1_SHIFT (20)
> +#define S5PC110_CLKDIV4_UART2_MASK (0xf<<24)
> +#define S5PC110_CLKDIV4_UART2_SHIFT (24)
> +#define S5PC110_CLKDIV4_UART3_MASK (0xf<<28)
> +#define S5PC110_CLKDIV4_UART3_SHIFT (28)
> +
> +/* CLK_DIV5 */
> +#define S5PC110_CLKDIV5_SPI0_MASK (0xf<<0)
> +#define S5PC110_CLKDIV5_SPI0_SHIFT (0)
> +#define S5PC110_CLKDIV5_SPI1_MASK (0xf<<4)
> +#define S5PC110_CLKDIV5_SPI1_SHIFT (4)
> +#define S5PC110_CLKDIV5_SPI2_MASK (0xf<<8)
> +#define S5PC110_CLKDIV5_SPI2_SHIFT (8)
> +#define S5PC110_CLKDIV5_PWM_MASK (0xf<<120)
> +#define S5PC110_CLKDIV5_PWM_SHIFT (12)
> +
> +/* CLK_DIV6 */
> +#define S5PC110_CLKDIV6_AUDIO0_MASK (0xf<<0)
> +#define S5PC110_CLKDIV6_AUDIO0_SHIFT (0)
> +#define S5PC110_CLKDIV6_AUDIO1_MASK (0xf<<4)
> +#define S5PC110_CLKDIV6_AUDIO1_SHIFT (4)
> +#define S5PC110_CLKDIV6_AUDIO2_MASK (0xf<<8)
> +#define S5PC110_CLKDIV6_AUDIO2_SHIFT (8)
> +#define S5PC110_CLKDIV6_ONENAND_MASK (0x7<<12)
> +#define S5PC110_CLKDIV6_ONENAND_SHIFT (12)
> +#define S5PC110_CLKDIV6_COPY_MASK (0x7<<16)
> +#define S5PC110_CLKDIV6_COPY_SHIFT (16)
> +#define S5PC110_CLKDIV6_HPM_MASK (0x7<<20)
> +#define S5PC110_CLKDIV6_HPM_SHIFT (20)
> +#define S5PC110_CLKDIV6_PWI_MASK (0xf<<24)
> +#define S5PC110_CLKDIV6_PWI_SHIFT (24)
> +#define S5PC110_CLKDIV6_ONEDRAM_MASK (0xf<<28)
> +#define S5PC110_CLKDIV6_ONEDRAM_SHIFT (28)
> +
> +/* Clock Gate IP0 */
> +#define S5PC110_CLKGATE_IP0_DMC0 (1<<0)
> +#define S5PC110_CLKGATE_IP0_DMC1 (1<<1)
> +#define S5PC110_CLKGATE_IP0_MDMA (1<<2)
> +#define S5PC110_CLKGATE_IP0_PDMA0 (1<<3)
> +#define S5PC110_CLKGATE_IP0_PDMA1 (1<<4)
> +#define S5PC110_CLKGATE_IP0_IMEM (1<<5)
> +#define S5PC110_CLKGATE_IP0_G3D (1<<8)
> +#define S5PC110_CLKGATE_IP0_MFC (1<<16)
> +#define S5PC110_CLKGATE_IP0_FIMC0 (1<<24)
> +#define S5PC110_CLKGATE_IP0_FIMC1 (1<<25)
> +#define S5PC110_CLKGATE_IP0_FIMC2 (1<<26)
> +#define S5PC110_CLKGATE_IP0_JPEG (1<<28)
> +#define S5PC110_CLKGATE_IP0_ROTATOR (1<<29)
> +#define S5PC110_CLKGATE_IP0_IPC (1<<30)
> +#define S5PC110_CLKGATE_IP0_CSIS (1<<31)
> +
> +/* Clock Gate IP1 */
> +#define S5PC110_CLKGATE_IP1_FIMD (1<<0)
> +#define S5PC110_CLKGATE_IP1_MIE (1<<1)
> +#define S5PC110_CLKGATE_IP1_DSIM (1<<2)
> +#define S5PC110_CLKGATE_IP1_VP (1<<8)
> +#define S5PC110_CLKGATE_IP1_MIXER (1<<9)
> +#define S5PC110_CLKGATE_IP1_TVENC (1<<10)
> +#define S5PC110_CLKGATE_IP1_HDMI (1<<11)
> +#define S5PC110_CLKGATE_IP1_USBOTG (1<<16)
> +#define S5PC110_CLKGATE_IP1_USBHOST (1<<17)
> +#define S5PC110_CLKGATE_IP1_NANDXL (1<<24)
> +#define S5PC110_CLKGATE_IP1_CFCON (1<<25)
> +#define S5PC110_CLKGATE_IP1_SROMC (1<<26)
> +#define S5PC110_CLKGATE_IP1_NFCON (1<<28)
> +
> +/* Clock Gate IP2 */
> +#define S5PC110_CLKGATE_IP2_SECSS (1<<0)
> +#define S5PC110_CLKGATE_IP2_SDM (1<<1)
> +#define S5PC110_CLKGATE_IP2_CORESIGHT (1<<8)
> +#define S5PC110_CLKGATE_IP2_MODEM (1<<9)
> +#define S5PC110_CLKGATE_IP2_HOSTIF (1<<10)
> +#define S5PC110_CLKGATE_IP2_SECJTAG (1<<11)
> +#define S5PC110_CLKGATE_IP2_HSMMC0 (1<<16)
> +#define S5PC110_CLKGATE_IP2_HSMMC1 (1<<17)
> +#define S5PC110_CLKGATE_IP2_HSMMC2 (1<<18)
> +#define S5PC110_CLKGATE_IP2_HSMMC3 (1<<19)
> +#define S5PC110_CLKGATE_IP2_TSI (1<<20)
> +#define S5PC110_CLKGATE_IP2_VIC0 (1<<24)
> +#define S5PC110_CLKGATE_IP2_VIC1 (1<<25)
> +#define S5PC110_CLKGATE_IP2_VIC2 (1<<26)
> +#define S5PC110_CLKGATE_IP2_VIC3 (1<<27)
> +#define S5PC110_CLKGATE_IP2_TZIC0 (1<<28)
> +#define S5PC110_CLKGATE_IP2_TZIC1 (1<<29)
> +#define S5PC110_CLKGATE_IP2_TZIC2 (1<<30)
> +#define S5PC110_CLKGATE_IP2_TZIC3 (1<<31)
> +
> +/* Clock Gate IP3 */
> +#define S5PC110_CLKGATE_IP3_SPDIF (1<<0)
> +#define S5PC110_CLKGATE_IP3_AC97 (1<<1)
> +#define S5PC110_CLKGATE_IP3_I2S0 (1<<4)
> +#define S5PC110_CLKGATE_IP3_I2S1 (1<<5)
> +#define S5PC110_CLKGATE_IP3_I2S2 (1<<6)
> +#define S5PC110_CLKGATE_IP3_I2C0 (1<<7)
> +#define S5PC110_CLKGATE_IP3_I2C1 (1<<8)
> +#define S5PC110_CLKGATE_IP3_I2C2 (1<<9)
> +#define S5PC110_CLKGATE_IP3_I2C_HDMI_DDC (1<<10)
> +#define S5PC110_CLKGATE_IP3_I2C_HDMI_PHY (1<<11)
> +#define S5PC110_CLKGATE_IP3_SPI0 (1<<12)
> +#define S5PC110_CLKGATE_IP3_SPI1 (1<<13)
> +#define S5PC110_CLKGATE_IP3_SPI2 (1<<14)
> +#define S5PC110_CLKGATE_IP3_RTC (1<<15)
> +#define S5PC110_CLKGATE_IP3_SYSTIMER (1<<16)
> +#define S5PC110_CLKGATE_IP3_UART0 (1<<17)
> +#define S5PC110_CLKGATE_IP3_UART1 (1<<18)
> +#define S5PC110_CLKGATE_IP3_UART2 (1<<19)
> +#define S5PC110_CLKGATE_IP3_UART3 (1<<20)
> +#define S5PC110_CLKGATE_IP3_KEYIF (1<<21)
> +#define S5PC110_CLKGATE_IP3_WDT (1<<22)
> +#define S5PC110_CLKGATE_IP3_PWM (1<<23)
> +#define S5PC110_CLKGATE_IP3_TSADC (1<<24)
> +#define S5PC110_CLKGATE_IP3_GPIO (1<<26)
> +#define S5PC110_CLKGATE_IP3_SYSCON (1<<27)
> +#define S5PC110_CLKGATE_IP3_PCM0 (1<<28)
> +#define S5PC110_CLKGATE_IP3_PCM1 (1<<29)
> +#define S5PC110_CLKGATE_IP3_PCM2 (1<<30)
> +
> +/* Clock Gate IP4 */
> +#define S5PC110_CLKGATE_IP4_CHIP_ID (1<<0)
> +#define S5PC110_CLKGATE_IP4_IEM_IEC (1<<1)
> +#define S5PC110_CLKGATE_IP4_IEM_APC (1<<2)
> +#define S5PC110_CLKGATE_IP4_SECKEY (1<<3)
> +#define S5PC110_CLKGATE_IP4_TZPC0 (1<<5)
> +#define S5PC110_CLKGATE_IP4_TZPC1 (1<<6)
> +#define S5PC110_CLKGATE_IP4_TZPC2 (1<<7)
> +#define S5PC110_CLKGATE_IP4_TZPC3 (1<<8)
> +
> +#endif /* _PLAT_REGS_CLOCK_H */
> diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
> index 679e145..898cd82 100644
> --- a/arch/arm/plat-s5pc1xx/Kconfig
> +++ b/arch/arm/plat-s5pc1xx/Kconfig
> @@ -50,6 +50,11 @@ config CPU_S5PC110_INIT
> help
> Common initialisation code for the S5PC1XX
>
> +config CPU_S5PC110_CLOCK
> + bool
> + help
> + Common clock support code for the S5PC1XX
> +
> # platform specific device setup
>
> endif
> diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
> index 3e8ebf1..b03a983 100644
> --- a/arch/arm/plat-s5pc1xx/Makefile
> +++ b/arch/arm/plat-s5pc1xx/Makefile
> @@ -21,6 +21,7 @@ obj-y += gpiolib.o
> obj-$(CONFIG_CPU_S5PC100_INIT) += s5pc100-init.o
> obj-$(CONFIG_CPU_S5PC100_CLOCK) += s5pc100-plls.o s5pc100-clocks.o
> obj-$(CONFIG_CPU_S5PC110_INIT) += s5pc110-init.o
> +obj-$(CONFIG_CPU_S5PC110_CLOCK) += s5pc110-plls.o s5pc110-clocks.o
>
> # Device setup
>
> diff --git a/arch/arm/plat-s5pc1xx/include/plat/pll.h b/arch/arm/plat-s5pc1xx/include/plat/pll.h
> index 21afef1..7380d16 100644
> --- a/arch/arm/plat-s5pc1xx/include/plat/pll.h
> +++ b/arch/arm/plat-s5pc1xx/include/plat/pll.h
> @@ -22,7 +22,7 @@
> #include <asm/div64.h>
>
> static inline unsigned long s5pc1xx_get_pll(unsigned long baseclk,
> - u32 pllcon)
> + u32 pllcon, int sub)
> {
> u32 mdiv, pdiv, sdiv;
> u64 fvco = baseclk;
> @@ -32,7 +32,11 @@ static inline unsigned long s5pc1xx_get_pll(unsigned long baseclk,
> sdiv = (pllcon >> S5P_PLL_SDIV_SHIFT) & S5P_PLL_SDIV_MASK;
>
> fvco *= mdiv;
> - do_div(fvco, (pdiv << sdiv));
> +
> + if (sub)
> + do_div(fvco, (pdiv << (sdiv - 1)));
> + else
> + do_div(fvco, (pdiv << sdiv));
>
> return (unsigned long)fvco;
> }
> diff --git a/arch/arm/plat-s5pc1xx/include/plat/s5pc110.h b/arch/arm/plat-s5pc1xx/include/plat/s5pc110.h
> index 93c623b..86d4952 100644
> --- a/arch/arm/plat-s5pc1xx/include/plat/s5pc110.h
> +++ b/arch/arm/plat-s5pc1xx/include/plat/s5pc110.h
> @@ -26,6 +26,17 @@ extern void s5pc110_init_irq(void);
> extern void s5pc110_register_clocks(void);
> extern void s5pc110_setup_clocks(void);
>
> +extern struct clk clk_hpll;
> +extern struct clk clk_hd0;
> +extern struct clk clk_pd0;
> +extern struct clk clk_54m;
> +extern struct clk clk_30m;
> +extern int s5pc110_ip0_ctrl(struct clk *clk, int enable);
> +extern int s5pc110_ip1_ctrl(struct clk *clk, int enable);
> +extern int s5pc110_ip2_ctrl(struct clk *clk, int enable);
> +extern int s5pc110_ip3_ctrl(struct clk *clk, int enable);
> +extern int s5pc110_ip4_ctrl(struct clk *clk, int enable);
> +
> #else
>
> #define s5pc110_map_io NULL
> diff --git a/arch/arm/plat-s5pc1xx/s5pc100-plls.c b/arch/arm/plat-s5pc1xx/s5pc100-plls.c
> index 45f073e..b7559f8 100644
> --- a/arch/arm/plat-s5pc1xx/s5pc100-plls.c
> +++ b/arch/arm/plat-s5pc1xx/s5pc100-plls.c
> @@ -1050,10 +1050,10 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
>
> printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
>
> - apll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_APLL_CON));
> - mpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_MPLL_CON));
> - epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_EPLL_CON));
> - hpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_HPLL_CON));
> + apll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_APLL_CON), 0);
> + mpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_MPLL_CON), 0);
> + epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_EPLL_CON), 0);
> + hpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_HPLL_CON), 0);
>
> printk(KERN_INFO "S5PC100: Apll=%ld.%03ld Mhz, Mpll=%ld.%03ld Mhz"
> ", Epll=%ld.%03ld Mhz, Hpll=%ld.%03ld Mhz\n",
> diff --git a/arch/arm/plat-s5pc1xx/s5pc110-clocks.c b/arch/arm/plat-s5pc1xx/s5pc110-clocks.c
> new file mode 100644
> index 0000000..456bd5e
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/s5pc110-clocks.c
> @@ -0,0 +1,254 @@
> +/* linux/arch/arm/plat-s5pc1xx/s5pc110-clocks.c
> + *
> + * Copyright 2009 Samsung Electronics Co.
> + *
> + * S5PC110 - Clocks support
> + *
> + * Based on plat-s3c64xx/clock.c
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/ioport.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/map.h>
> +
> +#include <plat/regs-clock.h>
> +#include <plat/devs.h>
> +#include <plat/clock.h>
> +
> +struct clk clk_27m = {
> + .name = "clk_27m",
> + .id = -1,
> + .rate = 27000000,
> +};
> +
> +struct clk clk_48m = {
> + .name = "clk_48m",
> + .id = -1,
> + .rate = 48000000,
> +};
> +
> +struct clk clk_54m = {
> + .name = "clk_54m",
> + .id = -1,
> + .rate = 54000000,
> +};
> +
> +struct clk clk_30m = {
> + .name = "clk_30m",
> + .id = -1,
> + .rate = 30000000,
> +};
> +
> +static int s5pc1xx_clk_gate(void __iomem *reg, struct clk *clk, int enable)
> +{
> + unsigned int ctrlbit = clk->ctrlbit;
> + u32 con;
> +
> + con = __raw_readl(reg);
> + if (enable)
> + con |= ctrlbit;
> + else
> + con &= ~ctrlbit;
> + __raw_writel(con, reg);
> +
> + return 0;
> +}
> +
> +int s5pc110_ip0_ctrl(struct clk *clk, int enable)
> +{
> + return s5pc1xx_clk_gate(S5PC110_CLKGATE_IP0, clk, enable);
> +}
> +
> +int s5pc110_ip1_ctrl(struct clk *clk, int enable)
> +{
> + return s5pc1xx_clk_gate(S5PC110_CLKGATE_IP1, clk, enable);
> +}
> +
> +int s5pc110_ip2_ctrl(struct clk *clk, int enable)
> +{
> + return s5pc1xx_clk_gate(S5PC110_CLKGATE_IP2, clk, enable);
> +}
> +
> +int s5pc110_ip3_ctrl(struct clk *clk, int enable)
> +{
> + return s5pc1xx_clk_gate(S5PC110_CLKGATE_IP3, clk, enable);
> +}
> +
> +int s5pc110_ip4_ctrl(struct clk *clk, int enable)
> +{
> + return s5pc1xx_clk_gate(S5PC110_CLKGATE_IP4, clk, enable);
> +}
> +
> +extern struct clk clk_dout_hclkm;
> +extern struct clk clk_dout_hclkd;
> +extern struct clk clk_dout_hclkp;
> +extern struct clk clk_dout_pclkd;
> +extern struct clk clk_dout_pclkp;
> +
> +static struct clk s5pc110_init_clocks_disable[] = {
> + {
> + .name = "keypad",
> + .id = -1,
> + .parent = &clk_dout_pclkp,
> + .enable = s5pc110_ip3_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP3_KEYIF,
> + },
> +};
> +
> +static struct clk s5pc110_init_clocks[] = {
> + /* IP0 */
> + {
> + .name = "mfc",
> + .id = -1,
> + .parent = NULL,
> + .enable = s5pc110_ip0_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP0_MFC,
> + },
> +
> + /* IP1 */
> + {
> + .name = "lcd",
> + .id = -1,
> + .parent = &clk_dout_hclkd,
> + .enable = s5pc110_ip1_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP1_FIMD,
> + }, {
> + .name = "otg",
> + .id = -1,
> + .parent = &clk_dout_hclkp,
> + .enable = s5pc110_ip1_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP1_USBOTG,
> + },
> +
> + /* IP2 */
> + {
> + .name = "hsmmc",
> + .id = 0,
> + .parent = &clk_dout_hclkp,
> + .enable = s5pc110_ip2_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP2_HSMMC0,
> + }, {
> + .name = "hsmmc",
> + .id = 1,
> + .parent = &clk_dout_hclkp,
> + .enable = s5pc110_ip2_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP2_HSMMC1,
> + }, {
> + .name = "hsmmc",
> + .id = 2,
> + .parent = &clk_dout_hclkp,
> + .enable = s5pc110_ip2_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP2_HSMMC2,
> + }, {
> + .name = "hsmmc",
> + .id = 3,
> + .parent = &clk_dout_hclkp,
> + .enable = s5pc110_ip2_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP2_HSMMC3,
> + },
> + /* IP3 */
> + {
> + .name = "iis",
> + .id = 0,
> + .parent = &clk_dout_pclkp,
> + .enable = s5pc110_ip3_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP3_I2S0,
> + }, {
> + .name = "iis",
> + .id = 1,
> + .parent = &clk_dout_pclkp,
> + .enable = s5pc110_ip3_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP3_I2S1,
> + }, {
> + .name = "iis",
> + .id = 2,
> + .parent = &clk_dout_pclkp,
> + .enable = s5pc110_ip3_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP3_I2S2,
> + }, {
> + .name = "i2c",
> + .id = 0,
> + .parent = &clk_dout_pclkp,
> + .enable = s5pc110_ip3_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP3_I2C0,
> + }, {
> + .name = "i2c",
> + .id = 1,
> + .parent = &clk_dout_pclkd,
> + .enable = s5pc110_ip3_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP3_I2C1,
> + }, {
> + .name = "i2c",
> + .id = 2,
> + .parent = &clk_dout_pclkp,
> + .enable = s5pc110_ip3_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP3_I2C2,
> + }, {
> + .name = "timers",
> + .id = -1,
> + .parent = &clk_dout_pclkp,
> + .enable = s5pc110_ip3_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP3_PWM,
> + }, {
> + .name = "adc",
> + .id = -1,
> + .parent = &clk_dout_pclkp,
> + .enable = s5pc110_ip3_ctrl,
> + .ctrlbit = S5PC110_CLKGATE_IP3_TSADC,
> + },
> +};
> +
> +static struct clk *clks[] __initdata = {
> + &clk_ext,
> + &clk_epll,
> + &clk_27m,
> + &clk_30m,
> + &clk_48m,
> + &clk_54m,
> +};
> +
> +void __init s5pc1xx_register_clocks(void)
> +{
> + struct clk *clkp;
> + int ret;
> + int ptr;
> + int size;
> +
> + s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
> +
> + clkp = s5pc110_init_clocks;
> + size = ARRAY_SIZE(s5pc110_init_clocks);
> +
> + for (ptr = 0; ptr < size; ptr++, clkp++) {
> + ret = s3c24xx_register_clock(clkp);
> + if (ret < 0) {
> + printk(KERN_ERR "Failed to register clock %s (%d)\n",
> + clkp->name, ret);
> + }
> + }
> +
> + clkp = s5pc110_init_clocks_disable;
> + size = ARRAY_SIZE(s5pc110_init_clocks_disable);
> +
> + for (ptr = 0; ptr < size; ptr++, clkp++) {
> + ret = s3c24xx_register_clock(clkp);
> + if (ret < 0) {
> + printk(KERN_ERR "Failed to register clock %s (%d)\n",
> + clkp->name, ret);
> + }
> +
> + (clkp->enable)(clkp, 0);
> + }
> +
> + s3c_pwmclk_init();
> +}
> diff --git a/arch/arm/plat-s5pc1xx/s5pc110-plls.c b/arch/arm/plat-s5pc1xx/s5pc110-plls.c
> new file mode 100644
> index 0000000..05ac43c
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/s5pc110-plls.c
> @@ -0,0 +1,1288 @@
> +/*
> + * linux/arch/arm/plat-s5pc1xx/s5pc110-plls.c
> + *
> + * Copyright 2009 Samsung Electronics, Co.
> + * Minkyu Kang <mk7.kang at samsung.com>
> + *
> + * S5PC110 based common clock support
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/list.h>
> +#include <linux/errno.h>
> +#include <linux/err.h>
> +#include <linux/clk.h>
> +#include <linux/sysdev.h>
> +#include <linux/io.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/map.h>
> +
> +#include <plat/cpu-freq.h>
> +
> +#include <plat/regs-clock.h>
> +#include <plat/clock.h>
> +#include <plat/cpu.h>
> +#include <plat/pll.h>
> +#include <plat/devs.h>
> +#include <plat/s5pc1xx.h>
> +
> +static struct clk clk_ext_xtal_mux = {
> + .name = "ext_xtal",
> + .id = -1,
> +};
> +
> +#define clk_fin_apll clk_ext_xtal_mux
> +#define clk_fin_mpll clk_ext_xtal_mux
> +#define clk_fin_epll clk_ext_xtal_mux
> +#define clk_fin_vpll clk_ext_xtal_mux
> +#define clk_hdmi_phy clk_ext_xtal_mux
> +
> +#define clk_fout_mpll clk_mpll
> +#define clk_hdmi_27m clk_27m
> +#define clk_usbphy0 clk_30m
> +#define clk_usbphy1 clk_48m
> +
> +static struct clk clk_usb_xtal = {
> + .name = "usb_xtal",
> + .id = -1,
> +};
> +
> +static struct clk clk_pcm_cd0 = {
> + .name = "pcm_cdclk0",
> + .id = -1,
> +};
> +
> +static struct clk clk_pcm_cd1 = {
> + .name = "pcm_cdclk1",
> + .id = -1,
> +};
> +
> +static struct clk clk_iis_cd1 = {
> + .name = "iis_cdclk1",
> + .id = -1,
> +};
> +
> +struct clk_sources {
> + unsigned int nr_sources;
> + struct clk **sources;
> +};
> +
> +struct clksrc_clk {
> + struct clk clk;
> + unsigned int mask;
> + unsigned int shift;
> +
> + struct clk_sources *sources;
> +
> + unsigned int divider_shift;
> + void __iomem *reg_divider;
> + void __iomem *reg_source;
> +};
> +
> +/* APLL */
> +static struct clk clk_fout_apll = {
> + .name = "fout_apll",
> + .id = -1,
> +};
> +
> +static struct clk *clk_src_apll_list[] = {
> + [0] = &clk_fin_apll,
> + [1] = &clk_fout_apll,
> +};
> +
> +static struct clk_sources clk_src_apll = {
> + .sources = clk_src_apll_list,
> + .nr_sources = ARRAY_SIZE(clk_src_apll_list),
> +};
> +
> +static struct clksrc_clk clk_mout_apll = {
> + .clk = {
> + .name = "mout_apll",
> + .id = -1,
> + },
> + .shift = S5PC110_CLKSRC0_APLL_SHIFT,
> + .mask = S5PC110_CLKSRC0_APLL_MASK,
> + .sources = &clk_src_apll,
> + .reg_source = S5PC110_CLKSRC0,
> +};
> +
> +/* MPLL */
> +static struct clk *clk_src_mpll_list[] = {
> + [0] = &clk_fin_mpll,
> + [1] = &clk_fout_mpll,
> +};
> +
> +static struct clk_sources clk_src_mpll = {
> + .sources = clk_src_mpll_list,
> + .nr_sources = ARRAY_SIZE(clk_src_mpll_list),
> +};
> +
> +static struct clksrc_clk clk_mout_mpll = {
> + .clk = {
> + .name = "mout_mpll",
> + .id = -1,
> + },
> + .shift = S5PC110_CLKSRC0_MPLL_SHIFT,
> + .mask = S5PC110_CLKSRC0_MPLL_MASK,
> + .sources = &clk_src_mpll,
> + .reg_source = S5PC110_CLKSRC0,
> +};
> +
> +static int s5pc110_default_enable(struct clk *clk, int enable)
> +{
> + return 0;
> +}
> +
> +/* EPLL */
> +static struct clk clk_fout_epll = {
> + .name = "fout_epll",
> + .id = -1,
> + .enable = s5pc110_default_enable,
> +};
> +
> +static struct clk *clk_src_epll_list[] = {
> + [0] = &clk_fin_epll,
> + [1] = &clk_fout_epll,
> +};
> +
> +static struct clk_sources clk_src_epll = {
> + .sources = clk_src_epll_list,
> + .nr_sources = ARRAY_SIZE(clk_src_epll_list),
> +};
> +
> +static struct clksrc_clk clk_mout_epll = {
> + .clk = {
> + .name = "mout_epll",
> + .id = -1,
> + },
> + .shift = S5PC110_CLKSRC0_EPLL_SHIFT,
> + .mask = S5PC110_CLKSRC0_EPLL_MASK,
> + .sources = &clk_src_epll,
> + .reg_source = S5PC110_CLKSRC0,
> +};
> +
> +/* VPLLSRC */
> +static struct clk *clk_src_vpllsrc_list[] = {
> + [0] = &clk_fin_vpll,
> + [1] = &clk_hdmi_27m,
> +};
> +
> +static struct clk_sources clk_src_vpllsrc = {
> + .sources = clk_src_vpllsrc_list,
> + .nr_sources = ARRAY_SIZE(clk_src_vpllsrc_list),
> +};
> +
> +static struct clksrc_clk clk_mout_vpllsrc = {
> + .clk = {
> + .name = "mout_vpllsrc",
> + .id = -1,
> + },
> + .shift = S5PC110_CLKSRC1_VPLLSRC_SHIFT,
> + .mask = S5PC110_CLKSRC1_VPLLSRC_MASK,
> + .sources = &clk_src_vpllsrc,
> + .reg_source = S5PC110_CLKSRC1,
> +};
> +
> +/* VPLL */
> +static struct clk clk_fout_vpll = {
> + .name = "fout_vpll",
> + .id = -1,
> +};
> +
> +static struct clk *clk_src_vpll_list[] = {
> + [0] = &clk_mout_vpllsrc.clk,
> + [1] = &clk_fout_vpll,
> +};
> +
> +static struct clk_sources clk_src_vpll = {
> + .sources = clk_src_vpll_list,
> + .nr_sources = ARRAY_SIZE(clk_src_vpll_list),
> +};
> +
> +static struct clksrc_clk clk_mout_vpll = {
> + .clk = {
> + .name = "mout_vpll",
> + .id = -1,
> + },
> + .shift = S5PC110_CLKSRC0_VPLL_SHIFT,
> + .mask = S5PC110_CLKSRC0_VPLL_MASK,
> + .sources = &clk_src_vpll,
> + .reg_source = S5PC110_CLKSRC0,
> +};
> +
> +/* Dout A2M */
> +static unsigned long s5pc110_clk_dout_a2m_get_rate(struct clk *clk)
> +{
> + unsigned long rate = clk_get_rate(clk->parent);
> + unsigned int ratio;
> +
> + ratio = __raw_readl(S5PC110_CLKDIV0) & S5PC110_CLKDIV0_A2M_MASK;
> + ratio >>= S5PC110_CLKDIV0_A2M_SHIFT;
> +
> + return rate / (ratio + 1);
> +}
> +
> +static struct clk clk_dout_a2m = {
> + .name = "dout_a2m",
> + .id = -1,
> + .parent = &clk_mout_apll.clk,
> + .get_rate = s5pc110_clk_dout_a2m_get_rate,
> +};
> +
> +/* HPM */
> +static struct clk *clk_src_hpm_list[] = {
> + [0] = &clk_mout_apll.clk,
> + [1] = &clk_mout_mpll.clk,
> +};
> +
> +static struct clk_sources clk_src_hpm = {
> + .sources = clk_src_hpm_list,
> + .nr_sources = ARRAY_SIZE(clk_src_hpm_list),
> +};
> +
> +static struct clksrc_clk clk_mout_hpm = {
> + .clk = {
> + .name = "mout_hpm",
> + .id = -1,
> + },
> + .shift = S5PC110_CLKSRC6_HPM_SHIFT,
> + .mask = S5PC110_CLKSRC6_HPM_MASK,
> + .sources = &clk_src_hpm,
> + .reg_source = S5PC110_CLKSRC6,
> +};
> +
> +/* MSYS */
> +static struct clk *clk_src_msys_list[] = {
> + [0] = &clk_mout_apll.clk,
> + [1] = &clk_mout_mpll.clk,
> +};
> +
> +static struct clk_sources clk_src_msys = {
> + .sources = clk_src_msys_list,
> + .nr_sources = ARRAY_SIZE(clk_src_msys_list),
> +};
> +
> +static struct clksrc_clk clk_mout_msys = {
> + .clk = {
> + .name = "mout_msys",
> + .id = -1,
> + },
> + .shift = S5PC110_CLKSRC0_MUX200_SHIFT,
> + .mask = S5PC110_CLKSRC0_MUX200_MASK,
> + .sources = &clk_src_msys,
> + .reg_source = S5PC110_CLKSRC0,
> +};
> +
> +/* DSYS */
> +static struct clk *clk_src_dsys_list[] = {
> + [0] = &clk_mout_mpll.clk,
> + [1] = &clk_dout_a2m,
> +};
> +
> +static struct clk_sources clk_src_dsys = {
> + .sources = clk_src_dsys_list,
> + .nr_sources = ARRAY_SIZE(clk_src_dsys_list),
> +};
> +
> +struct clksrc_clk clk_mout_dsys = {
> + .clk = {
> + .name = "mout_dsys",
> + .id = -1,
> + },
> + .shift = S5PC110_CLKSRC0_MUX166_SHIFT,
> + .mask = S5PC110_CLKSRC0_MUX166_MASK,
> + .sources = &clk_src_dsys,
> + .reg_source = S5PC110_CLKSRC0,
> +};
> +
> +/* PSYS */
> +static struct clk *clk_src_psys_list[] = {
> + [0] = &clk_mout_mpll.clk,
> + [1] = &clk_dout_a2m,
> +};
> +
> +static struct clk_sources clk_src_psys = {
> + .sources = clk_src_psys_list,
> + .nr_sources = ARRAY_SIZE(clk_src_psys_list),
> +};
> +
> +static struct clksrc_clk clk_mout_psys = {
> + .clk = {
> + .name = "mout_psys",
> + .id = -1,
> + },
> + .shift = S5PC110_CLKSRC0_MUX133_SHIFT,
> + .mask = S5PC110_CLKSRC0_MUX133_MASK,
> + .sources = &clk_src_psys,
> + .reg_source = S5PC110_CLKSRC0,
> +};
> +
> +/* Dout COPY */
> +static unsigned long s5pc110_clk_dout_copy_get_rate(struct clk *clk)
> +{
> + unsigned long rate = clk_get_rate(clk->parent);
> + unsigned int ratio;
> +
> + ratio = __raw_readl(S5PC110_CLKDIV6) & S5PC110_CLKDIV6_COPY_MASK;
> + ratio >>= S5PC110_CLKDIV6_COPY_SHIFT;
> +
> + return rate / (ratio + 1);
> +}
> +
> +static struct clk clk_dout_copy = {
> + .name = "dout_copy",
> + .id = -1,
> + .parent = &clk_mout_hpm.clk,
> + .get_rate = s5pc110_clk_dout_copy_get_rate,
> +};
> +
> +/* Dout HPM */
> +static unsigned long s5pc110_clk_dout_hpm_get_rate(struct clk *clk)
> +{
> + unsigned long rate = clk_get_rate(clk->parent);
> + unsigned int ratio;
> +
> + ratio = __raw_readl(S5PC110_CLKDIV6) & S5PC110_CLKDIV6_HPM_MASK;
> + ratio >>= S5PC110_CLKDIV6_HPM_SHIFT;
> +
> + return rate / (ratio + 1);
> +}
> +
> +static struct clk clk_dout_hpm = {
> + .name = "dout_hpm",
> + .id = -1,
> + .parent = &clk_dout_copy,
> + .get_rate = s5pc110_clk_dout_hpm_get_rate,
> +};
> +
> +/* Dout APLL - ARMCLK */
> +static unsigned long s5pc110_clk_dout_apll_get_rate(struct clk *clk)
> +{
> + unsigned long rate = clk_get_rate(clk->parent);
> + unsigned int ratio;
> +
> + ratio = __raw_readl(S5PC110_CLKDIV0) & S5PC110_CLKDIV0_APLL_MASK;
> + ratio >>= S5PC110_CLKDIV0_APLL_SHIFT;
> +
> + return rate / (ratio + 1);
> +}
> +
> +static struct clk clk_dout_apll = {
> + .name = "dout_apll",
> + .id = -1,
> + .parent = &clk_mout_msys.clk,
> + .get_rate = s5pc110_clk_dout_apll_get_rate,
> +};
> +
> +/* Dout HCLKM - ACLK200, HCLK_MSYS */
> +static unsigned long s5pc110_clk_dout_hclkm_get_rate(struct clk *clk)
> +{
> + unsigned long rate = clk_get_rate(clk->parent);
> + unsigned int ratio;
> +
> + ratio = __raw_readl(S5PC110_CLKDIV0) & S5PC110_CLKDIV0_HCLK_MSYS_MASK;
> + ratio >>= S5PC110_CLKDIV0_HCLK_MSYS_SHIFT;
> +
> + return rate / (ratio + 1);
> +}
> +
> +struct clk clk_dout_hclkm = {
> + .name = "dout_hclkm",
> + .id = -1,
> + .parent = &clk_dout_apll,
> + .get_rate = s5pc110_clk_dout_hclkm_get_rate,
> +};
> +
> +/* Dout PCLKM - PCLK_MSYS */
> +static unsigned long s5pc110_clk_dout_pclkm_get_rate(struct clk *clk)
> +{
> + unsigned long rate = clk_get_rate(clk->parent);
> + unsigned int ratio;
> +
> + ratio = __raw_readl(S5PC110_CLKDIV0) & S5PC110_CLKDIV0_PCLK_MSYS_MASK;
> + ratio >>= S5PC110_CLKDIV0_HCLK_PSYS_SHIFT;
> +
> + return rate / (ratio + 1);
> +}
> +
> +struct clk clk_dout_pclkm = {
> + .name = "dout_pclkm",
> + .id = -1,
> + .parent = &clk_dout_hclkm,
> + .get_rate = s5pc110_clk_dout_pclkm_get_rate,
> +};
> +
> +/* Dout IMEM - HCLK100 */
> +static unsigned long s5pc110_clk_dout_imem_get_rate(struct clk *clk)
> +{
> + unsigned long rate = clk_get_rate(clk->parent);
> + return rate / 2;
> +}
> +
> +static struct clk clk_dout_imem = {
> + .name = "dout_imem",
> + .id = -1,
> + .parent = &clk_dout_hclkm,
> + .get_rate = s5pc110_clk_dout_imem_get_rate,
> +};
> +
> +/* Dout HCLKD - HCLK_DSYS */
> +static unsigned long s5pc110_clk_dout_hclkd_get_rate(struct clk *clk)
> +{
> + unsigned long rate;
> + unsigned int ratio;
> +
> + rate = clk_get_rate(clk->parent);
> + ratio = __raw_readl(S5PC110_CLKDIV0) & S5PC110_CLKDIV0_HCLK_DSYS_MASK;
> + ratio >>= S5PC110_CLKDIV0_HCLK_DSYS_SHIFT;
> +
> + return rate / (ratio + 1);
> +}
> +
> +struct clk clk_dout_hclkd = {
> + .name = "dout_hclkd",
> + .id = -1,
> + .parent = &clk_mout_dsys.clk,
> + .get_rate = s5pc110_clk_dout_hclkd_get_rate,
> +};
> +
> +/* Dout PCLKD - PCLK_DSYS */
> +static unsigned long s5pc110_clk_dout_pclkd_get_rate(struct clk *clk)
> +{
> + unsigned long rate = clk_get_rate(clk->parent);
> + unsigned int ratio;
> +
> + ratio = __raw_readl(S5PC110_CLKDIV0) & S5PC110_CLKDIV0_PCLK_DSYS_MASK;
> + ratio >>= S5PC110_CLKDIV0_PCLK_DSYS_SHIFT;
> +
> + return rate / (ratio + 1);
> +}
> +
> +struct clk clk_dout_pclkd = {
> + .name = "dout_pclkd",
> + .id = -1,
> + .parent = &clk_dout_hclkd,
> + .get_rate = s5pc110_clk_dout_pclkd_get_rate,
> +};
> +
> +/* Dout FIMC - SCLK_FIMC */
> +static unsigned long s5pc110_clk_dout_fimc_get_rate(struct clk *clk)
> +{
> + unsigned long rate = clk_get_rate(clk->parent);
> + unsigned int ratio;
> +
> + ratio = __raw_readl(S5PC110_CLKDIV1) & S5PC110_CLKDIV1_FIMC_MASK;
> + ratio >>= S5PC110_CLKDIV1_FIMC_SHIFT;
> +
> + return rate / (ratio + 1);
> +}
> +
> +static struct clk clk_dout_fimc = {
> + .name = "dout_fimc",
> + .id = -1,
> + .parent = &clk_mout_dsys.clk,
> + .get_rate = s5pc110_clk_dout_fimc_get_rate,
> +};
> +
> +/* Dout HCLKP - ARMATCLK, HCLK_PSYS */
> +static unsigned long s5pc110_clk_dout_hclkp_get_rate(struct clk *clk)
> +{
> + unsigned long rate = clk_get_rate(clk->parent);
> + unsigned int ratio;
> +
> + ratio = __raw_readl(S5PC110_CLKDIV0) & S5PC110_CLKDIV0_HCLK_PSYS_MASK;
> + ratio >>= S5PC110_CLKDIV0_HCLK_PSYS_SHIFT;
> +
> + return rate / (ratio + 1);
> +}
> +
> +struct clk clk_dout_hclkp = {
> + .name = "dout_hclkp",
> + .id = -1,
> + .parent = &clk_mout_psys.clk,
> + .get_rate = s5pc110_clk_dout_hclkp_get_rate,
> +};
> +
> +/* Dout PCLKD - PCLK_DSYS */
> +static unsigned long s5pc110_clk_dout_pclkp_get_rate(struct clk *clk)
> +{
> + unsigned long rate = clk_get_rate(clk->parent);
> + unsigned int ratio;
> +
> + ratio = __raw_readl(S5PC110_CLKDIV0) & S5PC110_CLKDIV0_PCLK_PSYS_MASK;
> + ratio >>= S5PC110_CLKDIV0_PCLK_PSYS_SHIFT;
> +
> + return rate / (ratio + 1);
> +}
> +
> +struct clk clk_dout_pclkp = {
> + .name = "dout_pclkp",
> + .id = -1,
> + .parent = &clk_dout_hclkp,
> + .get_rate = s5pc110_clk_dout_pclkp_get_rate,
> +};
> +
> +/* FLASH */
> +static struct clk *clk_src_onenand_list[] = {
> + [0] = &clk_dout_hclkd,
> + [1] = &clk_dout_hclkp,
> +};
> +
> +static struct clk_sources clk_src_onenand = {
> + .sources = clk_src_onenand_list,
> + .nr_sources = ARRAY_SIZE(clk_src_onenand_list),
> +};
> +
> +static struct clksrc_clk clk_mout_onenand = {
> + .clk = {
> + .name = "mout_onenand",
> + .id = -1,
> + },
> + .shift = S5PC110_CLKSRC0_ONENAND_SHIFT,
> + .mask = S5PC110_CLKSRC0_ONENAND_MASK,
> + .sources = &clk_src_onenand,
> + .reg_source = S5PC110_CLKSRC0,
> +};
> +
> +/* Dout FLASH - SCLK_ONENAND */
> +static unsigned long s5pc110_clk_dout_onenand_get_rate(struct clk *clk)
> +{
> + unsigned long rate = clk_get_rate(clk->parent);
> + unsigned int ratio;
> +
> + ratio = __raw_readl(S5PC110_CLKDIV6) & S5PC110_CLKDIV6_ONENAND_MASK;
> + ratio >>= S5PC110_CLKDIV6_ONENAND_SHIFT;
> +
> + return rate / (ratio + 1);
> +}
> +
> +static struct clk clk_dout_onenand = {
> + .name = "dout_onenand",
> + .id = -1,
> + .parent = &clk_mout_onenand.clk,
> + .get_rate = s5pc110_clk_dout_onenand_get_rate,
> +};
> +
> +/* Dout FLASH2 - SCLK_ONENAND2 */
> +static unsigned long s5pc110_clk_dout_onenand2_get_rate(struct clk *clk)
> +{
> + unsigned long rate = clk_get_rate(clk->parent);
> + return rate / 2;
> +}
> +
> +static struct clk clk_dout_onenand2 = {
> + .name = "dout_onenand2",
> + .id = -1,
> + .parent = &clk_dout_onenand,
> + .get_rate = s5pc110_clk_dout_onenand2_get_rate,
> +};
> +
> +/* Peripherals */
> +static inline struct clksrc_clk *to_clksrc(struct clk *clk)
> +{
> + return container_of(clk, struct clksrc_clk, clk);
> +}
> +
> +static unsigned long s5pc110_getrate_clksrc(struct clk *clk)
> +{
> + struct clksrc_clk *sclk = to_clksrc(clk);
> + unsigned long rate = clk_get_rate(clk->parent);
> + u32 clkdiv = __raw_readl(sclk->reg_divider);
> +
> + clkdiv >>= sclk->divider_shift;
> + clkdiv &= 0xf;
> + clkdiv++;
> +
> + rate /= clkdiv;
> + return rate;
> +}
> +
> +static int s5pc110_setrate_clksrc(struct clk *clk, unsigned long rate)
> +{
> + struct clksrc_clk *sclk = to_clksrc(clk);
> + void __iomem *reg = sclk->reg_divider;
> + unsigned int div;
> + u32 val;
> +
> + rate = clk_round_rate(clk, rate);
> + div = clk_get_rate(clk->parent) / rate;
> + if (div > 16)
> + return -EINVAL;
> +
> + val = __raw_readl(reg);
> + val &= ~(0xf << sclk->divider_shift);
> + val |= (div - 1) << sclk->divider_shift;
> + __raw_writel(val, reg);
> +
> + return 0;
> +}
> +
> +static int s5pc110_setparent_clksrc(struct clk *clk, struct clk *parent)
> +{
> + struct clksrc_clk *sclk = to_clksrc(clk);
> + struct clk_sources *srcs = sclk->sources;
> + u32 clksrc = __raw_readl(sclk->reg_source);
> + int src_nr = -1;
> + int ptr;
> +
> + for (ptr = 0; ptr < srcs->nr_sources; ptr++) {
> + if (srcs->sources[ptr] == parent) {
> + src_nr = ptr;
> + break;
> + }
> + }
> +
> + if (src_nr >= 0) {
> + clksrc &= ~sclk->mask;
> + clksrc |= src_nr << sclk->shift;
> +
> + __raw_writel(clksrc, sclk->reg_source);
> + return 0;
> + }
> +
> + return -EINVAL;
> +}
> +
> +static unsigned long s5pc110_roundrate_clksrc(struct clk *clk,
> + unsigned long rate)
> +{
> + unsigned long parent_rate = clk_get_rate(clk->parent);
> + int div;
> +
> + if (rate > parent_rate)
> + rate = parent_rate;
> + else {
> + div = parent_rate / rate;
> +
> + if (div == 0)
> + div = 1;
> + if (div > 16)
> + div = 16;
> +
> + rate = parent_rate / div;
> + }
> +
> + return rate;
> +}
> +
> +static struct clk *clkset_default_list[] = {
> + &clk_fin_apll,
> + &clk_usb_xtal,
> + &clk_hdmi_27m,
> + &clk_usbphy0,
> + &clk_usbphy1,
> + &clk_hdmi_phy,
> + &clk_mout_mpll.clk,
> + &clk_mout_epll.clk,
> + &clk_mout_vpll.clk,
> +};
> +
> +
> +/* CAM */
> +static struct clk_sources clkset_cam = {
> + .sources = clkset_default_list,
> + .nr_sources = ARRAY_SIZE(clkset_default_list),
> +};
> +
> +static struct clksrc_clk clk_cam0 = {
> + .clk = {
> + .name = "cam",
> + .id = 0,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC1_CAM0_SHIFT,
> + .mask = S5PC110_CLKSRC1_CAM0_MASK,
> + .sources = &clkset_cam,
> + .divider_shift = S5PC110_CLKDIV1_CAM0_SHIFT,
> + .reg_divider = S5PC110_CLKDIV1,
> + .reg_source = S5PC110_CLKSRC1,
> +};
> +
> +static struct clksrc_clk clk_cam1 = {
> + .clk = {
> + .name = "cam",
> + .id = 1,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC1_CAM1_SHIFT,
> + .mask = S5PC110_CLKSRC1_CAM1_MASK,
> + .sources = &clkset_cam,
> + .divider_shift = S5PC110_CLKDIV1_CAM1_SHIFT,
> + .reg_divider = S5PC110_CLKDIV1,
> + .reg_source = S5PC110_CLKSRC1,
> +};
> +
> +/* FIMD */
> +static struct clk_sources clkset_fimd = {
> + .sources = clkset_default_list,
> + .nr_sources = ARRAY_SIZE(clkset_default_list),
> +};
> +
> +static struct clksrc_clk clk_fimd = {
> + .clk = {
> + .name = "fimd",
> + .id = -1,
> + .ctrlbit = S5PC110_CLKGATE_IP1_FIMD,
> + .enable = s5pc110_ip1_ctrl,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC1_FIMD_SHIFT,
> + .mask = S5PC110_CLKSRC1_FIMD_MASK,
> + .sources = &clkset_fimd,
> + .divider_shift = S5PC110_CLKDIV1_FIMD_SHIFT,
> + .reg_divider = S5PC110_CLKDIV1,
> + .reg_source = S5PC110_CLKSRC1,
> +};
> +
> +/* MMC */
> +static struct clk_sources clkset_mmc = {
> + .sources = clkset_default_list,
> + .nr_sources = ARRAY_SIZE(clkset_default_list),
> +};
> +
> +static struct clksrc_clk clk_mmc0 = {
> + .clk = {
> + .name = "mmc-bus",
> + .id = 0,
> + .ctrlbit = S5PC110_CLKGATE_IP2_HSMMC0,
> + .enable = s5pc110_ip2_ctrl,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC4_MMC0_SHIFT,
> + .mask = S5PC110_CLKSRC4_MMC0_MASK,
> + .sources = &clkset_mmc,
> + .divider_shift = S5PC110_CLKDIV4_MMC0_SHIFT,
> + .reg_divider = S5PC110_CLKDIV4,
> + .reg_source = S5PC110_CLKSRC4,
> +};
> +
> +static struct clksrc_clk clk_mmc1 = {
> + .clk = {
> + .name = "mmc-bus",
> + .id = 1,
> + .ctrlbit = S5PC110_CLKGATE_IP2_HSMMC1,
> + .enable = s5pc110_ip2_ctrl,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC4_MMC1_SHIFT,
> + .mask = S5PC110_CLKSRC4_MMC1_MASK,
> + .sources = &clkset_mmc,
> + .divider_shift = S5PC110_CLKDIV4_MMC1_SHIFT,
> + .reg_divider = S5PC110_CLKDIV4,
> + .reg_source = S5PC110_CLKSRC4,
> +};
> +
> +static struct clksrc_clk clk_mmc2 = {
> + .clk = {
> + .name = "mmc-bus",
> + .id = 2,
> + .ctrlbit = S5PC110_CLKGATE_IP2_HSMMC2,
> + .enable = s5pc110_ip2_ctrl,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC4_MMC2_SHIFT,
> + .mask = S5PC110_CLKSRC4_MMC2_MASK,
> + .sources = &clkset_mmc,
> + .divider_shift = S5PC110_CLKDIV4_MMC2_SHIFT,
> + .reg_divider = S5PC110_CLKDIV4,
> + .reg_source = S5PC110_CLKSRC4,
> +};
> +
> +static struct clksrc_clk clk_mmc3 = {
> + .clk = {
> + .name = "mmc-bus",
> + .id = 3,
> + .ctrlbit = S5PC110_CLKGATE_IP2_HSMMC3,
> + .enable = s5pc110_ip2_ctrl,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC4_MMC3_SHIFT,
> + .mask = S5PC110_CLKSRC4_MMC3_MASK,
> + .sources = &clkset_mmc,
> + .divider_shift = S5PC110_CLKDIV4_MMC3_SHIFT,
> + .reg_divider = S5PC110_CLKDIV4,
> + .reg_source = S5PC110_CLKSRC4,
> +};
> +
> +/* AUDIO0 */
> +static struct clk_sources clkset_audio0 = {
> + .sources = clkset_default_list,
> + .nr_sources = ARRAY_SIZE(clkset_default_list),
> +};
> +
> +static struct clksrc_clk clk_audio0 = {
> + .clk = {
> + .name = "audio-bus",
> + .id = 0,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC6_AUDIO0_SHIFT,
> + .mask = S5PC110_CLKSRC6_AUDIO0_MASK,
> + .sources = &clkset_audio0,
> + .divider_shift = S5PC110_CLKDIV6_AUDIO0_SHIFT,
> + .reg_divider = S5PC110_CLKDIV6,
> + .reg_source = S5PC110_CLKSRC6,
> +};
> +
> +/* AUDIO1 */
> +static struct clk *clkset_audio1_list[] = {
> + &clk_iis_cd1,
> + &clk_pcm_cd1,
> + &clk_hdmi_27m,
> + &clk_usbphy0,
> + &clk_usbphy1,
> + &clk_hdmi_phy,
> + &clk_mout_mpll.clk,
> + &clk_mout_epll.clk,
> + &clk_mout_vpll.clk,
> +};
> +
> +static struct clk_sources clkset_audio1 = {
> + .sources = clkset_audio1_list,
> + .nr_sources = ARRAY_SIZE(clkset_audio1_list),
> +};
> +
> +static struct clksrc_clk clk_audio1 = {
> + .clk = {
> + .name = "audio-bus",
> + .id = 1,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC6_AUDIO1_SHIFT,
> + .mask = S5PC110_CLKSRC6_AUDIO1_MASK,
> + .sources = &clkset_audio1,
> + .divider_shift = S5PC110_CLKDIV6_AUDIO1_SHIFT,
> + .reg_divider = S5PC110_CLKDIV6,
> + .reg_source = S5PC110_CLKSRC6,
> +};
> +
> +/* AUDIO2 */
> +static struct clk *clkset_audio2_list[] = {
> + &clk_fin_apll,
> + &clk_pcm_cd0,
> + &clk_hdmi_27m,
> + &clk_usbphy0,
> + &clk_usbphy1,
> + &clk_hdmi_phy,
> + &clk_mout_mpll.clk,
> + &clk_mout_epll.clk,
> + &clk_mout_vpll.clk,
> +};
> +
> +static struct clk_sources clkset_audio2 = {
> + .sources = clkset_audio2_list,
> + .nr_sources = ARRAY_SIZE(clkset_audio2_list),
> +};
> +
> +static struct clksrc_clk clk_audio2 = {
> + .clk = {
> + .name = "audio-bus",
> + .id = 2,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC6_AUDIO2_SHIFT,
> + .mask = S5PC110_CLKSRC6_AUDIO2_MASK,
> + .sources = &clkset_audio2,
> + .divider_shift = S5PC110_CLKDIV6_AUDIO2_SHIFT,
> + .reg_divider = S5PC110_CLKDIV6,
> + .reg_source = S5PC110_CLKSRC6,
> +};
> +
> +/* FIMC */
> +static struct clk_sources clkset_fimc = {
> + .sources = clkset_default_list,
> + .nr_sources = ARRAY_SIZE(clkset_default_list),
> +};
> +
> +static struct clksrc_clk clk_fimc0 = {
> + .clk = {
> + .name = "fimc",
> + .id = 0,
> + .ctrlbit = S5PC110_CLKGATE_IP0_FIMC0,
> + .enable = s5pc110_ip0_ctrl,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC3_FIMC0_LCLK_SHIFT,
> + .mask = S5PC110_CLKSRC3_FIMC0_LCLK_MASK,
> + .sources = &clkset_fimc,
> + .divider_shift = S5PC110_CLKDIV3_FIMC0_LCLK_SHIFT,
> + .reg_divider = S5PC110_CLKDIV3,
> + .reg_source = S5PC110_CLKSRC3,
> +};
> +
> +static struct clksrc_clk clk_fimc1 = {
> + .clk = {
> + .name = "fimc",
> + .id = 1,
> + .ctrlbit = S5PC110_CLKGATE_IP0_FIMC1,
> + .enable = s5pc110_ip0_ctrl,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC3_FIMC1_LCLK_SHIFT,
> + .mask = S5PC110_CLKSRC3_FIMC1_LCLK_MASK,
> + .sources = &clkset_fimc,
> + .divider_shift = S5PC110_CLKDIV3_FIMC1_LCLK_SHIFT,
> + .reg_divider = S5PC110_CLKDIV3,
> + .reg_source = S5PC110_CLKSRC3,
> +};
> +
> +static struct clksrc_clk clk_fimc2 = {
> + .clk = {
> + .name = "fimc",
> + .id = 2,
> + .ctrlbit = S5PC110_CLKGATE_IP0_FIMC2,
> + .enable = s5pc110_ip0_ctrl,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC3_FIMC2_LCLK_SHIFT,
> + .mask = S5PC110_CLKSRC3_FIMC2_LCLK_MASK,
> + .sources = &clkset_fimc,
> + .divider_shift = S5PC110_CLKDIV3_FIMC2_LCLK_SHIFT,
> + .reg_divider = S5PC110_CLKDIV3,
> + .reg_source = S5PC110_CLKSRC3,
> +};
> +
> +/* UART */
> +static struct clk_sources clkset_uart = {
> + .sources = clkset_default_list,
> + .nr_sources = ARRAY_SIZE(clkset_default_list),
> +};
> +
> +static struct clksrc_clk clk_uart0 = {
> + .clk = {
> + .name = "uart",
> + .id = 0,
> + .ctrlbit = S5PC110_CLKGATE_IP3_UART0,
> + .enable = s5pc110_ip3_ctrl,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC4_UART0_SHIFT,
> + .mask = S5PC110_CLKSRC4_UART0_MASK,
> + .sources = &clkset_uart,
> + .divider_shift = S5PC110_CLKDIV4_UART0_SHIFT,
> + .reg_divider = S5PC110_CLKDIV4,
> + .reg_source = S5PC110_CLKSRC4,
> +};
> +
> +static struct clksrc_clk clk_uart1 = {
> + .clk = {
> + .name = "uart",
> + .id = 1,
> + .ctrlbit = S5PC110_CLKGATE_IP3_UART1,
> + .enable = s5pc110_ip3_ctrl,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC4_UART1_SHIFT,
> + .mask = S5PC110_CLKSRC4_UART1_MASK,
> + .sources = &clkset_uart,
> + .divider_shift = S5PC110_CLKDIV4_UART1_SHIFT,
> + .reg_divider = S5PC110_CLKDIV4,
> + .reg_source = S5PC110_CLKSRC4,
> +};
> +
> +static struct clksrc_clk clk_uart2 = {
> + .clk = {
> + .name = "uart",
> + .id = 2,
> + .ctrlbit = S5PC110_CLKGATE_IP3_UART2,
> + .enable = s5pc110_ip3_ctrl,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC4_UART2_SHIFT,
> + .mask = S5PC110_CLKSRC4_UART2_MASK,
> + .sources = &clkset_uart,
> + .divider_shift = S5PC110_CLKDIV4_UART2_SHIFT,
> + .reg_divider = S5PC110_CLKDIV4,
> + .reg_source = S5PC110_CLKSRC4,
> +};
> +
> +static struct clksrc_clk clk_uart3 = {
> + .clk = {
> + .name = "uart",
> + .id = 3,
> + .ctrlbit = S5PC110_CLKGATE_IP3_UART3,
> + .enable = s5pc110_ip3_ctrl,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC4_UART3_SHIFT,
> + .mask = S5PC110_CLKSRC4_UART3_MASK,
> + .sources = &clkset_uart,
> + .divider_shift = S5PC110_CLKDIV4_UART3_SHIFT,
> + .reg_divider = S5PC110_CLKDIV4,
> + .reg_source = S5PC110_CLKSRC4,
> +};
> +
> +/* PWM */
> +static struct clk_sources clkset_pwm = {
> + .sources = clkset_default_list,
> + .nr_sources = ARRAY_SIZE(clkset_default_list),
> +};
> +
> +static struct clksrc_clk clk_pwm = {
> + .clk = {
> + .name = "pwm",
> + .id = -1,
> + .ctrlbit = S5PC110_CLKGATE_IP3_PWM,
> + .enable = s5pc110_ip3_ctrl,
> + .set_parent = s5pc110_setparent_clksrc,
> + .get_rate = s5pc110_getrate_clksrc,
> + .set_rate = s5pc110_setrate_clksrc,
> + .round_rate = s5pc110_roundrate_clksrc,
> + },
> + .shift = S5PC110_CLKSRC5_PWM_SHIFT,
> + .mask = S5PC110_CLKSRC5_PWM_MASK,
> + .sources = &clkset_pwm,
> + .divider_shift = S5PC110_CLKDIV5_PWM_SHIFT,
> + .reg_divider = S5PC110_CLKDIV5,
> + .reg_source = S5PC110_CLKSRC5,
> +};
> +
> +/* Clock initialisation code */
> +static struct clksrc_clk *init_parents[] = {
> + &clk_mout_apll,
> + &clk_mout_mpll,
> + &clk_mout_epll,
> + &clk_mout_vpllsrc,
> + &clk_mout_vpll,
> + &clk_mout_hpm,
> + &clk_mout_msys,
> + &clk_mout_dsys,
> + &clk_mout_psys,
> + &clk_mout_onenand,
> + &clk_cam0,
> + &clk_cam1,
> + &clk_fimd,
> + &clk_mmc0,
> + &clk_mmc1,
> + &clk_mmc2,
> + &clk_mmc3,
> + &clk_audio0,
> + &clk_audio1,
> + &clk_audio2,
> + &clk_fimc0,
> + &clk_fimc1,
> + &clk_fimc2,
> + &clk_uart0,
> + &clk_uart1,
> + &clk_uart2,
> + &clk_uart3,
> + &clk_pwm,
> +};
> +
> +static void __init_or_cpufreq s5pc110_set_clksrc(struct clksrc_clk *clk)
> +{
> + struct clk_sources *srcs = clk->sources;
> + u32 clksrc = __raw_readl(clk->reg_source);
> +
> + clksrc &= clk->mask;
> + clksrc >>= clk->shift;
> +
> + if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
> + printk(KERN_ERR "%s: bad source %d\n",
> + clk->clk.name, clksrc);
> + return;
> + }
> +
> + clk->clk.parent = srcs->sources[clksrc];
> +
> + printk(KERN_INFO "%s: source is %s (%d), rate is %ld.%03ld MHz\n",
> + clk->clk.name, clk->clk.parent->name, clksrc,
> + print_mhz(clk_get_rate(&clk->clk)));
> +}
> +
> +#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
> +
> +void __init_or_cpufreq s5pc110_setup_clocks(void)
> +{
> + struct clk *xtal_clk;
> + unsigned long xtal;
> + unsigned long armclk;
> + unsigned long hclk_msys, hclk_dsys, hclk_psys;
> + unsigned long pclk_msys, pclk_dsys, pclk_psys;
> + unsigned long apll, mpll, epll, vpll;
> + unsigned int clkdiv0;
> + unsigned int ptr;
> +
> + printk(KERN_DEBUG "%s: registering clocks\n", __func__);
> +
> + clkdiv0 = __raw_readl(S5PC110_CLKDIV0);
> +
> + printk(KERN_DEBUG "%s: clkdiv0 = %08x\n", __func__, clkdiv0);
> +
> + xtal_clk = clk_get(NULL, "xtal");
> + BUG_ON(IS_ERR(xtal_clk));
> +
> + xtal = clk_get_rate(xtal_clk);
> + clk_put(xtal_clk);
> +
> + printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
> +
> + apll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC110_APLL_CON), 1);
> + mpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC110_MPLL_CON), 0);
> + epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC110_EPLL_CON), 0);
> + vpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC110_VPLL_CON), 0);
> +
> + printk(KERN_INFO "S5PC110: Apll=%ld.%03ld Mhz, Mpll=%ld.%03ld Mhz"
> + ", Epll=%ld.%03ld Mhz, Vpll=%ld.%03ld Mhz\n",
> + print_mhz(apll), print_mhz(mpll),
> + print_mhz(epll), print_mhz(vpll));
> +
> + armclk = apll / GET_DIV(clkdiv0, S5PC110_CLKDIV0_APLL);
> + hclk_msys = armclk / GET_DIV(clkdiv0, S5PC110_CLKDIV0_HCLK_MSYS);
> + hclk_dsys = mpll / GET_DIV(clkdiv0, S5PC110_CLKDIV0_HCLK_DSYS);
> + hclk_psys = mpll / GET_DIV(clkdiv0, S5PC110_CLKDIV0_HCLK_PSYS);
> + pclk_msys = hclk_msys / GET_DIV(clkdiv0, S5PC110_CLKDIV0_PCLK_MSYS);
> + pclk_dsys = hclk_dsys / GET_DIV(clkdiv0, S5PC110_CLKDIV0_PCLK_DSYS);
> + pclk_psys = hclk_psys / GET_DIV(clkdiv0, S5PC110_CLKDIV0_PCLK_PSYS);
> +
> + printk(KERN_INFO "S5PC110: ARMCLK=%ld.%03ld MHz\n"
> + "HCLK: Msys %ld.%03ld MHz, Dsys %ld.%03ld MHz, Psys %ld.%03ld MHz\n"
> + "PCLK: Msys %ld.%03ld MHz, Dsys %ld.%03ld MHz, Psys %ld.%03ld MHz\n",
> + print_mhz(armclk),
> + print_mhz(hclk_msys), print_mhz(hclk_dsys), print_mhz(hclk_psys),
> + print_mhz(pclk_msys), print_mhz(pclk_dsys), print_mhz(pclk_psys));
> +
> + clk_ext_xtal_mux.rate = xtal;
> + clk_fout_apll.rate = apll;
> + clk_fout_mpll.rate = mpll;
> + clk_fout_epll.rate = epll;
> + clk_fout_vpll.rate = vpll;
> +
> + clk_dout_hclkm.rate = hclk_msys;
> + clk_dout_hclkd.rate = hclk_dsys;
> + clk_dout_hclkp.rate = hclk_psys;
> + clk_dout_pclkm.rate = pclk_msys;
> + clk_dout_pclkd.rate = pclk_dsys;
> + clk_dout_pclkp.rate = pclk_psys;
> +
> + clk_h.rate = hclk_psys;
> + clk_p.rate = pclk_psys;
> + clk_f.rate = armclk;
> +
> + for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
> + s5pc110_set_clksrc(init_parents[ptr]);
> +}
> +
> +static struct clk *clks[] __initdata = {
> + &clk_ext_xtal_mux,
> + &clk_usb_xtal,
> + &clk_pcm_cd0,
> + &clk_pcm_cd1,
> + &clk_iis_cd1,
> + &clk_mout_apll.clk,
> + &clk_mout_mpll.clk,
> + &clk_mout_epll.clk,
> + &clk_mout_vpllsrc.clk,
> + &clk_mout_vpll.clk,
> + &clk_dout_a2m,
> + &clk_mout_hpm.clk,
> + &clk_mout_msys.clk,
> + &clk_mout_dsys.clk,
> + &clk_mout_psys.clk,
> + &clk_dout_copy,
> + &clk_dout_hpm,
> + &clk_dout_apll,
> + &clk_dout_hclkm,
> + &clk_dout_pclkm,
> + &clk_dout_hclkd,
> + &clk_dout_pclkd,
> + &clk_dout_hclkp,
> + &clk_dout_pclkp,
> + &clk_dout_fimc,
> + &clk_dout_imem,
> + &clk_mout_onenand.clk,
> + &clk_dout_onenand,
> + &clk_dout_onenand2,
> + &clk_cam0.clk,
> + &clk_cam1.clk,
> + &clk_fimd.clk,
> + &clk_mmc0.clk,
> + &clk_mmc1.clk,
> + &clk_mmc2.clk,
> + &clk_mmc3.clk,
> + &clk_audio0.clk,
> + &clk_audio1.clk,
> + &clk_audio2.clk,
> + &clk_fimc0.clk,
> + &clk_fimc1.clk,
> + &clk_fimc2.clk,
> + &clk_uart0.clk,
> + &clk_uart1.clk,
> + &clk_uart2.clk,
> + &clk_uart3.clk,
> + &clk_pwm.clk,
> +};
> +
> +void __init s5pc110_register_clocks(void)
> +{
> + struct clk *clkp;
> + int ret;
> + int ptr;
> +
> + for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
> + clkp = clks[ptr];
> + ret = s3c24xx_register_clock(clkp);
> + if (ret < 0) {
> + printk(KERN_ERR "Failed to register clock %s (%d)\n",
> + clkp->name, ret);
> + }
> + }
> +}
> --
> 1.6.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
--
Ben
Q: What's a light-year?
A: One-third less calories than a regular year.
More information about the linux-arm-kernel
mailing list