static int __init ep93xx_clock_init()

in mach-ep93xx/clock.c [533:728]


static int __init ep93xx_clock_init(void)
{
	u32 value;
	struct clk_hw *hw;
	unsigned long clk_pll1_rate;
	unsigned long clk_f_rate;
	unsigned long clk_h_rate;
	unsigned long clk_p_rate;
	unsigned long clk_pll2_rate;
	unsigned int clk_f_div;
	unsigned int clk_h_div;
	unsigned int clk_p_div;
	unsigned int clk_usb_div;
	unsigned long clk_spi_div;

	hw = clk_hw_register_fixed_rate(NULL, "xtali", NULL, 0, EP93XX_EXT_CLK_RATE);
	clk_hw_register_clkdev(hw, NULL, "xtali");

	/* Determine the bootloader configured pll1 rate */
	value = __raw_readl(EP93XX_SYSCON_CLKSET1);
	if (!(value & EP93XX_SYSCON_CLKSET1_NBYP1))
		clk_pll1_rate = EP93XX_EXT_CLK_RATE;
	else
		clk_pll1_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);

	hw = clk_hw_register_fixed_rate(NULL, "pll1", "xtali", 0, clk_pll1_rate);
	clk_hw_register_clkdev(hw, NULL, "pll1");

	/* Initialize the pll1 derived clocks */
	clk_f_div = fclk_divisors[(value >> 25) & 0x7];
	clk_h_div = hclk_divisors[(value >> 20) & 0x7];
	clk_p_div = pclk_divisors[(value >> 18) & 0x3];

	hw = clk_hw_register_fixed_factor(NULL, "fclk", "pll1", 0, 1, clk_f_div);
	clk_f_rate = clk_get_rate(hw->clk);
	hw = clk_hw_register_fixed_factor(NULL, "hclk", "pll1", 0, 1, clk_h_div);
	clk_h_rate = clk_get_rate(hw->clk);
	hw = clk_hw_register_fixed_factor(NULL, "pclk", "hclk", 0, 1, clk_p_div);
	clk_p_rate = clk_get_rate(hw->clk);

	clk_hw_register_clkdev(hw, "apb_pclk", NULL);

	ep93xx_dma_clock_init();

	/* Determine the bootloader configured pll2 rate */
	value = __raw_readl(EP93XX_SYSCON_CLKSET2);
	if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
		clk_pll2_rate = EP93XX_EXT_CLK_RATE;
	else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
		clk_pll2_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);
	else
		clk_pll2_rate = 0;

	hw = clk_hw_register_fixed_rate(NULL, "pll2", "xtali", 0, clk_pll2_rate);
	clk_hw_register_clkdev(hw, NULL, "pll2");

	/* Initialize the pll2 derived clocks */
	/*
	 * These four bits set the divide ratio between the PLL2
	 * output and the USB clock.
	 * 0000 - Divide by 1
	 * 0001 - Divide by 2
	 * 0010 - Divide by 3
	 * 0011 - Divide by 4
	 * 0100 - Divide by 5
	 * 0101 - Divide by 6
	 * 0110 - Divide by 7
	 * 0111 - Divide by 8
	 * 1000 - Divide by 9
	 * 1001 - Divide by 10
	 * 1010 - Divide by 11
	 * 1011 - Divide by 12
	 * 1100 - Divide by 13
	 * 1101 - Divide by 14
	 * 1110 - Divide by 15
	 * 1111 - Divide by 1
	 * On power-on-reset these bits are reset to 0000b.
	 */
	clk_usb_div = (((value >> 28) & 0xf) + 1);
	hw = clk_hw_register_fixed_factor(NULL, "usb_clk", "pll2", 0, 1, clk_usb_div);
	hw = clk_hw_register_gate(NULL, "ohci-platform",
				"usb_clk", 0,
				EP93XX_SYSCON_PWRCNT,
				EP93XX_SYSCON_PWRCNT_USH_EN,
				0,
				&clk_lock);
	clk_hw_register_clkdev(hw, NULL, "ohci-platform");

	/*
	 * EP93xx SSP clock rate was doubled in version E2. For more information
	 * see:
	 *     http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
	 */
	clk_spi_div = 1;
	if (ep93xx_chip_revision() < EP93XX_CHIP_REV_E2)
		clk_spi_div = 2;
	hw = clk_hw_register_fixed_factor(NULL, "ep93xx-spi.0", "xtali", 0, 1, clk_spi_div);
	clk_hw_register_clkdev(hw, NULL, "ep93xx-spi.0");

	/* pwm clock */
	hw = clk_hw_register_fixed_factor(NULL, "pwm_clk", "xtali", 0, 1, 1);
	clk_hw_register_clkdev(hw, "pwm_clk", NULL);

	pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
		clk_pll1_rate / 1000000, clk_pll2_rate / 1000000);
	pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
		clk_f_rate / 1000000, clk_h_rate / 1000000,
		clk_p_rate / 1000000);

	ep93xx_uart_clock_init();

	/* touchscreen/adc clock */
	hw = clk_hw_register_div("ep93xx-adc",
				"xtali",
				EP93XX_SYSCON_KEYTCHCLKDIV,
				EP93XX_SYSCON_KEYTCHCLKDIV_TSEN,
				EP93XX_SYSCON_KEYTCHCLKDIV_ADIV,
				1,
				adc_divisors,
				ARRAY_SIZE(adc_divisors));

	clk_hw_register_clkdev(hw, NULL, "ep93xx-adc");

	/* keypad clock */
	hw = clk_hw_register_div("ep93xx-keypad",
				"xtali",
				EP93XX_SYSCON_KEYTCHCLKDIV,
				EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
				EP93XX_SYSCON_KEYTCHCLKDIV_KDIV,
				1,
				adc_divisors,
				ARRAY_SIZE(adc_divisors));

	clk_hw_register_clkdev(hw, NULL, "ep93xx-keypad");

	/* On reset PDIV and VDIV is set to zero, while PDIV zero
	 * means clock disable, VDIV shouldn't be zero.
	 * So i set both dividers to minimum.
	 */
	/* ENA - Enable CLK divider. */
	/* PDIV - 00 - Disable clock */
	/* VDIV - at least 2 */
	/* Check and enable video clk registers */
	value = __raw_readl(EP93XX_SYSCON_VIDCLKDIV);
	value |= (1 << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;
	ep93xx_syscon_swlocked_write(value, EP93XX_SYSCON_VIDCLKDIV);

	/* check and enable i2s clk registers */
	value = __raw_readl(EP93XX_SYSCON_I2SCLKDIV);
	value |= (1 << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;
	ep93xx_syscon_swlocked_write(value, EP93XX_SYSCON_I2SCLKDIV);

	/* video clk */
	hw = clk_hw_register_ddiv("ep93xx-fb",
				EP93XX_SYSCON_VIDCLKDIV,
				EP93XX_SYSCON_CLKDIV_ENABLE);

	clk_hw_register_clkdev(hw, NULL, "ep93xx-fb");

	/* i2s clk */
	hw = clk_hw_register_ddiv("mclk",
				EP93XX_SYSCON_I2SCLKDIV,
				EP93XX_SYSCON_CLKDIV_ENABLE);

	clk_hw_register_clkdev(hw, "mclk", "ep93xx-i2s");

	/* i2s sclk */
#define EP93XX_I2SCLKDIV_SDIV_SHIFT	16
#define EP93XX_I2SCLKDIV_SDIV_WIDTH	1
	hw = clk_hw_register_div("sclk",
				"mclk",
				EP93XX_SYSCON_I2SCLKDIV,
				EP93XX_SYSCON_I2SCLKDIV_SENA,
				EP93XX_I2SCLKDIV_SDIV_SHIFT,
				EP93XX_I2SCLKDIV_SDIV_WIDTH,
				sclk_divisors,
				ARRAY_SIZE(sclk_divisors));

	clk_hw_register_clkdev(hw, "sclk", "ep93xx-i2s");

	/* i2s lrclk */
#define EP93XX_I2SCLKDIV_LRDIV32_SHIFT	17
#define EP93XX_I2SCLKDIV_LRDIV32_WIDTH	3
	hw = clk_hw_register_div("lrclk",
				"sclk",
				EP93XX_SYSCON_I2SCLKDIV,
				EP93XX_SYSCON_I2SCLKDIV_SENA,
				EP93XX_I2SCLKDIV_LRDIV32_SHIFT,
				EP93XX_I2SCLKDIV_LRDIV32_WIDTH,
				lrclk_divisors,
				ARRAY_SIZE(lrclk_divisors));

	clk_hw_register_clkdev(hw, "lrclk", "ep93xx-i2s");

	return 0;
}