|
@@ -838,3 +838,93 @@ static struct clksrc_clk *clksrc_cdev[] = {
|
|
|
&clk_sclk_spi1,
|
|
|
&clk_audio_bus0,
|
|
|
&clk_audio_bus1,
|
|
|
+};
|
|
|
+
|
|
|
+static struct clk *clk_cdev[] = {
|
|
|
+ &clk_hsmmc0,
|
|
|
+ &clk_hsmmc1,
|
|
|
+ &clk_hsmmc2,
|
|
|
+ &clk_48m_spi0,
|
|
|
+ &clk_48m_spi1,
|
|
|
+ &clk_i2s0,
|
|
|
+ &clk_i2s1,
|
|
|
+};
|
|
|
+
|
|
|
+static struct clk_lookup s3c64xx_clk_lookup[] = {
|
|
|
+ CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
|
|
|
+ CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
|
|
|
+ CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0),
|
|
|
+ CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1),
|
|
|
+ CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2),
|
|
|
+ CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
|
|
|
+ CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
|
|
|
+ CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
|
|
|
+ CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
|
|
|
+ CLKDEV_INIT("s3c6410-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
|
|
|
+ CLKDEV_INIT("s3c6410-spi.0", "spi_busclk2", &clk_48m_spi0),
|
|
|
+ CLKDEV_INIT("s3c6410-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
|
|
|
+ CLKDEV_INIT("s3c6410-spi.1", "spi_busclk2", &clk_48m_spi1),
|
|
|
+ CLKDEV_INIT("samsung-i2s.0", "i2s_opclk0", &clk_i2s0),
|
|
|
+ CLKDEV_INIT("samsung-i2s.0", "i2s_opclk1", &clk_audio_bus0.clk),
|
|
|
+ CLKDEV_INIT("samsung-i2s.1", "i2s_opclk0", &clk_i2s1),
|
|
|
+ CLKDEV_INIT("samsung-i2s.1", "i2s_opclk1", &clk_audio_bus1.clk),
|
|
|
+#ifdef CONFIG_CPU_S3C6410
|
|
|
+ CLKDEV_INIT("samsung-i2s.2", "i2s_opclk0", &clk_i2s2),
|
|
|
+ CLKDEV_INIT("samsung-i2s.2", "i2s_opclk1", &clk_audio_bus2.clk),
|
|
|
+#endif
|
|
|
+};
|
|
|
+
|
|
|
+#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
|
|
|
+
|
|
|
+void __init_or_cpufreq s3c64xx_setup_clocks(void)
|
|
|
+{
|
|
|
+ struct clk *xtal_clk;
|
|
|
+ unsigned long xtal;
|
|
|
+ unsigned long fclk;
|
|
|
+ unsigned long hclk;
|
|
|
+ unsigned long hclk2;
|
|
|
+ unsigned long pclk;
|
|
|
+ unsigned long epll;
|
|
|
+ unsigned long apll;
|
|
|
+ unsigned long mpll;
|
|
|
+ unsigned int ptr;
|
|
|
+ u32 clkdiv0;
|
|
|
+
|
|
|
+ printk(KERN_DEBUG "%s: registering clocks\n", __func__);
|
|
|
+
|
|
|
+ clkdiv0 = __raw_readl(S3C_CLK_DIV0);
|
|
|
+ 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);
|
|
|
+
|
|
|
+ /* For now assume the mux always selects the crystal */
|
|
|
+ clk_ext_xtal_mux.parent = xtal_clk;
|
|
|
+
|
|
|
+ epll = s3c_get_pll6553x(xtal, __raw_readl(S3C_EPLL_CON0),
|
|
|
+ __raw_readl(S3C_EPLL_CON1));
|
|
|
+ mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON));
|
|
|
+ apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON));
|
|
|
+
|
|
|
+ fclk = mpll;
|
|
|
+
|
|
|
+ printk(KERN_INFO "S3C64XX: PLL settings, A=%ld, M=%ld, E=%ld\n",
|
|
|
+ apll, mpll, epll);
|
|
|
+
|
|
|
+ if(__raw_readl(S3C64XX_OTHERS) & S3C64XX_OTHERS_SYNCMUXSEL)
|
|
|
+ /* Synchronous mode */
|
|
|
+ hclk2 = apll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
|
|
|
+ else
|
|
|
+ /* Asynchronous mode */
|
|
|
+ hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
|
|
|
+
|
|
|
+ hclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK);
|
|
|
+ pclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK);
|
|
|
+
|
|
|
+ printk(KERN_INFO "S3C64XX: HCLK2=%ld, HCLK=%ld, PCLK=%ld\n",
|
|
|
+ hclk2, hclk, pclk);
|