diff mbox

[v2,10/13] ARM: davinci - update the dm355 soc code to use common clk drivers

Message ID 1348683037-9705-11-git-send-email-m-karicheri2@ti.com (mailing list archive)
State Changes Requested
Headers show

Commit Message

Murali Karicheri Sept. 26, 2012, 6:10 p.m. UTC
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 <m-karicheri2@ti.com>
diff mbox

Patch

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 <linux/serial_8250.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
-
 #include <linux/spi/spi.h>
+#ifdef CONFIG_COMMON_CLK
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_data/clk-davinci-pll.h>
+#include <linux/platform_data/clk-davinci-psc.h>
+#include <linux/platform_data/davinci-clock.h>
+#include <mach/pll.h>
+#endif
 
 #include <asm/mach/map.h>
 
@@ -30,17 +37,24 @@ 
 #include <mach/gpio-davinci.h>
 
 #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		24000000	/* 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,				\
+	};							\
+								\
+	static struct davinci_clk __name = {			\
+		.name		= #__name,			\
+		.parent		= &__pll,			\
+		.type		= DAVINCI_PRG_DIV_CLK,		\
+		.clk_data	= {				\
+			.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);
+
+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_mux,
+	.type			= DAVINCI_FIXED_FACTOR_CLK,
+	.clk_data		= {
+		.fixed_factor	=  &fixed_clk_data,
+	},
+};
+
+static struct clk_divider_data pll1_sysclkbp_data = {
+	.div_reg	= BPDIV,
+};
+
+static struct davinci_clk pll1_sysclkbp = {
+	.name		= "pll1_sysclkbp",
+	.parent		= &ref_clk_mux,
+	.type		= DAVINCI_PRG_DIV_CLK,
+	.clk_data	= {
+		.data	= &pll1_sysclkbp_data,
+	},
+};
+
+#define __lpsc_clk(cname, _parent, mod, flgs, _flgs, dom)	\
+	static struct clk_davinci_psc_data clk_psc_data##cname = {	\
+		.domain	= DAVINCI_GPSC_##dom,			\
+		.lpsc	= DAVINCI_LPSC_##mod,			\
+		.flags	= flgs,					\
+	};							\
+								\
+	static struct davinci_clk clk_##cname = {		\
+		.name		= #cname,			\
+		.parent		= &_parent,			\
+		.flags		= _flgs,			\
+		.type		= DAVINCI_PSC_CLK,		\
+		.clk_data	= {				\
+			.data	= &clk_psc_data##cname		\
+		},						\
+	}
+
+#define lpsc_clk_enabled(cname, parent, mod)		\
+	__lpsc_clk(cname, parent, mod, 0, ALWAYS_ENABLED, ARMDOMAIN)
+
+#define lpsc_clk(cname, flgs, parent, mod, dom)		\
+	__lpsc_clk(cname, parent, mod, flgs, 0, dom)
+
+#define __dm355_lpsc_clk(cname, _parent, mod, flgs, _flgs, dom)	\
+	static struct clk_davinci_psc_data clk_psc_data##cname = {	\
+		.domain	= DAVINCI_GPSC_##dom,			\
+		.lpsc	= DM355_LPSC_##mod,			\
+		.flags	= flgs,					\
+	};							\
+								\
+	static struct davinci_clk clk_##cname = {		\
+		.name		= #cname,			\
+		.parent		= &_parent,			\
+		.flags		= _flgs,			\
+		.type		= DAVINCI_PSC_CLK,		\
+		.clk_data	= {				\
+			.data	= &clk_psc_data##cname		\
+		},						\
+	}
+
+#define dm355_lpsc_clk(cname, flgs, parent, mod, dom)		\
+	__dm355_lpsc_clk(cname, parent, mod, flgs, 0, dom)
+
+dm355_lpsc_clk(vpss_dac, 0, pll1_sysclk3, VPSS_DAC, ARMDOMAIN);
+lpsc_clk(vpss_master, 0, pll1_sysclk4, VPSSMSTR, ARMDOMAIN);
+lpsc_clk(vpss_slave, 0, pll1_sysclk4, VPSSSLV, ARMDOMAIN);
+lpsc_clk_enabled(arm, pll1_sysclk1, ARM);
+lpsc_clk(mjcp, 0, pll1_sysclk1, IMCOP, ARMDOMAIN);
+lpsc_clk(uart0, 0, ref_clk_mux, UART0, ARMDOMAIN);
+lpsc_clk(uart1, 0, ref_clk_mux, UART1, ARMDOMAIN);
+lpsc_clk(uart2, 0, pll1_sysclk2, UART2, ARMDOMAIN);
+lpsc_clk(i2c, 0, ref_clk_mux, I2C, ARMDOMAIN);
+lpsc_clk(asp0, 0, pll1_sysclk2, McBSP, ARMDOMAIN);
+dm355_lpsc_clk(asp1, 0, pll1_sysclk2, McBSP1, ARMDOMAIN);
+lpsc_clk(mmcsd0, 0, pll1_sysclk2, MMC_SD, ARMDOMAIN);
+dm355_lpsc_clk(mmcsd1, 0, pll1_sysclk2, MMC_SD1, ARMDOMAIN);
+lpsc_clk(spi0, 0, pll1_sysclk2, SPI, ARMDOMAIN);
+dm355_lpsc_clk(spi1, 0, pll1_sysclk2, SPI1, ARMDOMAIN);
+dm355_lpsc_clk(spi2, 0, pll1_sysclk2, SPI2, ARMDOMAIN);
+lpsc_clk(gpio, 0, pll1_sysclk2, GPIO, ARMDOMAIN);
+lpsc_clk(aemif, 0, pll1_sysclk2, AEMIF, ARMDOMAIN);
+lpsc_clk(pwm0, 0, ref_clk_mux, PWM0, ARMDOMAIN);
+lpsc_clk(pwm1, 0, ref_clk_mux, PWM1, ARMDOMAIN);
+lpsc_clk(pwm2, 0, ref_clk_mux, PWM2, ARMDOMAIN);
+dm355_lpsc_clk(pwm3, 0, ref_clk_mux, PWM3, ARMDOMAIN);
+lpsc_clk(timer0, 0, ref_clk_mux, TIMER0, ARMDOMAIN);
+lpsc_clk(timer1, 0, ref_clk_mux, TIMER1, ARMDOMAIN);
+/* REVISIT: why can't this be disabled? */
+lpsc_clk(timer2, CLK_IGNORE_UNUSED, ref_clk_mux, TIMER2, ARMDOMAIN);
+dm355_lpsc_clk(timer3, 0, ref_clk_mux, TIMER3, ARMDOMAIN);
+dm355_lpsc_clk(rto, 0, ref_clk_mux, RTO, ARMDOMAIN);
+lpsc_clk(usb, 0, pll1_sysclk2, USB, ARMDOMAIN);
+
+static struct clk_davinci_pll_data pll2_data = {
+	.phy_pllm	= DAVINCI_PLL2_BASE + PLLM,
+	.phy_prediv	= DAVINCI_PLL2_BASE + PREDIV,
+	.phy_postdiv	= DAVINCI_PLL2_BASE + POSTDIV,
+	.pllm_mask	= PLLM_PLLM_MASK,
+	.prediv_mask	= PLLDIV_RATIO_MASK,
+	.postdiv_mask	= PLLDIV_RATIO_MASK,
+	.num = 2,
+	.pll_flags	= CLK_DAVINCI_PLL_HAS_PREDIV,
+};
+
+static struct davinci_clk pll2_clk = {
+	.name		= "pll2",
+	.parent		= &ref_clk_mux,
+	.type		= DAVINCI_MAIN_PLL_CLK,
+	.clk_data	= {
+		.data	= &pll2_data,
+	},
+};
+
+#define define_pll2_div_clk(__pll, __div, __name)	\
+	static struct clk_divider_data pll2_div_data##__div = {	\
+		.div_reg	= DAVINCI_PLL2_BASE + PLLDIV##__div,	\
+		.width		= 5,				\
+	};							\
+								\
+	static struct davinci_clk __name = {			\
+		.name		= #__name,			\
+		.parent		= &__pll,			\
+		.type		= DAVINCI_PRG_DIV_CLK,		\
+		.clk_data	= {				\
+			.data	=  &pll2_div_data##__div,	\
+		},						\
+	}
+
+static const char *pll2_plldiv_clk_mux_parents[] = {
+						"ref_clk_mux", "pll2"};
+
+static struct clk_mux_data pll2_plldiv_clk_mux_data = {
+	.shift		= PLLCTL_PLLEN_SHIFT,
+	.width		= PLLCTL_PLLEN_WIDTH,
+	.num_parents	= ARRAY_SIZE(pll2_plldiv_clk_mux_parents),
+	.parents	= pll2_plldiv_clk_mux_parents,
+	.phys_base	= DAVINCI_PLL2_BASE + PLLCTL,
+};
+
+static struct davinci_clk pll2_plldiv_clk_mux = {
+	.name		= "pll2_plldiv_clk_mux",
+	.parent		= &pll2_clk,
+	.type		= DAVINCI_MUX_CLK,
+	.clk_data	= {
+		.data	= &pll2_plldiv_clk_mux_data,
+	},
+};
+
+define_pll2_div_clk(pll2_plldiv_clk_mux, 1, pll2_sysclk1);
+
+static struct clk_divider_data pll2_sysclkbp_data = {
+	.div_reg	= DAVINCI_PLL2_BASE + BPDIV,
+	.width		= 5,
+};
+
+static struct davinci_clk pll2_sysclkbp = {
+	.name		= "pll2_sysclkbp",
+	.parent		= &ref_clk_mux,
+	.type		= DAVINCI_PRG_DIV_CLK,
+	.clk_data	= {
+		.data	= &pll2_sysclkbp_data,
+	},
+};
+
+static struct davinci_clk_lookup dm355_clks[] = {
+	CLK(NULL, "clkin", &ref_clk_clkin),
+	CLK(NULL, "oscin", &ref_clk_oscin),
+	CLK(NULL, "ref_clk_mux", &ref_clk_mux),
+	CLK(NULL, "pll1", &pll1_clk),
+	CLK(NULL, "pll1_plldiv_clk_mux", &pll1_plldiv_clk_mux),
+	CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
+	CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
+	CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
+	CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
+	CLK(NULL, "pll1_aux", &pll1_aux_clk),
+	CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
+	CLK(NULL, "vpss_dac", &clk_vpss_dac),
+	CLK(NULL, "vpss_master", &clk_vpss_master),
+	CLK(NULL, "vpss_slave", &clk_vpss_slave),
+	CLK(NULL, "pll2", &pll2_clk),
+	CLK(NULL, "pll2_plldiv_clk_mux", &pll2_plldiv_clk_mux),
+	CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
+	CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
+	CLK(NULL, "arm", &clk_arm),
+	CLK(NULL, "mjcp", &clk_mjcp),
+	CLK(NULL, "uart0", &clk_uart0),
+	CLK(NULL, "uart1", &clk_uart1),
+	CLK(NULL, "uart2", &clk_uart2),
+	CLK("i2c_davinci.1", NULL, &clk_i2c),
+	CLK("davinci-mcbsp.0", NULL, &clk_asp0),
+	CLK("davinci-mcbsp.1", NULL, &clk_asp1),
+	CLK("davinci_mmc.0", NULL, &clk_mmcsd0),
+	CLK("davinci_mmc.1", NULL, &clk_mmcsd1),
+	CLK("spi_davinci.0", NULL, &clk_spi0),
+	CLK("spi_davinci.1", NULL, &clk_spi1),
+	CLK("spi_davinci.2", NULL, &clk_spi2),
+	CLK(NULL, "gpio", &clk_gpio),
+	CLK(NULL, "aemif", &clk_aemif),
+	CLK(NULL, "pwm0", &clk_pwm0),
+	CLK(NULL, "pwm1", &clk_pwm1),
+	CLK(NULL, "pwm2", &clk_pwm2),
+	CLK(NULL, "pwm3", &clk_pwm3),
+	CLK(NULL, "timer0", &clk_timer0),
+	CLK(NULL, "timer1", &clk_timer1),
+	CLK("watchdog", NULL, &clk_timer2),
+	CLK(NULL, "timer3", &clk_timer3),
+	CLK(NULL, "rto", &clk_rto),
+	CLK(NULL, "usb", &clk_usb),
+	CLK(NULL, NULL, NULL),
+};
+#endif
 
 /*----------------------------------------------------------------------*/
 
@@ -829,6 +1171,32 @@  static struct platform_device dm355_serial_device = {
 	},
 };
 
+#ifdef CONFIG_COMMON_CLK
+static struct clk_lookup vpss_master_lookups[] = {
+	{ .dev_id = "dm355_ccdc", .con_id = "master", },
+};
+
+static struct clk_lookup vpss_slave_lookups[] = {
+	{ .dev_id = "dm355_ccdc", .con_id = "slave", },
+};
+
+static struct davinci_dev_lookup dev_clk_lookups[] = {
+	{
+		.con_id		= "vpss_master",
+		.num_devs	= ARRAY_SIZE(vpss_master_lookups),
+		.lookups	= vpss_master_lookups,
+	},
+	{
+		.con_id		= "vpss_slave",
+		.num_devs	= ARRAY_SIZE(vpss_slave_lookups),
+		.lookups	= vpss_slave_lookups,
+	},
+	{
+		.con_id		= NULL,
+	},
+};
+#endif
+
 static struct davinci_soc_info davinci_soc_info_dm355 = {
 	.io_desc		= dm355_io_desc,
 	.io_desc_num		= ARRAY_SIZE(dm355_io_desc),
@@ -836,6 +1204,9 @@  static struct davinci_soc_info davinci_soc_info_dm355 = {
 	.ids			= dm355_ids,
 	.ids_num		= ARRAY_SIZE(dm355_ids),
 	.cpu_clks		= dm355_clks,
+#ifdef CONFIG_COMMON_CLK
+	.dev_clk_lookups	= dev_clk_lookups,
+#endif
 	.psc_bases		= dm355_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(dm355_psc_bases),
 	.pinmux_base		= DAVINCI_SYSTEM_MODULE_BASE,
@@ -880,8 +1251,10 @@  static int __init dm355_init_devices(void)
 		return 0;
 
 	/* Add ccdc clock aliases */
+#ifndef CONFIG_COMMON_CLK
 	clk_add_alias("master", dm355_ccdc_dev.name, "vpss_master", NULL);
 	clk_add_alias("slave", dm355_ccdc_dev.name, "vpss_master", NULL);
+#endif
 	davinci_cfg_reg(DM355_INT_EDMA_CC);
 	platform_device_register(&dm355_edma_device);
 	platform_device_register(&dm355_vpss_device);