* [PATCH 2/5] clk: mmp: add clock definition for pxa168
2012-07-31 6:39 [PATCH 1/5] clk: mmp: add mmp specific clocks Chao Xie
@ 2012-07-31 6:39 ` Chao Xie
2012-07-31 11:54 ` Arnd Bergmann
2012-07-31 6:39 ` [PATCH 3/5] clk: mmp: add clock definition for pxa910 Chao Xie
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Chao Xie @ 2012-07-31 6:39 UTC (permalink / raw)
To: linux-arm-kernel
From: Chao Xie <chao.xie@marvell.com>
Initialize the clocks for pxa168
Signed-off-by: Chao Xie <xiechao.mail@gmail.com>
---
drivers/clk/mmp/Makefile | 2 +
drivers/clk/mmp/clk-pxa168.c | 268 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 270 insertions(+), 0 deletions(-)
create mode 100644 drivers/clk/mmp/clk-pxa168.c
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index a263cb7..8bbf882 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -3,3 +3,5 @@
#
obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-pll2.o
+
+obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
new file mode 100644
index 0000000..7af4407
--- /dev/null
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -0,0 +1,268 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+
+#include <mach/addr-map.h>
+
+#include "clk.h"
+
+#define APBC_RTC APBC_REG(0x28)
+#define APBC_TWSI0 APBC_REG(0x2c)
+#define APBC_KPC APBC_REG(0x30)
+#define APBC_UART0 APBC_REG(0x00)
+#define APBC_UART1 APBC_REG(0x04)
+#define APBC_GPIO APBC_REG(0x08)
+#define APBC_PWM0 APBC_REG(0x0c)
+#define APBC_PWM1 APBC_REG(0x10)
+#define APBC_PWM2 APBC_REG(0x14)
+#define APBC_PWM3 APBC_REG(0x18)
+#define APBC_SSP0 APBC_REG(0x81c)
+#define APBC_SSP1 APBC_REG(0x820)
+#define APBC_SSP2 APBC_REG(0x84c)
+#define APBC_SSP3 APBC_REG(0x858)
+#define APBC_SSP4 APBC_REG(0x85c)
+#define APBC_TWSI1 APBC_REG(0x6c)
+#define APBC_UART2 APBC_REG(0x70)
+
+#define APMU_SDH0 APMU_REG(0x54)
+#define APMU_SDH1 APMU_REG(0x58)
+#define APMU_USB APMU_REG(0x5c)
+#define APMU_DISP0 APMU_REG(0x4c)
+#define APMU_CCIC0 APMU_REG(0x50)
+#define APMU_DFC APMU_REG(0x60)
+
+static DEFINE_SPINLOCK(mmp_clk_lock);
+
+enum pll_clk {
+ clk32,
+ pll1, pll1_2, pll1_4, pll1_8, pll1_16,
+ pll1_6, pll1_12, pll1_24, pll1_48, pll1_96,
+ pll1_13, pll1_13_1_5, pll1_2_1_5, pll1_3_16,
+ pll2,
+ vctcxo,
+ uart_pll,
+ pll_max,
+};
+
+enum apbc_clk {
+ uart0_clk, uart1_clk, uart2_clk,
+ pwm0_clk, pwm1_clk, pwm2_clk, pwm3_clk,
+ twsi0_clk, twsi1_clk,
+ ssp0_clk, ssp1_clk, ssp2_clk,
+ ssp3_clk, ssp4_clk,
+ gpio_clk, kpc_clk, rtc_clk,
+ uart0_mux_clk, uart1_mux_clk, uart2_mux_clk,
+ ssp0_mux_clk, ssp1_mux_clk, ssp2_mux_clk,
+ ssp3_mux_clk, ssp4_mux_clk,
+ apbc_max,
+};
+
+enum apmu_clk {
+ sdh0_mux_clk, sdh1_mux_clk,
+ sdh0_clk, sdh1_clk,
+ dfc_clk,
+ usb_clk, sph_clk,
+ disp0_mux_clk, disp0_clk,
+ disp0_hclk,
+ ccic0_mux_clk, ccic0_clk,
+ ccic0_phy_mux_clk, ccic0_phy_clk, ccic0_sphy_div_clk, ccic0_sphy_clk,
+ apmu_max,
+};
+
+static struct clk_factor_masks factor_masks = {
+ .num_mask = 0x1fff,
+ .den_mask = 0x1fff,
+ .num_shift = 16,
+ .den_shift = 0,
+};
+
+static struct clk_factor_tbl factor_tbl[] = {
+ {.num = 8125, .den = 1536}, /* 14.745MHZ */
+};
+
+static const char *uart_parent[] = {"pll1_3_16", "uart_pll"};
+static const char *ssp_parent[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"};
+static const char *sdh_parent[] = {"pll1_12", "pll1_13"};
+static const char *disp_parent[] = {"pll1_2", "pll1_12"};
+static const char *ccic_parent[] = {"pll1_2", "pll1_12"};
+static const char *ccic_phy_parent[] = {"pll1_6", "pll1_12"};
+
+void __init pxa168_clk_init(void)
+{
+ struct clk *pll_clks[pll_max];
+ struct clk *apbc_clks[apbc_max];
+ struct clk *apmu_clks[apmu_max];
+ /* all root clocks */
+ MMP_CLK_REGISTER_FIXED_RATE(pll_clks, clk32, 32000);
+ MMP_CLK_REGISTER_FIXED_RATE(pll_clks, vctcxo, 26000000);
+ MMP_CLK_REGISTER_FIXED_RATE(pll_clks, pll1, 624000000);
+ pll_clks[pll2] = mmp_clk_register_pll2("pll2", "vctcxo", 0);
+ clk_register_clkdev(pll_clks[pll2], NULL, "pll2");
+
+ /* PLL1 */
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_2, pll1,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_4, pll1_2,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_8, pll1_4,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_16, pll1_8,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_6, pll1_2,
+ CLK_SET_RATE_PARENT, 1, 3);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_12, pll1_6,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_24, pll1_12,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_48, pll1_24,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_96, pll1_48,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_13, pll1,
+ CLK_SET_RATE_PARENT, 1, 13);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_13_1_5, pll1_13,
+ CLK_SET_RATE_PARENT, 2, 3);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_2_1_5, pll1_2,
+ CLK_SET_RATE_PARENT, 2, 3);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_3_16, pll1,
+ CLK_SET_RATE_PARENT, 3, 16);
+ pll_clks[uart_pll] = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
+ MPMU_REG(0x14), &factor_masks, factor_tbl,
+ ARRAY_SIZE(factor_tbl));
+ clk_set_rate(pll_clks[uart_pll], 14745600);
+ /* PLL2 */
+
+ /* APBC devices without mux parent */
+ MMP_CLK_REGISTER_APBC(apbc_clks, twsi0_clk, pll1_13_1_5, 10,
+ APBC_TWSI0, 0, "pxa2xx-i2c.0", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, twsi1_clk, pll1_13_1_5, 10,
+ APBC_TWSI1, 0, "pxa2xx-i2c.1", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, gpio_clk, vctcxo, 10,
+ APBC_GPIO, 0, "pxa-gpio", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, kpc_clk, clk32k, 10,
+ APBC_KPC, 0, "pxa27x-keypad", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, rtc_clk, clk32k, 10,
+ APBC_RTC, APBC_POWER_CTRL, "sa1100-rtc", NULL,
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, pwm0_clk, pll1_48, 10,
+ APBC_PWM0, 0, "pxa168-pwm.0", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, pwm1_clk, pll1_48, 10,
+ APBC_PWM1, 0, "pxa168-pwm.1", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, pwm2_clk, pll1_48, 10,
+ APBC_PWM2, 0, "pxa168-pwm.2", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, pwm3_clk, pll1_48, 10,
+ APBC_PWM3, 0, "pxa168-pwm.3", NULL, &mmp_clk_lock);
+
+ /* APBC devices with mux parent */
+ MMP_CLK_REGISTER_MUX(apbc_clks, uart0_mux_clk, uart_parent,
+ ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
+ APBC_UART0, 4, 3, 0, NULL, "uart_mux.0",
+ &mmp_clk_lock);
+ clk_set_parent(apbc_clks[uart0_mux_clk], pll_clks[uart_pll]);
+ MMP_CLK_REGISTER_APBC(apbc_clks, uart0_clk, uart0_mux_clk, 10,
+ APBC_UART0, 0, "pxa2xx-uart.0", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, uart1_mux_clk, uart_parent,
+ ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
+ APBC_UART1, 4, 3, 0, NULL, "uart_mux.1",
+ &mmp_clk_lock);
+ clk_set_parent(apbc_clks[uart1_mux_clk], pll_clks[uart_pll]);
+ MMP_CLK_REGISTER_APBC(apbc_clks, uart1_clk, uart1_mux_clk, 10,
+ APBC_UART1, 0, "pxa2xx-uart.1", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, uart2_mux_clk, uart_parent,
+ ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
+ APBC_UART2, 4, 3, 0, NULL, "uart_mux.2",
+ &mmp_clk_lock);
+ clk_set_parent(apbc_clks[uart2_mux_clk], pll_clks[uart_pll]);
+ MMP_CLK_REGISTER_APBC(apbc_clks, uart2_clk, uart2_mux_clk, 10,
+ APBC_UART2, 0, "pxa2xx-uart.2", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, ssp0_mux_clk, ssp_parent,
+ ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
+ APBC_SSP0, 4, 3, 0, NULL, "ssp_mux.0", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, ssp0_clk, ssp0_mux_clk, 10,
+ APBC_SSP0, 0, "pxa168-ssp.0", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, ssp1_mux_clk, ssp_parent,
+ ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
+ APBC_SSP1, 4, 3, 0, NULL, "ssp_mux.1", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, ssp1_clk, ssp1_mux_clk, 10,
+ APBC_SSP1, 0, "pxa168-ssp.1", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, ssp2_mux_clk, ssp_parent,
+ ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
+ APBC_SSP2, 4, 3, 0, NULL, "ssp_mux.2", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, ssp2_clk, ssp2_mux_clk, 10,
+ APBC_SSP2, 0, "pxa168-ssp.2", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, ssp3_mux_clk, ssp_parent,
+ ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
+ APBC_SSP3, 4, 3, 0, NULL, "ssp_mux.3", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, ssp3_clk, ssp3_mux_clk, 10,
+ APBC_SSP3, 0, "pxa168-ssp.3", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, ssp4_mux_clk, ssp_parent,
+ ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
+ APBC_SSP4, 4, 3, 0, NULL, "ssp_mux.4", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, ssp4_clk, ssp4_mux_clk, 10,
+ APBC_SSP4, 0, "pxa168-ssp.4", NULL, &mmp_clk_lock);
+
+ /* APMU devices */
+ /* nand */
+ MMP_CLK_REGISTER_APMU(apmu_clks, dfc_clk, pll1_4, APMU_DFC,
+ 0x19b, "pxa3xx-nand.0", NULL, &mmp_clk_lock);
+ /* sdh */
+ MMP_CLK_REGISTER_MUX(apmu_clks, sdh0_mux_clk, sdh_parent,
+ ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT,
+ APMU_SDH0, 6, 1, 0, NULL, "sdh_mux.0", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, sdh0_clk, sdh_mux_clk, APMU_SDH0,
+ 0x1b, "sdhci-pxa.0", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apmu_clks, sdh1_mux_clk, sdh_parent,
+ ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT,
+ APMU_SDH1, 6, 1, 0, NULL, "sdh_mux.1", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, sdh1_clk, sdh1_mux_clk, APMU_SDH1,
+ 0x1b, "sdhci-pxa.1", NULL, &mmp_clk_lock);
+
+ /* usb */
+ MMP_CLK_REGISTER_APMU(apmu_clks, usb_clk, usb_pll, APMU_USB,
+ 0x9, NULL, "usb-clk", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, sph_clk, usb_pll, APMU_USB,
+ 0x12, NULL, "sph-clk", &mmp_clk_lock);
+
+ /* display */
+ MMP_CLK_REGISTER_MUX(apmu_clks, disp0_mux_clk, disp_parent,
+ ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT,
+ APMU_DISP0, 6, 1, 0, NULL, "disp_mux.0",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, disp0_clk, disp0_mux_clk, APMU_DISP0,
+ 0x1b, "mmp-disp.0", "fnclk", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, disp0_hclk, disp0_mux_clk, APMU_DISP0,
+ 0x24, "mmp-disp.0", "hclk", &mmp_clk_lock);
+
+ /* ccic */
+ MMP_CLK_REGISTER_MUX(apmu_clks, ccic0_mux_clk, ccic_parent,
+ ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT,
+ APMU_CCIC0, 6, 1, 0, NULL, "ccic_mux.0",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, ccic0_clk, ccic0_mux_clk, APMU_CCIC0,
+ 0x1b, "mmp-ccic.0", "fnclk", &mmp_clk_lock);
+ MMP_CLK_REGISTER_MUX(apmu_clks, ccic0_phy_mux_clk, ccic_phy_parent,
+ ARRAY_SIZE(ccic_phy_parent), CLK_SET_RATE_PARENT,
+ APMU_CCIC0, 7, 1, 0, NULL, "ccic_phy_mux.0",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, ccic0_phy_clk, ccic0_phy_mux_clk,
+ APMU_CCIC0, 0x24, "mmp-ccic.0", "phyclk",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_DIV(apmu_clks, ccic0_sphy_div_clk, ccic0_mux_clk,
+ 0, APMU_CCIC0, 10, 5, 0,
+ "mmp-ccic.0", "sphyclk_div", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, ccic0_sphy_clk, ccic0_sphy_div_clk,
+ APMU_CCIC0, 0x300, "mmp-ccic.0", "sphyclk",
+ &mmp_clk_lock);
+
+}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/5] clk: mmp: add clock definition for pxa168
2012-07-31 6:39 ` [PATCH 2/5] clk: mmp: add clock definition for pxa168 Chao Xie
@ 2012-07-31 11:54 ` Arnd Bergmann
2012-08-02 7:24 ` Chao Xie
0 siblings, 1 reply; 8+ messages in thread
From: Arnd Bergmann @ 2012-07-31 11:54 UTC (permalink / raw)
To: linux-arm-kernel
On Tuesday 31 July 2012, Chao Xie wrote:
> +#define APBC_RTC APBC_REG(0x28)
> +#define APBC_TWSI0 APBC_REG(0x2c)
> +#define APBC_KPC APBC_REG(0x30)
> +#define APBC_UART0 APBC_REG(0x00)
> +#define APBC_UART1 APBC_REG(0x04)
> +#define APBC_GPIO APBC_REG(0x08)
> +#define APBC_PWM0 APBC_REG(0x0c)
> +#define APBC_PWM1 APBC_REG(0x10)
> +#define APBC_PWM2 APBC_REG(0x14)
> +#define APBC_PWM3 APBC_REG(0x18)
> +#define APBC_SSP0 APBC_REG(0x81c)
> +#define APBC_SSP1 APBC_REG(0x820)
> +#define APBC_SSP2 APBC_REG(0x84c)
> +#define APBC_SSP3 APBC_REG(0x858)
> +#define APBC_SSP4 APBC_REG(0x85c)
> +#define APBC_TWSI1 APBC_REG(0x6c)
> +#define APBC_UART2 APBC_REG(0x70)
> +
> +#define APMU_SDH0 APMU_REG(0x54)
> +#define APMU_SDH1 APMU_REG(0x58)
> +#define APMU_USB APMU_REG(0x5c)
> +#define APMU_DISP0 APMU_REG(0x4c)
> +#define APMU_CCIC0 APMU_REG(0x50)
> +#define APMU_DFC APMU_REG(0x60)
Same comment as for patch 1: get the address from the device tree and just
define those macros to the offset, like:
#define APBC_RTC 0x28
apbc_clks[rtc_clk] = mmp_clk_register_apbc(rtc_clk, clk32k, APBC_RTC, 10, APBC_POWER_CTRL, mmp_clk_lock);
clk_register_clkdev(apbc_clks[rtc_clk], NULL, "sa1100-rtc");
Arnd
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/5] clk: mmp: add clock definition for pxa168
2012-07-31 11:54 ` Arnd Bergmann
@ 2012-08-02 7:24 ` Chao Xie
2012-08-02 10:30 ` Arnd Bergmann
0 siblings, 1 reply; 8+ messages in thread
From: Chao Xie @ 2012-08-02 7:24 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Jul 31, 2012 at 7:54 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Tuesday 31 July 2012, Chao Xie wrote:
>> +#define APBC_RTC APBC_REG(0x28)
>> +#define APBC_TWSI0 APBC_REG(0x2c)
>> +#define APBC_KPC APBC_REG(0x30)
>> +#define APBC_UART0 APBC_REG(0x00)
>> +#define APBC_UART1 APBC_REG(0x04)
>> +#define APBC_GPIO APBC_REG(0x08)
>> +#define APBC_PWM0 APBC_REG(0x0c)
>> +#define APBC_PWM1 APBC_REG(0x10)
>> +#define APBC_PWM2 APBC_REG(0x14)
>> +#define APBC_PWM3 APBC_REG(0x18)
>> +#define APBC_SSP0 APBC_REG(0x81c)
>> +#define APBC_SSP1 APBC_REG(0x820)
>> +#define APBC_SSP2 APBC_REG(0x84c)
>> +#define APBC_SSP3 APBC_REG(0x858)
>> +#define APBC_SSP4 APBC_REG(0x85c)
>> +#define APBC_TWSI1 APBC_REG(0x6c)
>> +#define APBC_UART2 APBC_REG(0x70)
>> +
>> +#define APMU_SDH0 APMU_REG(0x54)
>> +#define APMU_SDH1 APMU_REG(0x58)
>> +#define APMU_USB APMU_REG(0x5c)
>> +#define APMU_DISP0 APMU_REG(0x4c)
>> +#define APMU_CCIC0 APMU_REG(0x50)
>> +#define APMU_DFC APMU_REG(0x60)
>
> Same comment as for patch 1: get the address from the device tree and just
> define those macros to the offset, like:
>
> #define APBC_RTC 0x28
>
> apbc_clks[rtc_clk] = mmp_clk_register_apbc(rtc_clk, clk32k, APBC_RTC, 10, APBC_POWER_CTRL, mmp_clk_lock);
> clk_register_clkdev(apbc_clks[rtc_clk], NULL, "sa1100-rtc");
>
> Arnd
>
hi
I would like to keep the mmp_clk_register_apbc to receive the "reg
base" not "reg offset".
It will be aligned with other kind of clock register APIs.
To read out APBC base register from device tree can be added at the
clock-pxa168.c, and it can map the registers and pass to the
mmp_clk_register_apbc.
Now, i have talked to Haojian who is doing device tree maintainer in
pxa/mmp. This kind of support is not added.
I suggest that after device tree support in clock can be added later
after other functionality of the clock framework is fine.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/5] clk: mmp: add clock definition for pxa168
2012-08-02 7:24 ` Chao Xie
@ 2012-08-02 10:30 ` Arnd Bergmann
0 siblings, 0 replies; 8+ messages in thread
From: Arnd Bergmann @ 2012-08-02 10:30 UTC (permalink / raw)
To: linux-arm-kernel
On Thursday 02 August 2012, Chao Xie wrote:
> > #define APBC_RTC 0x28
> >
> > apbc_clks[rtc_clk] = mmp_clk_register_apbc(rtc_clk, clk32k, APBC_RTC, 10, APBC_POWER_CTRL, mmp_clk_lock);
> > clk_register_clkdev(apbc_clks[rtc_clk], NULL, "sa1100-rtc");
> >
> > Arnd
> >
> hi
> I would like to keep the mmp_clk_register_apbc to receive the "reg
> base" not "reg offset".
> It will be aligned with other kind of clock register APIs.
> To read out APBC base register from device tree can be added at the
> clock-pxa168.c, and it can map the registers and pass to the
> mmp_clk_register_apbc.
Right, my mistake.
The above should have been something like
#define APBC_RTC 0x28
apbc_clks[rtc_clk] = mmp_clk_register_apbc(rtc_clk, clk32k, clock_base + APBC_RTC, 10, APBC_POWER_CTRL, mmp_clk_lock);
clk_register_clkdev(apbc_clks[rtc_clk], NULL, "sa1100-rtc");
instead, with clock_base pointing to the __iomem token for the clock controller.
> Now, i have talked to Haojian who is doing device tree maintainer in
> pxa/mmp. This kind of support is not added.
> I suggest that after device tree support in clock can be added later
> after other functionality of the clock framework is fine.
You can do device tree support as a second step, but in this first step, you
should already start using ioremap to get the virtual address of the
clock controller, rather than hardcoding it.
Arnd
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/5] clk: mmp: add clock definition for pxa910
2012-07-31 6:39 [PATCH 1/5] clk: mmp: add mmp specific clocks Chao Xie
2012-07-31 6:39 ` [PATCH 2/5] clk: mmp: add clock definition for pxa168 Chao Xie
@ 2012-07-31 6:39 ` Chao Xie
2012-07-31 6:39 ` [PATCH 4/5] clk: mmp: add clock definition for mmp2 Chao Xie
2012-07-31 11:47 ` [PATCH 1/5] clk: mmp: add mmp specific clocks Arnd Bergmann
3 siblings, 0 replies; 8+ messages in thread
From: Chao Xie @ 2012-07-31 6:39 UTC (permalink / raw)
To: linux-arm-kernel
From: Chao Xie <chao.xie@marvell.com>
Initialize the clocks for pxa910
Signed-off-by: Chao Xie <xiechao.mail@gmail.com>
---
drivers/clk/mmp/Makefile | 1 +
drivers/clk/mmp/clk-pxa910.c | 249 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 250 insertions(+), 0 deletions(-)
create mode 100644 drivers/clk/mmp/clk-pxa910.c
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 8bbf882..4fe1d15 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -5,3 +5,4 @@
obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-pll2.o
obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
+obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
new file mode 100644
index 0000000..7522883
--- /dev/null
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -0,0 +1,249 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+
+#include <mach/addr-map.h>
+
+#include "clk.h"
+
+#define APBC_RTC APBC_REG(0x28)
+#define APBC_TWSI0 APBC_REG(0x2c)
+#define APBC_KPC APBC_REG(0x30)
+#define APBC_UART0 APBC_REG(0x00)
+#define APBC_UART1 APBC_REG(0x04)
+#define APBC_GPIO APBC_REG(0x08)
+#define APBC_PWM0 APBC_REG(0x0c)
+#define APBC_PWM1 APBC_REG(0x10)
+#define APBC_PWM2 APBC_REG(0x14)
+#define APBC_PWM3 APBC_REG(0x18)
+#define APBC_SSP0 APBC_REG(0x1c)
+#define APBC_SSP1 APBC_REG(0x20)
+#define APBC_SSP2 APBC_REG(0x4c)
+#define APBC_TWSI1 APBCP_REG(0x28)
+#define APBC_UART2 APBCP_REG(0x1c)
+
+#define APMU_SDH0 APMU_REG(0x54)
+#define APMU_SDH1 APMU_REG(0x58)
+#define APMU_USB APMU_REG(0x5c)
+#define APMU_DISP0 APMU_REG(0x4c)
+#define APMU_CCIC0 APMU_REG(0x50)
+#define APMU_DFC APMU_REG(0x60)
+
+static DEFINE_SPINLOCK(mmp_clk_lock);
+
+enum pll_clk {
+ clk32,
+ pll1, pll1_2, pll1_4, pll1_8, pll1_16,
+ pll1_6, pll1_12, pll1_24, pll1_48, pll1_96,
+ pll1_13, pll1_13_1_5, pll1_2_1_5, pll1_3_16,
+ pll2,
+ vctcxo,
+ uart_pll,
+ pll_max,
+};
+
+enum apbc_clk {
+ uart0_clk, uart1_clk, uart2_clk,
+ pwm0_clk, pwm1_clk, pwm2_clk, pwm3_clk,
+ twsi0_clk, twsi1_clk,
+ ssp0_clk, ssp1_clk, ssp2_clk,
+ gpio_clk, kpc_clk, rtc_clk,
+ uart0_mux_clk, uart1_mux_clk, uart2_mux_clk,
+ ssp0_mux_clk, ssp1_mux_clk, ssp2_mux_clk,
+ apbc_max,
+};
+
+enum apmu_clk {
+ sdh0_mux_clk, sdh1_mux_clk,
+ sdh0_clk, sdh1_clk,
+ dfc_clk,
+ usb_clk, sph_clk,
+ disp0_mux_clk, disp0_clk,
+ ccic0_mux_clk, ccic0_clk,
+ ccic0_phy_mux_clk, ccic0_phy_clk, ccic0_sphy_div_clk, ccic0_sphy_clk,
+ apmu_max,
+};
+
+static struct clk_factor_masks factor_masks = {
+ .num_mask = 0x1fff,
+ .den_mask = 0x1fff,
+ .num_shift = 16,
+ .den_shift = 0,
+};
+
+static struct clk_factor_tbl factor_tbl[] = {
+ {.num = 8125, .den = 1536}, /* 14.745MHZ */
+};
+
+static const char *uart_parent[] = {"pll1_3_16", "uart_pll"};
+static const char *ssp_parent[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"};
+static const char *sdh_parent[] = {"pll1_12", "pll1_13"};
+static const char *disp_parent[] = {"pll1_2", "pll1_12"};
+static const char *ccic_parent[] = {"pll1_2", "pll1_12"};
+static const char *ccic_phy_parent[] = {"pll1_6", "pll1_12"};
+
+void __init pxa910_clk_init(void)
+{
+ struct clk *pll_clks[pll_max];
+ struct clk *apbc_clks[apbc_max];
+ struct clk *apmu_clks[apmu_max];
+ /* all root clocks */
+ MMP_CLK_REGISTER_FIXED_RATE(pll_clks, clk32, 32000);
+ MMP_CLK_REGISTER_FIXED_RATE(pll_clks, vctcxo, 26000000);
+ MMP_CLK_REGISTER_FIXED_RATE(pll_clks, pll1, 624000000);
+ pll_clks[pll2] = mmp_clk_register_pll2("pll2", "vctcxo", 0);
+ clk_register_clkdev(pll_clks[pll2], NULL, "pll2");
+
+ /* PLL1 */
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_2, pll1,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_4, pll1_2,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_8, pll1_4,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_16, pll1_8,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_6, pll1_2,
+ CLK_SET_RATE_PARENT, 1, 3);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_12, pll1_6,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_24, pll1_12,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_48, pll1_24,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_96, pll1_48,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_13, pll1,
+ CLK_SET_RATE_PARENT, 1, 13);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_13_1_5, pll1_13,
+ CLK_SET_RATE_PARENT, 2, 3);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_2_1_5, pll1_2,
+ CLK_SET_RATE_PARENT, 2, 3);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_3_16, pll1,
+ CLK_SET_RATE_PARENT, 3, 16);
+ pll_clks[uart_pll] = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
+ MPMU_REG(0x14), &factor_masks, factor_tbl,
+ ARRAY_SIZE(factor_tbl));
+ clk_set_rate(pll_clks[uart_pll], 14745600);
+ /* PLL2 */
+
+ /* APBC devices without mux parent */
+ MMP_CLK_REGISTER_APBC(apbc_clks, twsi0_clk, pll1_13_1_5, 10,
+ APBC_TWSI0, 0, "pxa2xx-i2c.0", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, twsi1_clk, pll1_13_1_5, 10,
+ APBC_TWSI1, 0, "pxa2xx-i2c.1", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, gpio_clk, vctcxo, 10,
+ APBC_GPIO, 0, "pxa-gpio", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, kpc_clk, clk32k, 10,
+ APBC_KPC, 0, "pxa27x-keypad", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, rtc_clk, clk32k, 10,
+ APBC_RTC, APBC_POWER_CTRL, "sa1100-rtc", NULL,
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, pwm0_clk, pll1_48, 10,
+ APBC_PWM0, 0, "pxa168-pwm.0", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, pwm1_clk, pll1_48, 10,
+ APBC_PWM1, 0, "pxa168-pwm.1", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, pwm2_clk, pll1_48, 10,
+ APBC_PWM2, 0, "pxa168-pwm.2", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, pwm3_clk, pll1_48, 10,
+ APBC_PWM3, 0, "pxa168-pwm.3", NULL, &mmp_clk_lock);
+
+ /* APBC devices with mux parent */
+ MMP_CLK_REGISTER_MUX(apbc_clks, uart0_mux_clk, uart_parent,
+ ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
+ APBC_UART0, 4, 3, 0, NULL, "uart_mux.0",
+ &mmp_clk_lock);
+ clk_set_parent(apbc_clks[uart0_mux_clk], pll_clks[uart_pll]);
+ MMP_CLK_REGISTER_APBC(apbc_clks, uart0_clk, uart0_mux_clk, 10,
+ APBC_UART0, 0, "pxa2xx-uart.0", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, uart1_mux_clk, uart_parent,
+ ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
+ APBC_UART1, 4, 3, 0, NULL, "uart_mux.1",
+ &mmp_clk_lock);
+ clk_set_parent(apbc_clks[uart1_mux_clk], pll_clks[uart_pll]);
+ MMP_CLK_REGISTER_APBC(apbc_clks, uart1_clk, uart1_mux_clk, 10,
+ APBC_UART1, 0, "pxa2xx-uart.1", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, uart2_mux_clk, uart_parent,
+ ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
+ APBC_UART2, 4, 3, 0, NULL, "uart_mux.2",
+ &mmp_clk_lock);
+ clk_set_parent(apbc_clks[uart2_mux_clk], pll_clks[uart_pll]);
+ MMP_CLK_REGISTER_APBC(apbc_clks, uart2_clk, uart2_mux_clk, 10,
+ APBC_UART2, 0, "pxa2xx-uart.2", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, ssp0_mux_clk, ssp_parent,
+ ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
+ APBC_SSP0, 4, 3, 0, NULL, "ssp_mux.0", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, ssp0_clk, ssp0_mux_clk, 10,
+ APBC_SSP0, 0, "pxa168-ssp.0", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, ssp1_mux_clk, ssp_parent,
+ ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
+ APBC_SSP1, 4, 3, 0, NULL, "ssp_mux.1", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, ssp1_clk, ssp1_mux_clk, 10,
+ APBC_SSP1, 0, "pxa168-ssp.1", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, ssp2_mux_clk, ssp_parent,
+ ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
+ APBC_SSP2, 4, 3, 0, NULL, "ssp_mux.2", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, ssp2_clk, ssp2_mux_clk, 10,
+ APBC_SSP2, 0, "pxa168-ssp.2", NULL, &mmp_clk_lock);
+
+ /* APMU devices */
+ /* nand */
+ MMP_CLK_REGISTER_APMU(apmu_clks, dfc_clk, pll1_4, APMU_DFC,
+ 0x19b, "pxa3xx-nand.0", NULL, &mmp_clk_lock);
+ /* sdh */
+ MMP_CLK_REGISTER_MUX(apmu_clks, sdh0_mux_clk, sdh_parent,
+ ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT,
+ APMU_SDH0, 6, 1, 0, NULL, "sdh_mux.0", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, sdh0_clk, sdh_mux_clk, APMU_SDH0,
+ 0x1b, "sdhci-pxa.0", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apmu_clks, sdh1_mux_clk, sdh_parent,
+ ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT,
+ APMU_SDH1, 6, 1, 0, NULL, "sdh_mux.1", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, sdh1_clk, sdh1_mux_clk, APMU_SDH1,
+ 0x1b, "sdhci-pxa.1", NULL, &mmp_clk_lock);
+
+ /* usb */
+ MMP_CLK_REGISTER_APMU(apmu_clks, usb_clk, usb_pll, APMU_USB,
+ 0x9, NULL, "usb-clk", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, sph_clk, usb_pll, APMU_USB,
+ 0x12, NULL, "sph-clk", &mmp_clk_lock);
+
+ /* display */
+ MMP_CLK_REGISTER_MUX(apmu_clks, disp0_mux_clk, disp_parent,
+ ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT,
+ APMU_DISP0, 6, 1, 0, NULL, "disp_mux.0",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, disp0_clk, disp0_mux_clk, APMU_DISP0,
+ 0x1b, "mmp-disp.0", "fnclk", &mmp_clk_lock);
+
+ /* ccic */
+ MMP_CLK_REGISTER_MUX(apmu_clks, ccic0_mux_clk, ccic_parent,
+ ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT,
+ APMU_CCIC0, 6, 1, 0, NULL, "ccic_mux.0",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, ccic0_clk, ccic0_mux_clk, APMU_CCIC0,
+ 0x1b, "mmp-ccic.0", "fnclk", &mmp_clk_lock);
+ MMP_CLK_REGISTER_MUX(apmu_clks, ccic0_phy_mux_clk, ccic_phy_parent,
+ ARRAY_SIZE(ccic_phy_parent), CLK_SET_RATE_PARENT,
+ APMU_CCIC0, 7, 1, 0, NULL, "ccic_phy_mux.0",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, ccic0_phy_clk, ccic0_phy_mux_clk,
+ APMU_CCIC0, 0x24, "mmp-ccic.0", "phyclk",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_DIV(apmu_clks, ccic0_sphy_div_clk, ccic0_mux_clk,
+ 0, APMU_CCIC0, 10, 5, 0,
+ "mmp-ccic.0", "sphyclk_div", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, ccic0_sphy_clk, ccic0_sphy_div_clk,
+ APMU_CCIC0, 0x300, "mmp-ccic.0", "sphyclk",
+ &mmp_clk_lock);
+
+}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/5] clk: mmp: add clock definition for mmp2
2012-07-31 6:39 [PATCH 1/5] clk: mmp: add mmp specific clocks Chao Xie
2012-07-31 6:39 ` [PATCH 2/5] clk: mmp: add clock definition for pxa168 Chao Xie
2012-07-31 6:39 ` [PATCH 3/5] clk: mmp: add clock definition for pxa910 Chao Xie
@ 2012-07-31 6:39 ` Chao Xie
2012-07-31 11:47 ` [PATCH 1/5] clk: mmp: add mmp specific clocks Arnd Bergmann
3 siblings, 0 replies; 8+ messages in thread
From: Chao Xie @ 2012-07-31 6:39 UTC (permalink / raw)
To: linux-arm-kernel
From: Chao Xie <chao.xie@marvell.com>
Initialize the clocks for mmp2
Signed-off-by: Chao Xie <xiechao.mail@gmail.com>
---
drivers/clk/mmp/Makefile | 1 +
drivers/clk/mmp/clk-mmp2.c | 337 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 338 insertions(+), 0 deletions(-)
create mode 100644 drivers/clk/mmp/clk-mmp2.c
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 4fe1d15..12845e0 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -6,3 +6,4 @@ obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-pll2.o
obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
+obj-$(CONFIG_CPU_MMP2) += clk-mmp2.o
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
new file mode 100644
index 0000000..6196e13
--- /dev/null
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -0,0 +1,337 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+
+#include <mach/addr-map.h>
+
+#include "clk.h"
+
+#define APBC_RTC APBC_REG(0x00)
+#define APBC_TWSI0 APBC_REG(0x04)
+#define APBC_TWSI1 APBC_REG(0x08)
+#define APBC_TWSI2 APBC_REG(0x0c)
+#define APBC_TWSI3 APBC_REG(0x10)
+#define APBC_TWSI4 APBC_REG(0x7c)
+#define APBC_TWSI5 APBC_REG(0x80)
+#define APBC_KPC APBC_REG(0x18)
+#define APBC_UART0 APBC_REG(0x2c)
+#define APBC_UART1 APBC_REG(0x30)
+#define APBC_UART2 APBC_REG(0x34)
+#define APBC_UART3 APBC_REG(0x88)
+#define APBC_GPIO APBC_REG(0x38)
+#define APBC_PWM0 APBC_REG(0x3c)
+#define APBC_PWM1 APBC_REG(0x40)
+#define APBC_PWM2 APBC_REG(0x44)
+#define APBC_PWM3 APBC_REG(0x48)
+#define APBC_SSP0 APBC_REG(0x50)
+#define APBC_SSP1 APBC_REG(0x54)
+#define APBC_SSP2 APBC_REG(0x58)
+#define APBC_SSP3 APBC_REG(0x5c)
+
+#define APMU_SDH0 APMU_REG(0x54)
+#define APMU_SDH1 APMU_REG(0x58)
+#define APMU_SDH2 APMU_REG(0xe8)
+#define APMU_SDH3 APMU_REG(0xec)
+#define APMU_USB APMU_REG(0x5c)
+#define APMU_DISP0 APMU_REG(0x4c)
+#define APMU_DISP1 APMU_REG(0x110)
+#define APMU_CCIC0 APMU_REG(0x50)
+#define APMU_CCIC1 APMU_REG(0xf4)
+
+static DEFINE_SPINLOCK(mmp_clk_lock);
+
+enum pll_clk {
+ clk32,
+ pll1, pll1_2, pll1_4, pll1_8, pll1_16,
+ pll1_20, pll1_3, pll1_6, pll1_12,
+ pll2, pll2_2, pll2_4, pll2_8, pll2_16,
+ pll2_3, pll2_6, pll2_12,
+ vctcxo, vctcxo_2, vctcxo_4,
+ usb_pll, uart_pll,
+ pll_max,
+};
+
+enum apbc_clk {
+ uart0_clk, uart1_clk, uart2_clk, uart3_clk,
+ pwm0_clk, pwm1_clk, pwm2_clk, pwm3_clk,
+ twsi0_clk, twsi1_clk, twsi2_clk, twsi3_clk, twsi4_clk, twsi5_clk,
+ ssp0_clk, ssp1_clk, ssp2_clk, ssp3_clk,
+ gpio_clk, kpc_clk, rtc_clk,
+ uart0_mux_clk, uart1_mux_clk, uart2_mux_clk, uart3_mux_clk,
+ ssp0_mux_clk, ssp1_mux_clk, ssp2_mux_clk, ssp3_mux_clk,
+ apbc_max,
+};
+
+enum apmu_clk {
+ sdh_mux_clk, sdh_div_clk,
+ sdh0_clk, sdh1_clk, sdh2_clk, sdh3_clk,
+ usb_clk,
+ disp0_mux_clk, disp1_mux_clk,
+ disp0_div_clk, disp1_div_clk, disp0_sphy_div_clk,
+ disp0_clk, disp1_clk, disp0_sphy_clk,
+ ccic_arbiter_clk,
+ ccic0_mux_clk, ccic1_mux_clk,
+ ccic0_div_clk, ccic1_div_clk, ccic0_sphy_div_clk, ccic1_sphy_div_clk,
+ ccic0_phy_clk, ccic1_phy_clk, ccic0_sphy_clk, ccic1_sphy_clk,
+ ccic0_clk, ccic1_clk,
+ apmu_max,
+};
+
+static struct clk_factor_masks factor_masks = {
+ .num_mask = 0x1fff,
+ .den_mask = 0x1fff,
+ .num_shift = 16,
+ .den_shift = 0,
+};
+
+static struct clk_factor_tbl factor_tbl[] = {
+ {.num = 14634, .den = 2165}, /* 14.745MHZ */
+ {.num = 3521, .den = 689}, /* 19.23MHZ */
+ {.num = 9679, .den = 5728}, /* 58.9824MHZ */
+ {.num = 15850, .den = 9451}, /* 59.429 */
+};
+
+static const char *uart_parent[] = {"uart_pll", "vctcxo"};
+static const char *ssp_parent[] = {"vctcxo_4", "vctcxo_2", "vctcxo",
+ "pll1_16"};
+static const char *sdh_parent[] = {"pll1_4", "pll2", "usb_pll", "pll1"};
+static const char *disp_parent[] = {"pll1", "pll1_16", "pll2", "vctcxo"};
+static const char *ccic_parent[] = {"pll1_2", "pll1_16", "vctcxo"};
+
+void __init mmp2_clk_init(void)
+{
+ struct clk *pll_clks[pll_max];
+ struct clk *apbc_clks[apbc_max];
+ struct clk *apmu_clks[apmu_max];
+ /* all root clocks */
+ MMP_CLK_REGISTER_FIXED_RATE(pll_clks, clk32, 32000);
+ MMP_CLK_REGISTER_FIXED_RATE(pll_clks, vctcxo, 26000000);
+ MMP_CLK_REGISTER_FIXED_RATE(pll_clks, pll1, 800000000);
+ MMP_CLK_REGISTER_FIXED_RATE(pll_clks, usb_pll, 480000000);
+ pll_clks[pll2] = mmp_clk_register_pll2("pll2", "vctcxo", 0);
+ clk_register_clkdev(pll_clks[pll2], NULL, "pll2");
+
+ /* PLL1 */
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_2, pll1,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_4, pll1_2,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_8, pll1_4,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_16, pll1_8,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_20, pll1_4,
+ CLK_SET_RATE_PARENT, 1, 5);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_3, pll1,
+ CLK_SET_RATE_PARENT, 1, 3);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_6, pll1_3,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll1_12, pll1_6,
+ CLK_SET_RATE_PARENT, 1, 2);
+ pll_clks[uart_pll] = mmp_clk_register_factor("uart_pll", "pll_4", 0,
+ MPMU_REG(0x14), &factor_masks, factor_tbl,
+ ARRAY_SIZE(factor_tbl));
+ /* PLL2 */
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll2_2, pll2,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll2_4, pll2_2,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll2_8, pll2_4,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll2_16, pll2_8,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll2_3, pll2,
+ CLK_SET_RATE_PARENT, 1, 3);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll2_6, pll2_3,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, pll2_12, pll2_6,
+ CLK_SET_RATE_PARENT, 1, 2);
+
+ /* vctcxo */
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, vctcxo_2, vctcxo,
+ CLK_SET_RATE_PARENT, 1, 2);
+ MMP_CLK_REGISTER_FIXED_FACTOR(pll_clks, vctcxo_4, vctcxo_2,
+ CLK_SET_RATE_PARENT, 1, 2);
+
+ /* APBC devices without mux parent */
+ MMP_CLK_REGISTER_APBC(apbc_clks, twsi0_clk, vctcxo, 10,
+ APBC_TWSI0, 0, "pxa2xx-i2c.0", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, twsi1_clk, vctcxo, 10,
+ APBC_TWSI1, 0, "pxa2xx-i2c.1", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, twsi2_clk, vctcxo, 10,
+ APBC_TWSI2, 0, "pxa2xx-i2c.2", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, twsi3_clk, vctcxo, 10,
+ APBC_TWSI3, 0, "pxa2xx-i2c.3", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, twsi4_clk, vctcxo, 10,
+ APBC_TWSI4, 0, "pxa2xx-i2c.4", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, twsi5_clk, vctcxo, 10,
+ APBC_TWSI5, 0, "pxa2xx-i2c.5", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, gpio_clk, vctcxo, 10,
+ APBC_GPIO, 0, "pxa-gpio", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, kpc_clk, clk32k, 10,
+ APBC_KPC, 0, "pxa27x-keypad", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, rtc_clk, clk32k, 10,
+ APBC_RTC, 0, "mmp-rtc", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, pwm0_clk, vctcxo, 10,
+ APBC_PWM0, 0, "mmp2-pwm.0", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, pwm1_clk, vctcxo, 10,
+ APBC_PWM1, 0, "mmp2-pwm.1", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, pwm2_clk, vctcxo, 10,
+ APBC_PWM2, 0, "mmp2-pwm.2", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, pwm3_clk, vctcxo, 10,
+ APBC_PWM3, 0, "mmp2-pwm.3", NULL, &mmp_clk_lock);
+
+ /* APBC devices with mux parent */
+ MMP_CLK_REGISTER_MUX(apbc_clks, uart0_mux_clk, uart_parent,
+ ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
+ APBC_UART0, 4, 3, 0, NULL, "uart_mux.0",
+ &mmp_clk_lock);
+ clk_set_parent(apbc_clks[uart0_mux_clk], pll_clks[vctcxo]);
+ MMP_CLK_REGISTER_APBC(apbc_clks, uart0_clk, uart0_mux_clk, 10,
+ APBC_UART0, 0, "pxa2xx-uart.0", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, uart1_mux_clk, uart_parent,
+ ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
+ APBC_UART1, 4, 3, 0, NULL, "uart_mux.1",
+ &mmp_clk_lock);
+ clk_set_parent(apbc_clks[uart1_mux_clk], pll_clks[vctcxo]);
+ MMP_CLK_REGISTER_APBC(apbc_clks, uart1_clk, uart1_mux_clk, 10,
+ APBC_UART1, 0, "pxa2xx-uart.1", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, uart2_mux_clk, uart_parent,
+ ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
+ APBC_UART2, 4, 3, 0, NULL, "uart_mux.2",
+ &mmp_clk_lock);
+ clk_set_parent(apbc_clks[uart2_mux_clk], pll_clks[vctcxo]);
+ MMP_CLK_REGISTER_APBC(apbc_clks, uart2_clk, uart2_mux_clk, 10,
+ APBC_UART2, 0, "pxa2xx-uart.2", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, uart3_mux_clk, uart_parent,
+ ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
+ APBC_UART3, 4, 3, 0, NULL, "uart_mux.3",
+ &mmp_clk_lock);
+ clk_set_parent(apbc_clks[uart3_mux_clk], pll_clks[vctcxo]);
+ MMP_CLK_REGISTER_APBC(apbc_clks, uart3_clk, uart3_mux_clk, 10,
+ APBC_UART3, 0, "pxa2xx-uart.3", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, ssp0_mux_clk, ssp_parent,
+ ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
+ APBC_SSP0, 4, 3, 0, NULL, "ssp_mux.0", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, ssp0_clk, ssp0_mux_clk, 10,
+ APBC_SSP0, 0, "mmp-ssp.0", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, ssp1_mux_clk, ssp_parent,
+ ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
+ APBC_SSP1, 4, 3, 0, NULL, "ssp_mux.1", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, ssp1_clk, ssp1_mux_clk, 10,
+ APBC_SSP1, 0, "mmp-ssp.1", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, ssp2_mux_clk, ssp_parent,
+ ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
+ APBC_SSP2, 4, 3, 0, NULL, "ssp_mux.2", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, ssp2_clk, ssp2_mux_clk, 10,
+ APBC_SSP2, 0, "mmp-ssp.2", NULL, &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apbc_clks, ssp3_mux_clk, ssp_parent,
+ ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
+ APBC_SSP3, 4, 3, 0, NULL, "ssp_mux.3", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APBC(apbc_clks, ssp3_clk, ssp3_mux_clk, 10,
+ APBC_SSP3, 0, "mmp-ssp.3", NULL, &mmp_clk_lock);
+
+ /* APMU devices */
+ /* sdh */
+ MMP_CLK_REGISTER_MUX(apmu_clks, sdh_mux_clk, sdh_parent,
+ ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT,
+ APMU_SDH0, 8, 2, 0, NULL, "sdh_mux", &mmp_clk_lock);
+ MMP_CLK_REGISTER_DIV(apmu_clks, sdh_div_clk, sdh_mux_clk,
+ CLK_SET_RATE_PARENT, APMU_SDH0, 10, 4,
+ CLK_DIVIDER_ONE_BASED, NULL, "sdh_div", &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_APMU(apmu_clks, sdh0_clk, sdh_div_clk, APMU_SDH0,
+ 0x1b, "sdhci-pxav3.0", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, sdh1_clk, sdh_div_clk, APMU_SDH1,
+ 0x1b, "sdhci-pxav3.1", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, sdh2_clk, sdh_div_clk, APMU_SDH2,
+ 0x1b, "sdhci-pxav3.2", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, sdh3_clk, sdh_div_clk, APMU_SDH3,
+ 0x1b, "sdhci-pxav3.3", NULL, &mmp_clk_lock);
+
+ /* usb */
+ MMP_CLK_REGISTER_APMU(apmu_clks, usb_clk, usb_pll, APMU_USB,
+ 0x9, NULL, "usb-clk", &mmp_clk_lock);
+
+ /* display */
+ MMP_CLK_REGISTER_MUX(apmu_clks, disp0_mux_clk, disp_parent,
+ ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT,
+ APMU_DISP0, 6, 2, 0, NULL, "disp_mux.0",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_DIV(apmu_clks, disp0_div_clk, disp0_mux_clk,
+ CLK_SET_RATE_PARENT, APMU_DISP0, 8, 4,
+ CLK_DIVIDER_ONE_BASED, NULL, "disp_div.0",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, disp0_clk, disp0_div_clk, APMU_DISP0,
+ 0x1b, "mmp-disp.0", NULL, &mmp_clk_lock);
+ MMP_CLK_REGISTER_DIV(apmu_clks, disp0_sphy_div_clk, disp0_mux_clk,
+ 0, APMU_DISP0, 15, 5,
+ 0, NULL, "disp0_sphy_div", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, disp0_sphy_clk, disp0_sphy_div_clk,
+ APMU_DISP0, 0x1024, NULL, "disp0_sphy", &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apmu_clks, disp1_mux_clk, disp_parent,
+ ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT,
+ APMU_DISP1, 6, 2, 0, NULL, "disp_mux.0",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_DIV(apmu_clks, disp1_div_clk, disp1_mux_clk,
+ CLK_SET_RATE_PARENT, APMU_DISP1, 8, 4,
+ CLK_DIVIDER_ONE_BASED, NULL, "disp_div.0",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, disp1_clk, disp1_div_clk, APMU_DISP1,
+ 0x1b, "mmp-disp.1", NULL, &mmp_clk_lock);
+
+ /* ccic */
+ MMP_CLK_REGISTER_APMU(apmu_clks, ccic_arbiter_clk, vctcxo,
+ APMU_CCIC0, 0x1800, NULL, "ccic_arbiter",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_MUX(apmu_clks, ccic0_mux_clk, ccic_parent,
+ ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT,
+ APMU_CCIC0, 6, 2, 0, NULL, "ccic_mux.0",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_DIV(apmu_clks, ccic0_div_clk, ccic0_mux_clk,
+ CLK_SET_RATE_PARENT, APMU_CCIC0, 17, 4,
+ CLK_DIVIDER_ONE_BASED, NULL, "ccic_div.0",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, ccic0_clk, ccic0_div_clk, APMU_CCIC0,
+ 0x1b, "mmp-ccic.0", "fnclk", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, ccic0_phy_clk, ccic0_div_clk,
+ APMU_CCIC0, 0x24, "mmp-ccic.0", "phyclk",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_DIV(apmu_clks, ccic0_sphy_div_clk, ccic0_div_clk,
+ 0, APMU_CCIC0, 10, 5, 0,
+ "mmp-ccic.0", "sphyclk_div", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, ccic0_sphy_clk, ccic0_sphy_div_clk,
+ APMU_CCIC0, 0x300, "mmp-ccic.0", "sphyclk",
+ &mmp_clk_lock);
+
+ MMP_CLK_REGISTER_MUX(apmu_clks, ccic1_mux_clk, ccic_parent,
+ ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT,
+ APMU_CCIC1, 6, 2, 0, NULL, "ccic_mux.1",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_DIV(apmu_clks, ccic1_div_clk, ccic1_mux_clk,
+ CLK_SET_RATE_PARENT, APMU_CCIC1, 16, 4,
+ CLK_DIVIDER_ONE_BASED, NULL, "ccic_div.1",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, ccic1_clk, ccic1_div_clk, APMU_CCIC1,
+ 0x1b, "mmp-ccic.1", "fnclk", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, ccic1_phy_clk, ccic1_div_clk,
+ APMU_CCIC0, 0x24, "mmp-ccic.1", "phyclk",
+ &mmp_clk_lock);
+ MMP_CLK_REGISTER_DIV(apmu_clks, ccic1_sphy_div_clk, ccic1_div_clk,
+ 0, APMU_CCIC1, 10, 5, 0,
+ "mmp-ccic.1", "sphyclk_div", &mmp_clk_lock);
+ MMP_CLK_REGISTER_APMU(apmu_clks, ccic1_sphy_clk, ccic1_sphy_div_clk,
+ APMU_CCIC1, 0x300, "mmp-ccic.1", "sphyclk",
+ &mmp_clk_lock);
+}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 1/5] clk: mmp: add mmp specific clocks
2012-07-31 6:39 [PATCH 1/5] clk: mmp: add mmp specific clocks Chao Xie
` (2 preceding siblings ...)
2012-07-31 6:39 ` [PATCH 4/5] clk: mmp: add clock definition for mmp2 Chao Xie
@ 2012-07-31 11:47 ` Arnd Bergmann
3 siblings, 0 replies; 8+ messages in thread
From: Arnd Bergmann @ 2012-07-31 11:47 UTC (permalink / raw)
To: linux-arm-kernel
On Tuesday 31 July 2012, Chao Xie wrote:
> +static int clk_apbc_prepare(struct clk_hw *hw)
> +{
> + struct clk_apbc *apbc = to_clk_apbc(hw);
> + unsigned int data;
> + unsigned long flags = 0;
> +
> + /*
> + * It may share same register as MUX clock,
> + * and it will impact FNCLK enable. Spinlock is needed
> + */
> + if (apbc->lock)
> + spin_lock_irqsave(apbc->lock, flags);
> +
> + data = __raw_readl(apbc->base);
> + if (apbc->flags & APBC_POWER_CTRL)
> + data |= APBC_POWER;
> + data |= APBC_FNCLK;
> + __raw_writel(data, apbc->base);
Better use readl_relaxed() in device drivers rather than __raw_readl().
> +#define MPMU_PLL2CR MPMU_REG(0x0034)
> +#define MPMU_PLL2_CTRL1 MPMU_REG(0x0414)
In a device driver like this, don't hardcode the MMIO register addresses. Instead,
use ioremap or of_iomap to get a virtual address from a resource or a DT
property that gets passed.
> +static int clk_pll2_prepare(struct clk_hw *hw)
> +{
> + unsigned long data;
> +
> + data = __raw_readl(MPMU_PLL2CR);
> + if (data & (1 << 8))
> + return 0;
> + data |= (1 << 8);
> + __raw_writel(data, MPMU_PLL2CR);
> +
> + udelay(500);
> +
> + if (cpu_is_mmp2()) {
> + /* out of reset */
> + data = __raw_readl(MPMU_PLL2_CTRL1);
> + data |= (1 << 29);
> + __raw_writel(data, MPMU_PLL2CR);
> +
> + udelay(500);
> + }
> +
> + return 0;
> +}
500 microsends is a long time to waste. Can you do an msleep(1)
instead so the CPU is allowed to sleep here?
The cpu_is_mmp2() check here looks a bit clumsy. I think you're
better off making this two separate functions like
static int pxa_clk_pll2_prepare(struct clk_hw *hw)
{
unsigned long data;
data = __raw_readl(MPMU_PLL2CR);
if (data & (1 << 8))
return 0;
data |= (1 << 8);
__raw_writel(data, MPMU_PLL2CR);
udelay(500);
return 0;
}
static int mmp2_clk_pll2_prepare(struct clk_hw *hw)
{
unsigned long data;
pxa_clk_pll2_prepare(hw);
/* out of reset */
data = __raw_readl(MPMU_PLL2_CTRL1);
data |= (1 << 29);
__raw_writel(data, MPMU_PLL2CR);
udelay(500);
return 0;
}
and then using two separate clk_ops structures but picking the one
you need based on the chip.
> +#define MMP_CLK_REGISTER_FIXED_RATE(_clk, _name, _rate) \
> + do { \
> + _clk[_name] = clk_register_fixed_rate(NULL, #_name, \
> + NULL, CLK_IS_ROOT, _rate); \
> + clk_register_clkdev(_clk[_name], #_name, NULL); \
> + } while (0)
> +
> +#define MMP_CLK_REGISTER_FIXED_FACTOR(_clk, _name, _parent, _flags, \
> + _mul, _div) \
> + do { \
> + _clk[_name] = clk_register_fixed_factor(NULL, #_name, \
> + #_parent, _flags, _mul, _div); \
> + clk_register_clkdev(_clk[_name], #_name, NULL); \
> + } while (0)
I very much dislike macros like these that don't add much value in terms of
shortening the code, but at the same time make the code much harder to read
by someone who is looking over all clock drivers. Better just open-code
all of the call sites of this.
Arnd
^ permalink raw reply [flat|nested] 8+ messages in thread