Marek Szyprowski wrote:
> 
> From: Tomasz Stanislawski <[email protected]>
> 
> This patch adds clocks and definitions needed by TV driver
> infrastructure for Samsung Exynos4 platform.
> 
> Signed-off-by: Tomasz Stanislawski <[email protected]>
> Signed-off-by: Kyungmin Park <[email protected]>
> Reviewed-by: Marek Szyprowski <[email protected]>
> Signed-off-by: Marek Szyprowski <[email protected]>
> ---
>  arch/arm/mach-exynos4/clock.c                   |  205
> +++++++++++++++++++++++
>  arch/arm/mach-exynos4/cpu.c                     |    4 +
>  arch/arm/mach-exynos4/include/mach/irqs.h       |    4 +-
>  arch/arm/mach-exynos4/include/mach/map.h        |   26 +++
>  arch/arm/mach-exynos4/include/mach/regs-clock.h |    1 +
>  arch/arm/mach-exynos4/include/mach/regs-pmu.h   |    6 +
>  6 files changed, 245 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
> index b5e6d9d..f61a82d 100644
> --- a/arch/arm/mach-exynos4/clock.c
> +++ b/arch/arm/mach-exynos4/clock.c
> @@ -83,6 +83,11 @@ static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int
enable)
>       return s5p_gatectrl(S5P_CLKGATE_IP_MFC, clk, enable);
>  }
> 
> +static int exynos4_clksrc_mask_tv_ctrl(struct clk *clk, int enable)
> +{
> +     return s5p_gatectrl(S5P_CLKSRC_MASK_TV, clk, enable);
> +}
> +
>  static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
>  {
>       return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
> @@ -123,6 +128,16 @@ static int exynos4_clk_ip_perir_ctrl(struct clk *clk,
int
> enable)
>       return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
>  }
> 
> +static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
> +{
> +     return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
> +}
> +
> +static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
> +{
> +     return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
> +}
> +
>  /* Core list of CMU_CPU side */
> 
>  static struct clksrc_clk clk_mout_apll = {
> @@ -449,6 +464,36 @@ static struct clk init_clocks_off[] = {
>               .enable         = exynos4_clk_ip_fsys_ctrl,
>               .ctrlbit        = (1 << 9),
>       }, {
> +             .name           = "dac",
> +             .devname        = "s5p-sdo",
> +             .enable         = exynos4_clk_ip_tv_ctrl,
> +             .ctrlbit        = (1 << 2),
> +     }, {
> +             .name           = "mixer",
> +             .devname        = "s5p-mixer",
> +             .enable         = exynos4_clk_ip_tv_ctrl,
> +             .ctrlbit        = (1 << 1),
> +     }, {
> +             .name           = "vp",
> +             .devname        = "s5p-mixer",
> +             .enable         = exynos4_clk_ip_tv_ctrl,
> +             .ctrlbit        = (1 << 0),
> +     }, {
> +             .name           = "hdmi",
> +             .devname        = "s5p-hdmi",
> +             .enable         = exynos4_clk_ip_tv_ctrl,
> +             .ctrlbit        = (1 << 3),
> +     }, {
> +             .name           = "hdmiphy",
> +             .devname        = "s5p-hdmi",
> +             .enable         = exynos4_clk_hdmiphy_ctrl,
> +             .ctrlbit        = (1 << 0),
> +     }, {
> +             .name           = "dacphy",
> +             .devname        = "s5p-sdo",
> +             .enable         = exynos4_clk_dac_ctrl,
> +             .ctrlbit        = (1 << 0),
> +     }, {
>               .name           = "sata",
>               .parent         = &clk_aclk_133.clk,
>               .enable         = exynos4_clk_ip_fsys_ctrl,
> @@ -788,6 +833,82 @@ static struct clksrc_sources clkset_mout_mfc = {
>       .nr_sources     = ARRAY_SIZE(clkset_mout_mfc_list),
>  };
> 
> +static struct clk *clkset_sclk_dac_list[] = {
> +     [0] = &clk_sclk_vpll.clk,
> +     [1] = &clk_sclk_hdmiphy,
> +};
> +
> +static struct clksrc_sources clkset_sclk_dac = {
> +     .sources        = clkset_sclk_dac_list,
> +     .nr_sources     = ARRAY_SIZE(clkset_sclk_dac_list),
> +};
> +
> +static struct clksrc_clk clk_sclk_dac = {
> +     .clk            = {
> +             .name           = "sclk_dac",
> +             .enable         = exynos4_clksrc_mask_tv_ctrl,
> +             .ctrlbit        = (1 << 8),
> +     },
> +     .sources = &clkset_sclk_dac,
> +     .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 8, .size = 1 },
> +};
> +
> +static struct clksrc_clk clk_sclk_pixel = {
> +     .clk            = {
> +             .name           = "sclk_pixel",
> +             .parent = &clk_sclk_vpll.clk,
> +     },
> +     .reg_div = { .reg = S5P_CLKDIV_TV, .shift = 0, .size = 4 },
> +};
> +
> +static struct clk *clkset_sclk_hdmi_list[] = {
> +     [0] = &clk_sclk_pixel.clk,
> +     [1] = &clk_sclk_hdmiphy,
> +};
> +
> +static struct clksrc_sources clkset_sclk_hdmi = {
> +     .sources        = clkset_sclk_hdmi_list,
> +     .nr_sources     = ARRAY_SIZE(clkset_sclk_hdmi_list),
> +};
> +
> +static struct clksrc_clk clk_sclk_hdmi = {
> +     .clk            = {
> +             .name           = "sclk_hdmi",
> +             .enable         = exynos4_clksrc_mask_tv_ctrl,
> +             .ctrlbit        = (1 << 0),
> +     },
> +     .sources = &clkset_sclk_hdmi,
> +     .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 0, .size = 1 },
> +};
> +
> +static struct clk *clkset_sclk_mixer_list[] = {
> +     [0] = &clk_sclk_dac.clk,
> +     [1] = &clk_sclk_hdmi.clk,
> +};
> +
> +static struct clksrc_sources clkset_sclk_mixer = {
> +     .sources        = clkset_sclk_mixer_list,
> +     .nr_sources     = ARRAY_SIZE(clkset_sclk_mixer_list),
> +};
> +
> +static struct clksrc_clk clk_sclk_mixer = {
> +     .clk            = {
> +             .name           = "sclk_mixer",
> +             .enable         = exynos4_clksrc_mask_tv_ctrl,
> +             .ctrlbit        = (1 << 4),
> +     },
> +     .sources = &clkset_sclk_mixer,
> +     .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 4, .size = 1 },
> +};
> +
> +static struct clksrc_clk *sclk_tv[] = {
> +     &clk_sclk_dac,
> +     &clk_sclk_pixel,
> +     &clk_sclk_hdmi,
> +     &clk_sclk_mixer,
> +     NULL,
> +};
> +
>  static struct clksrc_clk clk_dout_mmc0 = {
>       .clk            = {
>               .name           = "dout_mmc0",
> @@ -1129,6 +1250,81 @@ static struct clk_ops exynos4_fout_apll_ops = {
>       .get_rate = exynos4_fout_apll_get_rate,
>  };
> 
> +struct vpll_div_data {
> +     u32 rate;
> +     u32 pdiv;
> +     u32 mdiv;
> +     u32 sdiv;
> +     u32 k;
> +     u32 mfr;
> +     u32 mrr;
> +     u32 vsel;
> +
> +};
> +
> +static struct vpll_div_data vpll_div[] = {
> +     {  54000000, 3, 53, 3, 1024, 0, 17, 0 },
> +     { 108000000, 3, 53, 2, 1024, 0, 17, 0 },
> +};
> +
> +static unsigned long exynos4_vpll_get_rate(struct clk *clk)
> +{
> +     return clk->rate;
> +}

Please refer to my reply on s5pv210/clock.c.

> +
> +static int exynos4_vpll_set_rate(struct clk *clk, unsigned long rate)
> +{
> +     unsigned int vpll_con0, vpll_con1;
> +     unsigned int i;
> +
> +     /* Return if nothing changed */
> +     if (clk->rate == rate)
> +             return 0;
> +
> +     vpll_con0 = __raw_readl(S5P_VPLL_CON0);
> +     vpll_con0 &= ~(0x1 << 27 |                                      \
> +                     PLL90XX_MDIV_MASK << PLL90XX_MDIV_SHIFT |       \
> +                     PLL90XX_PDIV_MASK << PLL90XX_PDIV_SHIFT |       \
> +                     PLL90XX_SDIV_MASK << PLL90XX_SDIV_SHIFT);
> +
> +     vpll_con1 = __raw_readl(S5P_VPLL_CON1);
> +     vpll_con1 &= ~(0x1f << 24 |     \
> +                     0x3f << 16 |    \
> +                     0xfff << 0);
> +
> +     for (i = 0; i < ARRAY_SIZE(vpll_div); i++) {
> +             if (vpll_div[i].rate == rate) {
> +                     vpll_con0 |= vpll_div[i].vsel << 27;
> +                     vpll_con0 |= vpll_div[i].pdiv << PLL90XX_PDIV_SHIFT;
> +                     vpll_con0 |= vpll_div[i].mdiv << PLL90XX_MDIV_SHIFT;
> +                     vpll_con0 |= vpll_div[i].sdiv << PLL90XX_SDIV_SHIFT;
> +
> +                     vpll_con1 |= vpll_div[i].mrr << 24;
> +                     vpll_con1 |= vpll_div[i].mfr << 16;
> +                     vpll_con1 |= vpll_div[i].k << 0;
> +                     break;
> +             }
> +     }
> +
> +     if (i == ARRAY_SIZE(vpll_div)) {
> +             printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
> +                             __func__);
> +             return -EINVAL;
> +     }
> +
> +     __raw_writel(vpll_con0, S5P_VPLL_CON0);
> +     __raw_writel(vpll_con1, S5P_VPLL_CON1);
> +
Same.

> +     clk->rate = rate;
> +
> +     return 0;
> +}
Same.

> +
> +static struct clk_ops exynos4_vpll_ops = {
> +     .get_rate = exynos4_vpll_get_rate,
> +     .set_rate = exynos4_vpll_set_rate,
> +};
Same...

> +
>  void __init_or_cpufreq exynos4_setup_clocks(void)
>  {
>       struct clk *xtal_clk;
> @@ -1171,6 +1367,7 @@ void __init_or_cpufreq exynos4_setup_clocks(void)
>       clk_fout_apll.ops = &exynos4_fout_apll_ops;
>       clk_fout_mpll.rate = mpll;
>       clk_fout_epll.rate = epll;
> +     clk_fout_vpll.ops = &exynos4_vpll_ops;
>       clk_fout_vpll.rate = vpll;
> 
>       printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld
> V=%ld",
> @@ -1199,6 +1396,10 @@ void __init_or_cpufreq exynos4_setup_clocks(void)
> 
>  static struct clk *clks[] __initdata = {
>       /* Nothing here yet */
> +     &clk_sclk_hdmi27m,
> +     &clk_sclk_hdmiphy,
> +     &clk_sclk_usbphy0,
> +     &clk_sclk_usbphy1,
>  };
> 
>  void __init exynos4_register_clocks(void)
> @@ -1210,6 +1411,10 @@ void __init exynos4_register_clocks(void)
>       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
>               s3c_register_clksrc(sysclks[ptr], 1);
> 
> +     /* register TV clocks */
> +     for (ptr = 0; sclk_tv[ptr]; ++ptr)
> +             s3c_register_clksrc(sclk_tv[ptr], 1);
> +
>       s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
>       s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
> 
> diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
> index 3df6739..f57d281 100644
> --- a/arch/arm/mach-exynos4/cpu.c
> +++ b/arch/arm/mach-exynos4/cpu.c
> @@ -25,6 +25,7 @@
>  #include <plat/devs.h>
>  #include <plat/fimc-core.h>
>  #include <plat/iic-core.h>
> +#include <plat/tv-core.h>
> 
>  #include <mach/regs-irq.h>
> 
> @@ -151,6 +152,9 @@ void __init exynos4_map_io(void)
>       s3c_i2c0_setname("s3c2440-i2c");
>       s3c_i2c1_setname("s3c2440-i2c");
>       s3c_i2c2_setname("s3c2440-i2c");
> +
> +     /* setup TV devices */
> +     s5p_hdmi_setname("exynos4-hdmi");
>  }
> 
>  void __init exynos4_init_clocks(int xtal)
> diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-
> exynos4/include/mach/irqs.h
> index c342ba1..c2077ce 100644
> --- a/arch/arm/mach-exynos4/include/mach/irqs.h
> +++ b/arch/arm/mach-exynos4/include/mach/irqs.h
> @@ -93,10 +93,12 @@
>  #define IRQ_2D                       IRQ_SPI(89)
>  #define IRQ_PCIE             IRQ_SPI(90)
> 
> +#define IRQ_MIXER            IRQ_SPI(91)
> +#define IRQ_HDMI             IRQ_SPI(92)
>  #define IRQ_HDMI_I2C         IRQ_SPI(93)
>  #define IRQ_IIC8             IRQ_HDMI_I2C
> -
>  #define IRQ_MFC                      IRQ_SPI(94)
> +#define IRQ_SDO                      IRQ_SPI(95)
> 
>  #define IRQ_AUDIO_SS         IRQ_SPI(96)
>  #define IRQ_I2S0             IRQ_SPI(97)
> diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-
> exynos4/include/mach/map.h
> index 1fd986b..79ec1f9 100644
> --- a/arch/arm/mach-exynos4/include/mach/map.h
> +++ b/arch/arm/mach-exynos4/include/mach/map.h
> @@ -168,4 +168,30 @@
> 
>  #define S5P_SZ_UART                  SZ_256
> 
> +/* CEC */
> +#define S5PV210_PA_CEC               (0x100B0000)
> +#define S5P_PA_CEC           S5PV210_PA_CEC
> +#define S5P_SZ_CEC           SZ_4K
> +
> +/* TVOUT */
> +#define S5PV210_PA_SDO               (0x12C20000)
> +#define S5P_PA_SDO           S5PV210_PA_SDO
> +#define S5P_SZ_SDO           SZ_64K
> +
> +#define S5PV210_PA_VP                (0x12C00000)
> +#define S5P_PA_VP            S5PV210_PA_VP
> +#define S5P_SZ_VP            SZ_64K
> +
> +#define S5PV210_PA_MIXER     (0x12C10000)
> +#define S5P_PA_MIXER         S5PV210_PA_MIXER
> +#define S5P_SZ_MIXER         SZ_64K
> +
> +#define S5PV210_PA_HDMI              (0x12D00000)
> +#define S5P_PA_HDMI          S5PV210_PA_HDMI
> +#define S5P_SZ_HDMI          SZ_1M
> +
> +#define S5PV210_I2C_HDMI_PHY (0x138E0000)
> +#define S5P_I2C_HDMI_PHY     S5PV210_I2C_HDMI_PHY
> +#define S5P_I2C_HDMI_SZ_PHY  SZ_1K
> +
>  #endif /* __ASM_ARCH_MAP_H */
> diff --git a/arch/arm/mach-exynos4/include/mach/regs-clock.h
b/arch/arm/mach-
> exynos4/include/mach/regs-clock.h
> index 64bdd24..854c736 100644
> --- a/arch/arm/mach-exynos4/include/mach/regs-clock.h
> +++ b/arch/arm/mach-exynos4/include/mach/regs-clock.h
> @@ -36,6 +36,7 @@
>  #define S5P_CLKSRC_TOP0                      S5P_CLKREG(0x0C210)
>  #define S5P_CLKSRC_TOP1                      S5P_CLKREG(0x0C214)
>  #define S5P_CLKSRC_CAM                       S5P_CLKREG(0x0C220)
> +#define S5P_CLKSRC_TV                        S5P_CLKREG(0x0C224)
>  #define S5P_CLKSRC_MFC                       S5P_CLKREG(0x0C228)
>  #define S5P_CLKSRC_IMAGE             S5P_CLKREG(0x0C230)
>  #define S5P_CLKSRC_LCD0                      S5P_CLKREG(0x0C234)
> diff --git a/arch/arm/mach-exynos4/include/mach/regs-pmu.h
b/arch/arm/mach-
> exynos4/include/mach/regs-pmu.h
> index fa49bbb..faf9b98 100644
> --- a/arch/arm/mach-exynos4/include/mach/regs-pmu.h
> +++ b/arch/arm/mach-exynos4/include/mach/regs-pmu.h
> @@ -33,9 +33,15 @@
>  #define S5P_EINT_WAKEUP_MASK
>       S5P_PMUREG(0x0604)
>  #define S5P_WAKEUP_MASK
>       S5P_PMUREG(0x0608)
> 
> +#define S5P_HDMI_PHY_CONTROL
>       S5P_PMUREG(0x0700)
> +#define S5P_HDMI_PHY_ENABLE                  (1 << 0)
> +
>  #define S5P_USBHOST_PHY_CONTROL
>       S5P_PMUREG(0x0708)
>  #define S5P_USBHOST_PHY_ENABLE                       (1 << 0)
> 
> +#define S5P_DAC_PHY_CONTROL
>       S5P_PMUREG(0x070C)
> +#define S5P_DAC_PHY_ENABLE                   (1 << 0)
> +
>  #define S5P_MIPI_DPHY_CONTROL(n)             S5P_PMUREG(0x0710 + (n) *
> 4)
>  #define S5P_MIPI_DPHY_ENABLE                 (1 << 0)
>  #define S5P_MIPI_DPHY_SRESETN                        (1 << 1)
> --
> 1.7.1.569.g6f426



Thanks.

Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to