1 /* 2 * mmp2 clock framework source file 3 * 4 * Copyright (C) 2012 Marvell 5 * Chao Xie <xiechao.mail@gmail.com> 6 * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk> 7 * 8 * This file is licensed under the terms of the GNU General Public 9 * License version 2. This program is licensed "as is" without any 10 * warranty of any kind, whether express or implied. 11 */ 12 13 #include <linux/module.h> 14 #include <linux/kernel.h> 15 #include <linux/spinlock.h> 16 #include <linux/io.h> 17 #include <linux/delay.h> 18 #include <linux/err.h> 19 #include <linux/of_address.h> 20 21 #include <dt-bindings/clock/marvell,mmp2.h> 22 23 #include "clk.h" 24 #include "reset.h" 25 26 #define APBC_RTC 0x0 27 #define APBC_TWSI0 0x4 28 #define APBC_TWSI1 0x8 29 #define APBC_TWSI2 0xc 30 #define APBC_TWSI3 0x10 31 #define APBC_TWSI4 0x7c 32 #define APBC_TWSI5 0x80 33 #define APBC_KPC 0x18 34 #define APBC_TIMER 0x24 35 #define APBC_UART0 0x2c 36 #define APBC_UART1 0x30 37 #define APBC_UART2 0x34 38 #define APBC_UART3 0x88 39 #define APBC_GPIO 0x38 40 #define APBC_PWM0 0x3c 41 #define APBC_PWM1 0x40 42 #define APBC_PWM2 0x44 43 #define APBC_PWM3 0x48 44 #define APBC_SSP0 0x50 45 #define APBC_SSP1 0x54 46 #define APBC_SSP2 0x58 47 #define APBC_SSP3 0x5c 48 #define APMU_SDH0 0x54 49 #define APMU_SDH1 0x58 50 #define APMU_SDH2 0xe8 51 #define APMU_SDH3 0xec 52 #define APMU_SDH4 0x15c 53 #define APMU_USB 0x5c 54 #define APMU_DISP0 0x4c 55 #define APMU_DISP1 0x110 56 #define APMU_CCIC0 0x50 57 #define APMU_CCIC1 0xf4 58 #define APBC_THERMAL0 0x90 59 #define APBC_THERMAL1 0x98 60 #define APBC_THERMAL2 0x9c 61 #define APBC_THERMAL3 0xa0 62 #define APMU_USBHSIC0 0xf8 63 #define APMU_USBHSIC1 0xfc 64 #define APMU_GPU 0xcc 65 66 #define MPMU_FCCR 0x8 67 #define MPMU_POSR 0x10 68 #define MPMU_UART_PLL 0x14 69 #define MPMU_PLL2_CR 0x34 70 /* MMP3 specific below */ 71 #define MPMU_PLL3_CR 0x50 72 #define MPMU_PLL3_CTRL1 0x58 73 #define MPMU_PLL1_CTRL 0x5c 74 #define MPMU_PLL_DIFF_CTRL 0x68 75 #define MPMU_PLL2_CTRL1 0x414 76 77 enum mmp2_clk_model { 78 CLK_MODEL_MMP2, 79 CLK_MODEL_MMP3, 80 }; 81 82 struct mmp2_clk_unit { 83 struct mmp_clk_unit unit; 84 enum mmp2_clk_model model; 85 void __iomem *mpmu_base; 86 void __iomem *apmu_base; 87 void __iomem *apbc_base; 88 }; 89 90 static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { 91 {MMP2_CLK_CLK32, "clk32", NULL, 0, 32768}, 92 {MMP2_CLK_VCTCXO, "vctcxo", NULL, 0, 26000000}, 93 {MMP2_CLK_USB_PLL, "usb_pll", NULL, 0, 480000000}, 94 }; 95 96 static struct mmp_param_pll_clk pll_clks[] = { 97 {MMP2_CLK_PLL1, "pll1", 797330000, MPMU_FCCR, 0x4000, MPMU_POSR, 0}, 98 {MMP2_CLK_PLL2, "pll2", 0, MPMU_PLL2_CR, 0x0300, MPMU_PLL2_CR, 10}, 99 }; 100 101 static struct mmp_param_pll_clk mmp3_pll_clks[] = { 102 {MMP2_CLK_PLL2, "pll1", 797330000, MPMU_FCCR, 0x4000, MPMU_POSR, 0, 26000000, MPMU_PLL1_CTRL, 25}, 103 {MMP2_CLK_PLL2, "pll2", 0, MPMU_PLL2_CR, 0x0300, MPMU_PLL2_CR, 10, 26000000, MPMU_PLL2_CTRL1, 25}, 104 {MMP3_CLK_PLL1_P, "pll1_p", 0, MPMU_PLL_DIFF_CTRL, 0x0010, 0, 0, 797330000, MPMU_PLL_DIFF_CTRL, 0}, 105 {MMP3_CLK_PLL2_P, "pll2_p", 0, MPMU_PLL_DIFF_CTRL, 0x0100, MPMU_PLL2_CR, 10, 26000000, MPMU_PLL_DIFF_CTRL, 5}, 106 {MMP3_CLK_PLL3, "pll3", 0, MPMU_PLL3_CR, 0x0300, MPMU_PLL3_CR, 10, 26000000, MPMU_PLL3_CTRL1, 25}, 107 }; 108 109 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { 110 {MMP2_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0}, 111 {MMP2_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0}, 112 {MMP2_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0}, 113 {MMP2_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0}, 114 {MMP2_CLK_PLL1_20, "pll1_20", "pll1_4", 1, 5, 0}, 115 {MMP2_CLK_PLL1_3, "pll1_3", "pll1", 1, 3, 0}, 116 {MMP2_CLK_PLL1_6, "pll1_6", "pll1_3", 1, 2, 0}, 117 {MMP2_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0}, 118 {MMP2_CLK_PLL2_2, "pll2_2", "pll2", 1, 2, 0}, 119 {MMP2_CLK_PLL2_4, "pll2_4", "pll2_2", 1, 2, 0}, 120 {MMP2_CLK_PLL2_8, "pll2_8", "pll2_4", 1, 2, 0}, 121 {MMP2_CLK_PLL2_16, "pll2_16", "pll2_8", 1, 2, 0}, 122 {MMP2_CLK_PLL2_3, "pll2_3", "pll2", 1, 3, 0}, 123 {MMP2_CLK_PLL2_6, "pll2_6", "pll2_3", 1, 2, 0}, 124 {MMP2_CLK_PLL2_12, "pll2_12", "pll2_6", 1, 2, 0}, 125 {MMP2_CLK_VCTCXO_2, "vctcxo_2", "vctcxo", 1, 2, 0}, 126 {MMP2_CLK_VCTCXO_4, "vctcxo_4", "vctcxo_2", 1, 2, 0}, 127 }; 128 129 static struct mmp_clk_factor_masks uart_factor_masks = { 130 .factor = 2, 131 .num_mask = 0x1fff, 132 .den_mask = 0x1fff, 133 .num_shift = 16, 134 .den_shift = 0, 135 }; 136 137 static struct mmp_clk_factor_tbl uart_factor_tbl[] = { 138 {.num = 8125, .den = 1536}, /*14.745MHZ */ 139 {.num = 3521, .den = 689}, /*19.23MHZ */ 140 }; 141 142 static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit) 143 { 144 struct clk *clk; 145 struct mmp_clk_unit *unit = &pxa_unit->unit; 146 147 mmp_register_fixed_rate_clks(unit, fixed_rate_clks, 148 ARRAY_SIZE(fixed_rate_clks)); 149 150 if (pxa_unit->model == CLK_MODEL_MMP3) { 151 mmp_register_pll_clks(unit, mmp3_pll_clks, 152 pxa_unit->mpmu_base, 153 ARRAY_SIZE(mmp3_pll_clks)); 154 } else { 155 mmp_register_pll_clks(unit, pll_clks, 156 pxa_unit->mpmu_base, 157 ARRAY_SIZE(pll_clks)); 158 } 159 160 mmp_register_fixed_factor_clks(unit, fixed_factor_clks, 161 ARRAY_SIZE(fixed_factor_clks)); 162 163 clk = mmp_clk_register_factor("uart_pll", "pll1_4", 164 CLK_SET_RATE_PARENT, 165 pxa_unit->mpmu_base + MPMU_UART_PLL, 166 &uart_factor_masks, uart_factor_tbl, 167 ARRAY_SIZE(uart_factor_tbl), NULL); 168 mmp_clk_add(unit, MMP2_CLK_UART_PLL, clk); 169 } 170 171 static DEFINE_SPINLOCK(uart0_lock); 172 static DEFINE_SPINLOCK(uart1_lock); 173 static DEFINE_SPINLOCK(uart2_lock); 174 static const char * const uart_parent_names[] = {"uart_pll", "vctcxo"}; 175 176 static DEFINE_SPINLOCK(ssp0_lock); 177 static DEFINE_SPINLOCK(ssp1_lock); 178 static DEFINE_SPINLOCK(ssp2_lock); 179 static DEFINE_SPINLOCK(ssp3_lock); 180 static const char * const ssp_parent_names[] = {"vctcxo_4", "vctcxo_2", "vctcxo", "pll1_16"}; 181 182 static DEFINE_SPINLOCK(timer_lock); 183 static const char * const timer_parent_names[] = {"clk32", "vctcxo_4", "vctcxo_2", "vctcxo"}; 184 185 static DEFINE_SPINLOCK(reset_lock); 186 187 static struct mmp_param_mux_clk apbc_mux_clks[] = { 188 {0, "uart0_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART0, 4, 3, 0, &uart0_lock}, 189 {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART1, 4, 3, 0, &uart1_lock}, 190 {0, "uart2_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART2, 4, 3, 0, &uart2_lock}, 191 {0, "uart3_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART3, 4, 3, 0, &uart2_lock}, 192 {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP0, 4, 3, 0, &ssp0_lock}, 193 {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock}, 194 {0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, &ssp2_lock}, 195 {0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, &ssp3_lock}, 196 {0, "timer_mux", timer_parent_names, ARRAY_SIZE(timer_parent_names), CLK_SET_RATE_PARENT, APBC_TIMER, 4, 3, 0, &timer_lock}, 197 }; 198 199 static struct mmp_param_gate_clk apbc_gate_clks[] = { 200 {MMP2_CLK_TWSI0, "twsi0_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI0, 0x7, 0x3, 0x0, 0, &reset_lock}, 201 {MMP2_CLK_TWSI1, "twsi1_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI1, 0x7, 0x3, 0x0, 0, &reset_lock}, 202 {MMP2_CLK_TWSI2, "twsi2_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI2, 0x7, 0x3, 0x0, 0, &reset_lock}, 203 {MMP2_CLK_TWSI3, "twsi3_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI3, 0x7, 0x3, 0x0, 0, &reset_lock}, 204 {MMP2_CLK_TWSI4, "twsi4_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI4, 0x7, 0x3, 0x0, 0, &reset_lock}, 205 {MMP2_CLK_TWSI5, "twsi5_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI5, 0x7, 0x3, 0x0, 0, &reset_lock}, 206 {MMP2_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_GPIO, 0x7, 0x3, 0x0, 0, &reset_lock}, 207 {MMP2_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_KPC, 0x7, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock}, 208 {MMP2_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_RTC, 0x87, 0x83, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock}, 209 {MMP2_CLK_PWM0, "pwm0_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM0, 0x7, 0x3, 0x0, 0, &reset_lock}, 210 {MMP2_CLK_PWM1, "pwm1_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM1, 0x7, 0x3, 0x0, 0, &reset_lock}, 211 {MMP2_CLK_PWM2, "pwm2_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM2, 0x7, 0x3, 0x0, 0, &reset_lock}, 212 {MMP2_CLK_PWM3, "pwm3_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM3, 0x7, 0x3, 0x0, 0, &reset_lock}, 213 /* The gate clocks has mux parent. */ 214 {MMP2_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, APBC_UART0, 0x7, 0x3, 0x0, 0, &uart0_lock}, 215 {MMP2_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x7, 0x3, 0x0, 0, &uart1_lock}, 216 {MMP2_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, APBC_UART2, 0x7, 0x3, 0x0, 0, &uart2_lock}, 217 {MMP2_CLK_UART3, "uart3_clk", "uart3_mux", CLK_SET_RATE_PARENT, APBC_UART3, 0x7, 0x3, 0x0, 0, &uart2_lock}, 218 {MMP2_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, APBC_SSP0, 0x7, 0x3, 0x0, 0, &ssp0_lock}, 219 {MMP2_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x7, 0x3, 0x0, 0, &ssp1_lock}, 220 {MMP2_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 0x7, 0x3, 0x0, 0, &ssp2_lock}, 221 {MMP2_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 0x7, 0x3, 0x0, 0, &ssp3_lock}, 222 {MMP2_CLK_TIMER, "timer_clk", "timer_mux", CLK_SET_RATE_PARENT, APBC_TIMER, 0x7, 0x3, 0x0, 0, &timer_lock}, 223 {MMP2_CLK_THERMAL0, "thermal0_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_THERMAL0, 0x7, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock}, 224 }; 225 226 static struct mmp_param_gate_clk mmp3_apbc_gate_clks[] = { 227 {MMP3_CLK_THERMAL1, "thermal1_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_THERMAL1, 0x7, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock}, 228 {MMP3_CLK_THERMAL2, "thermal2_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_THERMAL2, 0x7, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock}, 229 {MMP3_CLK_THERMAL3, "thermal3_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_THERMAL3, 0x7, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock}, 230 }; 231 232 static void mmp2_apb_periph_clk_init(struct mmp2_clk_unit *pxa_unit) 233 { 234 struct mmp_clk_unit *unit = &pxa_unit->unit; 235 236 mmp_register_mux_clks(unit, apbc_mux_clks, pxa_unit->apbc_base, 237 ARRAY_SIZE(apbc_mux_clks)); 238 239 mmp_register_gate_clks(unit, apbc_gate_clks, pxa_unit->apbc_base, 240 ARRAY_SIZE(apbc_gate_clks)); 241 242 if (pxa_unit->model == CLK_MODEL_MMP3) { 243 mmp_register_gate_clks(unit, mmp3_apbc_gate_clks, pxa_unit->apbc_base, 244 ARRAY_SIZE(mmp3_apbc_gate_clks)); 245 } 246 } 247 248 static DEFINE_SPINLOCK(sdh_lock); 249 static const char * const sdh_parent_names[] = {"pll1_4", "pll2", "usb_pll", "pll1"}; 250 static struct mmp_clk_mix_config sdh_mix_config = { 251 .reg_info = DEFINE_MIX_REG_INFO(4, 10, 2, 8, 32), 252 }; 253 254 static DEFINE_SPINLOCK(usb_lock); 255 static DEFINE_SPINLOCK(usbhsic0_lock); 256 static DEFINE_SPINLOCK(usbhsic1_lock); 257 258 static DEFINE_SPINLOCK(disp0_lock); 259 static DEFINE_SPINLOCK(disp1_lock); 260 static const char * const disp_parent_names[] = {"pll1", "pll1_16", "pll2", "vctcxo"}; 261 262 static DEFINE_SPINLOCK(ccic0_lock); 263 static DEFINE_SPINLOCK(ccic1_lock); 264 static const char * const ccic_parent_names[] = {"pll1_2", "pll1_16", "vctcxo"}; 265 266 static DEFINE_SPINLOCK(gpu_lock); 267 static const char * const mmp2_gpu_gc_parent_names[] = {"pll1_2", "pll1_3", "pll2_2", "pll2_3", "pll2", "usb_pll"}; 268 static u32 mmp2_gpu_gc_parent_table[] = { 0x0000, 0x0040, 0x0080, 0x00c0, 0x1000, 0x1040 }; 269 static const char * const mmp2_gpu_bus_parent_names[] = {"pll1_4", "pll2", "pll2_2", "usb_pll"}; 270 static u32 mmp2_gpu_bus_parent_table[] = { 0x0000, 0x0020, 0x0030, 0x4020 }; 271 static const char * const mmp3_gpu_bus_parent_names[] = {"pll1_4", "pll1_6", "pll1_2", "pll2_2"}; 272 static const char * const mmp3_gpu_gc_parent_names[] = {"pll1", "pll2", "pll1_p", "pll2_p"}; 273 274 static struct mmp_clk_mix_config ccic0_mix_config = { 275 .reg_info = DEFINE_MIX_REG_INFO(4, 17, 2, 6, 32), 276 }; 277 static struct mmp_clk_mix_config ccic1_mix_config = { 278 .reg_info = DEFINE_MIX_REG_INFO(4, 16, 2, 6, 32), 279 }; 280 281 static struct mmp_param_mux_clk apmu_mux_clks[] = { 282 {MMP2_CLK_DISP0_MUX, "disp0_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP0, 6, 2, 0, &disp0_lock}, 283 {MMP2_CLK_DISP1_MUX, "disp1_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP1, 6, 2, 0, &disp1_lock}, 284 }; 285 286 static struct mmp_param_mux_clk mmp3_apmu_mux_clks[] = { 287 {0, "gpu_bus_mux", mmp3_gpu_bus_parent_names, ARRAY_SIZE(mmp3_gpu_bus_parent_names), 288 CLK_SET_RATE_PARENT, APMU_GPU, 4, 2, 0, &gpu_lock}, 289 {0, "gpu_3d_mux", mmp3_gpu_gc_parent_names, ARRAY_SIZE(mmp3_gpu_gc_parent_names), 290 CLK_SET_RATE_PARENT, APMU_GPU, 6, 2, 0, &gpu_lock}, 291 {0, "gpu_2d_mux", mmp3_gpu_gc_parent_names, ARRAY_SIZE(mmp3_gpu_gc_parent_names), 292 CLK_SET_RATE_PARENT, APMU_GPU, 12, 2, 0, &gpu_lock}, 293 }; 294 295 static struct mmp_param_div_clk apmu_div_clks[] = { 296 {0, "disp0_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 8, 4, 0, &disp0_lock}, 297 {0, "disp0_sphy_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 15, 5, 0, &disp0_lock}, 298 {0, "disp1_div", "disp1_mux", CLK_SET_RATE_PARENT, APMU_DISP1, 8, 4, 0, &disp1_lock}, 299 {0, "ccic0_sphy_div", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 10, 5, 0, &ccic0_lock}, 300 {0, "ccic1_sphy_div", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 10, 5, 0, &ccic1_lock}, 301 }; 302 303 static struct mmp_param_div_clk mmp3_apmu_div_clks[] = { 304 {0, "gpu_3d_div", "gpu_3d_mux", CLK_SET_RATE_PARENT, APMU_GPU, 24, 4, 0, &gpu_lock}, 305 {0, "gpu_2d_div", "gpu_2d_mux", CLK_SET_RATE_PARENT, APMU_GPU, 28, 4, 0, &gpu_lock}, 306 }; 307 308 static struct mmp_param_gate_clk apmu_gate_clks[] = { 309 {MMP2_CLK_USB, "usb_clk", "usb_pll", 0, APMU_USB, 0x9, 0x9, 0x0, 0, &usb_lock}, 310 {MMP2_CLK_USBHSIC0, "usbhsic0_clk", "usb_pll", 0, APMU_USBHSIC0, 0x1b, 0x1b, 0x0, 0, &usbhsic0_lock}, 311 {MMP2_CLK_USBHSIC1, "usbhsic1_clk", "usb_pll", 0, APMU_USBHSIC1, 0x1b, 0x1b, 0x0, 0, &usbhsic1_lock}, 312 /* The gate clocks has mux parent. */ 313 {MMP2_CLK_SDH0, "sdh0_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH0, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, 314 {MMP2_CLK_SDH1, "sdh1_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, 315 {MMP2_CLK_SDH2, "sdh2_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH2, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, 316 {MMP2_CLK_SDH3, "sdh3_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH3, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, 317 {MMP2_CLK_DISP0, "disp0_clk", "disp0_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x12, 0x12, 0x0, 0, &disp0_lock}, 318 {MMP2_CLK_DISP0_LCDC, "disp0_lcdc_clk", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 0x09, 0x09, 0x0, 0, &disp0_lock}, 319 {MMP2_CLK_DISP0_SPHY, "disp0_sphy_clk", "disp0_sphy_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1024, 0x1024, 0x0, 0, &disp0_lock}, 320 {MMP2_CLK_DISP1, "disp1_clk", "disp1_div", CLK_SET_RATE_PARENT, APMU_DISP1, 0x09, 0x09, 0x0, 0, &disp1_lock}, 321 {MMP2_CLK_CCIC_ARBITER, "ccic_arbiter", "vctcxo", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1800, 0x1800, 0x0, 0, &ccic0_lock}, 322 {MMP2_CLK_CCIC0, "ccic0_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock}, 323 {MMP2_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock}, 324 {MMP2_CLK_CCIC0_SPHY, "ccic0_sphy_clk", "ccic0_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x300, 0x300, 0x0, 0, &ccic0_lock}, 325 {MMP2_CLK_CCIC1, "ccic1_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x1b, 0x1b, 0x0, 0, &ccic1_lock}, 326 {MMP2_CLK_CCIC1_PHY, "ccic1_phy_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x24, 0x24, 0x0, 0, &ccic1_lock}, 327 {MMP2_CLK_CCIC1_SPHY, "ccic1_sphy_clk", "ccic1_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x300, 0x300, 0x0, 0, &ccic1_lock}, 328 {MMP2_CLK_GPU_BUS, "gpu_bus_clk", "gpu_bus_mux", CLK_SET_RATE_PARENT, APMU_GPU, 0xa, 0xa, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock}, 329 }; 330 331 static struct mmp_param_gate_clk mmp2_apmu_gate_clks[] = { 332 {MMP2_CLK_GPU_3D, "gpu_3d_clk", "gpu_3d_mux", CLK_SET_RATE_PARENT, APMU_GPU, 0x5, 0x5, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock}, 333 }; 334 335 static struct mmp_param_gate_clk mmp3_apmu_gate_clks[] = { 336 {MMP3_CLK_SDH4, "sdh4_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH4, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, 337 {MMP3_CLK_GPU_3D, "gpu_3d_clk", "gpu_3d_div", CLK_SET_RATE_PARENT, APMU_GPU, 0x5, 0x5, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock}, 338 {MMP3_CLK_GPU_2D, "gpu_2d_clk", "gpu_2d_div", CLK_SET_RATE_PARENT, APMU_GPU, 0x1c0000, 0x1c0000, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock}, 339 }; 340 341 static void mmp2_axi_periph_clk_init(struct mmp2_clk_unit *pxa_unit) 342 { 343 struct clk *clk; 344 struct mmp_clk_unit *unit = &pxa_unit->unit; 345 346 sdh_mix_config.reg_info.reg_clk_ctrl = pxa_unit->apmu_base + APMU_SDH0; 347 clk = mmp_clk_register_mix(NULL, "sdh_mix_clk", sdh_parent_names, 348 ARRAY_SIZE(sdh_parent_names), 349 CLK_SET_RATE_PARENT, 350 &sdh_mix_config, &sdh_lock); 351 352 ccic0_mix_config.reg_info.reg_clk_ctrl = pxa_unit->apmu_base + APMU_CCIC0; 353 clk = mmp_clk_register_mix(NULL, "ccic0_mix_clk", ccic_parent_names, 354 ARRAY_SIZE(ccic_parent_names), 355 CLK_SET_RATE_PARENT, 356 &ccic0_mix_config, &ccic0_lock); 357 mmp_clk_add(unit, MMP2_CLK_CCIC0_MIX, clk); 358 359 ccic1_mix_config.reg_info.reg_clk_ctrl = pxa_unit->apmu_base + APMU_CCIC1; 360 clk = mmp_clk_register_mix(NULL, "ccic1_mix_clk", ccic_parent_names, 361 ARRAY_SIZE(ccic_parent_names), 362 CLK_SET_RATE_PARENT, 363 &ccic1_mix_config, &ccic1_lock); 364 mmp_clk_add(unit, MMP2_CLK_CCIC1_MIX, clk); 365 366 mmp_register_mux_clks(unit, apmu_mux_clks, pxa_unit->apmu_base, 367 ARRAY_SIZE(apmu_mux_clks)); 368 369 mmp_register_div_clks(unit, apmu_div_clks, pxa_unit->apmu_base, 370 ARRAY_SIZE(apmu_div_clks)); 371 372 mmp_register_gate_clks(unit, apmu_gate_clks, pxa_unit->apmu_base, 373 ARRAY_SIZE(apmu_gate_clks)); 374 375 if (pxa_unit->model == CLK_MODEL_MMP3) { 376 mmp_register_mux_clks(unit, mmp3_apmu_mux_clks, pxa_unit->apmu_base, 377 ARRAY_SIZE(mmp3_apmu_mux_clks)); 378 379 mmp_register_div_clks(unit, mmp3_apmu_div_clks, pxa_unit->apmu_base, 380 ARRAY_SIZE(mmp3_apmu_div_clks)); 381 382 mmp_register_gate_clks(unit, mmp3_apmu_gate_clks, pxa_unit->apmu_base, 383 ARRAY_SIZE(mmp3_apmu_gate_clks)); 384 } else { 385 clk_register_mux_table(NULL, "gpu_3d_mux", mmp2_gpu_gc_parent_names, 386 ARRAY_SIZE(mmp2_gpu_gc_parent_names), 387 CLK_SET_RATE_PARENT, 388 pxa_unit->apmu_base + APMU_GPU, 389 0, 0x10c0, 0, 390 mmp2_gpu_gc_parent_table, &gpu_lock); 391 392 clk_register_mux_table(NULL, "gpu_bus_mux", mmp2_gpu_bus_parent_names, 393 ARRAY_SIZE(mmp2_gpu_bus_parent_names), 394 CLK_SET_RATE_PARENT, 395 pxa_unit->apmu_base + APMU_GPU, 396 0, 0x4030, 0, 397 mmp2_gpu_bus_parent_table, &gpu_lock); 398 399 mmp_register_gate_clks(unit, mmp2_apmu_gate_clks, pxa_unit->apmu_base, 400 ARRAY_SIZE(mmp2_apmu_gate_clks)); 401 } 402 } 403 404 static void mmp2_clk_reset_init(struct device_node *np, 405 struct mmp2_clk_unit *pxa_unit) 406 { 407 struct mmp_clk_reset_cell *cells; 408 int i, nr_resets; 409 410 nr_resets = ARRAY_SIZE(apbc_gate_clks); 411 cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL); 412 if (!cells) 413 return; 414 415 for (i = 0; i < nr_resets; i++) { 416 cells[i].clk_id = apbc_gate_clks[i].id; 417 cells[i].reg = pxa_unit->apbc_base + apbc_gate_clks[i].offset; 418 cells[i].flags = 0; 419 cells[i].lock = apbc_gate_clks[i].lock; 420 cells[i].bits = 0x4; 421 } 422 423 mmp_clk_reset_register(np, cells, nr_resets); 424 } 425 426 static void __init mmp2_clk_init(struct device_node *np) 427 { 428 struct mmp2_clk_unit *pxa_unit; 429 430 pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); 431 if (!pxa_unit) 432 return; 433 434 if (of_device_is_compatible(np, "marvell,mmp3-clock")) 435 pxa_unit->model = CLK_MODEL_MMP3; 436 else 437 pxa_unit->model = CLK_MODEL_MMP2; 438 439 pxa_unit->mpmu_base = of_iomap(np, 0); 440 if (!pxa_unit->mpmu_base) { 441 pr_err("failed to map mpmu registers\n"); 442 goto free_memory; 443 } 444 445 pxa_unit->apmu_base = of_iomap(np, 1); 446 if (!pxa_unit->apmu_base) { 447 pr_err("failed to map apmu registers\n"); 448 goto unmap_mpmu_region; 449 } 450 451 pxa_unit->apbc_base = of_iomap(np, 2); 452 if (!pxa_unit->apbc_base) { 453 pr_err("failed to map apbc registers\n"); 454 goto unmap_apmu_region; 455 } 456 457 mmp_clk_init(np, &pxa_unit->unit, MMP2_NR_CLKS); 458 459 mmp2_pll_init(pxa_unit); 460 461 mmp2_apb_periph_clk_init(pxa_unit); 462 463 mmp2_axi_periph_clk_init(pxa_unit); 464 465 mmp2_clk_reset_init(np, pxa_unit); 466 467 return; 468 469 unmap_apmu_region: 470 iounmap(pxa_unit->apmu_base); 471 unmap_mpmu_region: 472 iounmap(pxa_unit->mpmu_base); 473 free_memory: 474 kfree(pxa_unit); 475 } 476 477 CLK_OF_DECLARE(mmp2_clk, "marvell,mmp2-clock", mmp2_clk_init); 478 CLK_OF_DECLARE(mmp3_clk, "marvell,mmp3-clock", mmp2_clk_init); 479