1df5338d9SRob Herring /* 2df5338d9SRob Herring * pxa1928 clock framework source file 3df5338d9SRob Herring * 4df5338d9SRob Herring * Copyright (C) 2015 Linaro, Ltd. 5df5338d9SRob Herring * Rob Herring <robh@kernel.org> 6df5338d9SRob Herring * 7df5338d9SRob Herring * Based on drivers/clk/mmp/clk-of-mmp2.c: 8df5338d9SRob Herring * Copyright (C) 2012 Marvell 9df5338d9SRob Herring * Chao Xie <xiechao.mail@gmail.com> 10df5338d9SRob Herring * 11df5338d9SRob Herring * This file is licensed under the terms of the GNU General Public 12df5338d9SRob Herring * License version 2. This program is licensed "as is" without any 13df5338d9SRob Herring * warranty of any kind, whether express or implied. 14df5338d9SRob Herring */ 15df5338d9SRob Herring #include <linux/kernel.h> 16df5338d9SRob Herring #include <linux/io.h> 17df5338d9SRob Herring #include <linux/of_address.h> 18df5338d9SRob Herring #include <linux/slab.h> 19df5338d9SRob Herring #include <linux/spinlock.h> 20df5338d9SRob Herring 21df5338d9SRob Herring #include <dt-bindings/clock/marvell,pxa1928.h> 22df5338d9SRob Herring 23df5338d9SRob Herring #include "clk.h" 24df5338d9SRob Herring #include "reset.h" 25df5338d9SRob Herring 26df5338d9SRob Herring #define MPMU_UART_PLL 0x14 27df5338d9SRob Herring 28df5338d9SRob Herring struct pxa1928_clk_unit { 29df5338d9SRob Herring struct mmp_clk_unit unit; 30df5338d9SRob Herring void __iomem *mpmu_base; 31df5338d9SRob Herring void __iomem *apmu_base; 32df5338d9SRob Herring void __iomem *apbc_base; 33df5338d9SRob Herring void __iomem *apbcp_base; 34df5338d9SRob Herring }; 35df5338d9SRob Herring 36df5338d9SRob Herring static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { 37df5338d9SRob Herring {0, "clk32", NULL, CLK_IS_ROOT, 32768}, 38df5338d9SRob Herring {0, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, 39df5338d9SRob Herring {0, "pll1_624", NULL, CLK_IS_ROOT, 624000000}, 40df5338d9SRob Herring {0, "pll5p", NULL, CLK_IS_ROOT, 832000000}, 41df5338d9SRob Herring {0, "pll5", NULL, CLK_IS_ROOT, 1248000000}, 42df5338d9SRob Herring {0, "usb_pll", NULL, CLK_IS_ROOT, 480000000}, 43df5338d9SRob Herring }; 44df5338d9SRob Herring 45df5338d9SRob Herring static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { 46df5338d9SRob Herring {0, "pll1_d2", "pll1_624", 1, 2, 0}, 47df5338d9SRob Herring {0, "pll1_d9", "pll1_624", 1, 9, 0}, 48df5338d9SRob Herring {0, "pll1_d12", "pll1_624", 1, 12, 0}, 49df5338d9SRob Herring {0, "pll1_d16", "pll1_624", 1, 16, 0}, 50df5338d9SRob Herring {0, "pll1_d20", "pll1_624", 1, 20, 0}, 51df5338d9SRob Herring {0, "pll1_416", "pll1_624", 2, 3, 0}, 52df5338d9SRob Herring {0, "vctcxo_d2", "vctcxo", 1, 2, 0}, 53df5338d9SRob Herring {0, "vctcxo_d4", "vctcxo", 1, 4, 0}, 54df5338d9SRob Herring }; 55df5338d9SRob Herring 56df5338d9SRob Herring static struct mmp_clk_factor_masks uart_factor_masks = { 57df5338d9SRob Herring .factor = 2, 58df5338d9SRob Herring .num_mask = 0x1fff, 59df5338d9SRob Herring .den_mask = 0x1fff, 60df5338d9SRob Herring .num_shift = 16, 61df5338d9SRob Herring .den_shift = 0, 62df5338d9SRob Herring }; 63df5338d9SRob Herring 64df5338d9SRob Herring static struct mmp_clk_factor_tbl uart_factor_tbl[] = { 65df5338d9SRob Herring {.num = 832, .den = 234}, /*58.5MHZ */ 66df5338d9SRob Herring {.num = 1, .den = 1}, /*26MHZ */ 67df5338d9SRob Herring }; 68df5338d9SRob Herring 69df5338d9SRob Herring static void pxa1928_pll_init(struct pxa1928_clk_unit *pxa_unit) 70df5338d9SRob Herring { 71df5338d9SRob Herring struct clk *clk; 72df5338d9SRob Herring struct mmp_clk_unit *unit = &pxa_unit->unit; 73df5338d9SRob Herring 74df5338d9SRob Herring mmp_register_fixed_rate_clks(unit, fixed_rate_clks, 75df5338d9SRob Herring ARRAY_SIZE(fixed_rate_clks)); 76df5338d9SRob Herring 77df5338d9SRob Herring mmp_register_fixed_factor_clks(unit, fixed_factor_clks, 78df5338d9SRob Herring ARRAY_SIZE(fixed_factor_clks)); 79df5338d9SRob Herring 80df5338d9SRob Herring clk = mmp_clk_register_factor("uart_pll", "pll1_416", 81df5338d9SRob Herring CLK_SET_RATE_PARENT, 82df5338d9SRob Herring pxa_unit->mpmu_base + MPMU_UART_PLL, 83df5338d9SRob Herring &uart_factor_masks, uart_factor_tbl, 84df5338d9SRob Herring ARRAY_SIZE(uart_factor_tbl), NULL); 85df5338d9SRob Herring } 86df5338d9SRob Herring 87df5338d9SRob Herring static DEFINE_SPINLOCK(uart0_lock); 88df5338d9SRob Herring static DEFINE_SPINLOCK(uart1_lock); 89df5338d9SRob Herring static DEFINE_SPINLOCK(uart2_lock); 90df5338d9SRob Herring static DEFINE_SPINLOCK(uart3_lock); 91df5338d9SRob Herring static const char *uart_parent_names[] = {"uart_pll", "vctcxo"}; 92df5338d9SRob Herring 93df5338d9SRob Herring static DEFINE_SPINLOCK(ssp0_lock); 94df5338d9SRob Herring static DEFINE_SPINLOCK(ssp1_lock); 95df5338d9SRob Herring static const char *ssp_parent_names[] = {"vctcxo_d4", "vctcxo_d2", "vctcxo", "pll1_d12"}; 96df5338d9SRob Herring 97df5338d9SRob Herring static DEFINE_SPINLOCK(reset_lock); 98df5338d9SRob Herring 99df5338d9SRob Herring static struct mmp_param_mux_clk apbc_mux_clks[] = { 100df5338d9SRob Herring {0, "uart0_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_UART0 * 4, 4, 3, 0, &uart0_lock}, 101df5338d9SRob Herring {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_UART1 * 4, 4, 3, 0, &uart1_lock}, 102df5338d9SRob Herring {0, "uart2_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_UART2 * 4, 4, 3, 0, &uart2_lock}, 103df5338d9SRob Herring {0, "uart3_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_UART3 * 4, 4, 3, 0, &uart3_lock}, 104df5338d9SRob Herring {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_SSP0 * 4, 4, 3, 0, &ssp0_lock}, 105df5338d9SRob Herring {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_SSP1 * 4, 4, 3, 0, &ssp1_lock}, 106df5338d9SRob Herring }; 107df5338d9SRob Herring 108df5338d9SRob Herring static struct mmp_param_gate_clk apbc_gate_clks[] = { 109df5338d9SRob Herring {PXA1928_CLK_TWSI0, "twsi0_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI0 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, 110df5338d9SRob Herring {PXA1928_CLK_TWSI1, "twsi1_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI1 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, 111df5338d9SRob Herring {PXA1928_CLK_TWSI2, "twsi2_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI2 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, 112df5338d9SRob Herring {PXA1928_CLK_TWSI3, "twsi3_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI3 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, 113df5338d9SRob Herring {PXA1928_CLK_TWSI4, "twsi4_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI4 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, 114df5338d9SRob Herring {PXA1928_CLK_TWSI5, "twsi5_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI5 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, 115df5338d9SRob Herring {PXA1928_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_GPIO * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, 116df5338d9SRob Herring {PXA1928_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, PXA1928_CLK_KPC * 4, 0x3, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL}, 117df5338d9SRob Herring {PXA1928_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, PXA1928_CLK_RTC * 4, 0x83, 0x83, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL}, 118df5338d9SRob Herring {PXA1928_CLK_PWM0, "pwm0_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_PWM0 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, 119df5338d9SRob Herring {PXA1928_CLK_PWM1, "pwm1_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_PWM1 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, 120df5338d9SRob Herring {PXA1928_CLK_PWM2, "pwm2_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_PWM2 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, 121df5338d9SRob Herring {PXA1928_CLK_PWM3, "pwm3_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_PWM3 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, 122df5338d9SRob Herring /* The gate clocks has mux parent. */ 123df5338d9SRob Herring {PXA1928_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_UART0 * 4, 0x3, 0x3, 0x0, 0, &uart0_lock}, 124df5338d9SRob Herring {PXA1928_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_UART1 * 4, 0x3, 0x3, 0x0, 0, &uart1_lock}, 125df5338d9SRob Herring {PXA1928_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_UART2 * 4, 0x3, 0x3, 0x0, 0, &uart2_lock}, 126df5338d9SRob Herring {PXA1928_CLK_UART3, "uart3_clk", "uart3_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_UART3 * 4, 0x3, 0x3, 0x0, 0, &uart3_lock}, 127df5338d9SRob Herring {PXA1928_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_SSP0 * 4, 0x3, 0x3, 0x0, 0, &ssp0_lock}, 128df5338d9SRob Herring {PXA1928_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_SSP1 * 4, 0x3, 0x3, 0x0, 0, &ssp1_lock}, 129df5338d9SRob Herring }; 130df5338d9SRob Herring 131df5338d9SRob Herring static void pxa1928_apb_periph_clk_init(struct pxa1928_clk_unit *pxa_unit) 132df5338d9SRob Herring { 133df5338d9SRob Herring struct mmp_clk_unit *unit = &pxa_unit->unit; 134df5338d9SRob Herring 135df5338d9SRob Herring mmp_register_mux_clks(unit, apbc_mux_clks, pxa_unit->apbc_base, 136df5338d9SRob Herring ARRAY_SIZE(apbc_mux_clks)); 137df5338d9SRob Herring 138df5338d9SRob Herring mmp_register_gate_clks(unit, apbc_gate_clks, pxa_unit->apbc_base, 139df5338d9SRob Herring ARRAY_SIZE(apbc_gate_clks)); 140df5338d9SRob Herring } 141df5338d9SRob Herring 142df5338d9SRob Herring static DEFINE_SPINLOCK(sdh0_lock); 143df5338d9SRob Herring static DEFINE_SPINLOCK(sdh1_lock); 144df5338d9SRob Herring static DEFINE_SPINLOCK(sdh2_lock); 145df5338d9SRob Herring static DEFINE_SPINLOCK(sdh3_lock); 146df5338d9SRob Herring static DEFINE_SPINLOCK(sdh4_lock); 147df5338d9SRob Herring static const char *sdh_parent_names[] = {"pll1_624", "pll5p", "pll5", "pll1_416"}; 148df5338d9SRob Herring 149df5338d9SRob Herring static DEFINE_SPINLOCK(usb_lock); 150df5338d9SRob Herring 151df5338d9SRob Herring static struct mmp_param_mux_clk apmu_mux_clks[] = { 152df5338d9SRob Herring {0, "sdh_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_SDH0 * 4, 8, 2, 0, &sdh0_lock}, 153df5338d9SRob Herring }; 154df5338d9SRob Herring 155df5338d9SRob Herring static struct mmp_param_div_clk apmu_div_clks[] = { 156df5338d9SRob Herring {0, "sdh_div", "sdh_mux", 0, PXA1928_CLK_SDH0 * 4, 10, 4, CLK_DIVIDER_ONE_BASED, &sdh0_lock}, 157df5338d9SRob Herring }; 158df5338d9SRob Herring 159df5338d9SRob Herring static struct mmp_param_gate_clk apmu_gate_clks[] = { 160df5338d9SRob Herring {PXA1928_CLK_USB, "usb_clk", "usb_pll", 0, PXA1928_CLK_USB * 4, 0x9, 0x9, 0x0, 0, &usb_lock}, 161df5338d9SRob Herring {PXA1928_CLK_HSIC, "hsic_clk", "usb_pll", 0, PXA1928_CLK_HSIC * 4, 0x9, 0x9, 0x0, 0, &usb_lock}, 162df5338d9SRob Herring /* The gate clocks has mux parent. */ 163df5338d9SRob Herring {PXA1928_CLK_SDH0, "sdh0_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH0 * 4, 0x1b, 0x1b, 0x0, 0, &sdh0_lock}, 164df5338d9SRob Herring {PXA1928_CLK_SDH1, "sdh1_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH1 * 4, 0x1b, 0x1b, 0x0, 0, &sdh1_lock}, 165df5338d9SRob Herring {PXA1928_CLK_SDH2, "sdh2_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH2 * 4, 0x1b, 0x1b, 0x0, 0, &sdh2_lock}, 166df5338d9SRob Herring {PXA1928_CLK_SDH3, "sdh3_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH3 * 4, 0x1b, 0x1b, 0x0, 0, &sdh3_lock}, 167df5338d9SRob Herring {PXA1928_CLK_SDH4, "sdh4_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH4 * 4, 0x1b, 0x1b, 0x0, 0, &sdh4_lock}, 168df5338d9SRob Herring }; 169df5338d9SRob Herring 170df5338d9SRob Herring static void pxa1928_axi_periph_clk_init(struct pxa1928_clk_unit *pxa_unit) 171df5338d9SRob Herring { 172df5338d9SRob Herring struct mmp_clk_unit *unit = &pxa_unit->unit; 173df5338d9SRob Herring 174df5338d9SRob Herring mmp_register_mux_clks(unit, apmu_mux_clks, pxa_unit->apmu_base, 175df5338d9SRob Herring ARRAY_SIZE(apmu_mux_clks)); 176df5338d9SRob Herring 177df5338d9SRob Herring mmp_register_div_clks(unit, apmu_div_clks, pxa_unit->apmu_base, 178df5338d9SRob Herring ARRAY_SIZE(apmu_div_clks)); 179df5338d9SRob Herring 180df5338d9SRob Herring mmp_register_gate_clks(unit, apmu_gate_clks, pxa_unit->apmu_base, 181df5338d9SRob Herring ARRAY_SIZE(apmu_gate_clks)); 182df5338d9SRob Herring } 183df5338d9SRob Herring 184df5338d9SRob Herring static void pxa1928_clk_reset_init(struct device_node *np, 185df5338d9SRob Herring struct pxa1928_clk_unit *pxa_unit) 186df5338d9SRob Herring { 187df5338d9SRob Herring struct mmp_clk_reset_cell *cells; 188df5338d9SRob Herring int i, base, nr_resets; 189df5338d9SRob Herring 190df5338d9SRob Herring nr_resets = ARRAY_SIZE(apbc_gate_clks); 191df5338d9SRob Herring cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL); 192df5338d9SRob Herring if (!cells) 193df5338d9SRob Herring return; 194df5338d9SRob Herring 195df5338d9SRob Herring base = 0; 196df5338d9SRob Herring for (i = 0; i < nr_resets; i++) { 197df5338d9SRob Herring cells[base + i].clk_id = apbc_gate_clks[i].id; 198df5338d9SRob Herring cells[base + i].reg = 199df5338d9SRob Herring pxa_unit->apbc_base + apbc_gate_clks[i].offset; 200df5338d9SRob Herring cells[base + i].flags = 0; 201df5338d9SRob Herring cells[base + i].lock = apbc_gate_clks[i].lock; 202df5338d9SRob Herring cells[base + i].bits = 0x4; 203df5338d9SRob Herring } 204df5338d9SRob Herring 205df5338d9SRob Herring mmp_clk_reset_register(np, cells, nr_resets); 206df5338d9SRob Herring } 207df5338d9SRob Herring 208df5338d9SRob Herring static void __init pxa1928_mpmu_clk_init(struct device_node *np) 209df5338d9SRob Herring { 210df5338d9SRob Herring struct pxa1928_clk_unit *pxa_unit; 211df5338d9SRob Herring 212df5338d9SRob Herring pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); 213df5338d9SRob Herring if (!pxa_unit) 214df5338d9SRob Herring return; 215df5338d9SRob Herring 216df5338d9SRob Herring pxa_unit->mpmu_base = of_iomap(np, 0); 217df5338d9SRob Herring if (!pxa_unit->mpmu_base) { 218df5338d9SRob Herring pr_err("failed to map mpmu registers\n"); 219df5338d9SRob Herring return; 220df5338d9SRob Herring } 221df5338d9SRob Herring 222df5338d9SRob Herring pxa1928_pll_init(pxa_unit); 223df5338d9SRob Herring } 224df5338d9SRob Herring CLK_OF_DECLARE(pxa1928_mpmu_clk, "marvell,pxa1928-mpmu", pxa1928_mpmu_clk_init); 225df5338d9SRob Herring 226df5338d9SRob Herring static void __init pxa1928_apmu_clk_init(struct device_node *np) 227df5338d9SRob Herring { 228df5338d9SRob Herring struct pxa1928_clk_unit *pxa_unit; 229df5338d9SRob Herring 230df5338d9SRob Herring pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); 231df5338d9SRob Herring if (!pxa_unit) 232df5338d9SRob Herring return; 233df5338d9SRob Herring 234df5338d9SRob Herring pxa_unit->apmu_base = of_iomap(np, 0); 235df5338d9SRob Herring if (!pxa_unit->apmu_base) { 236df5338d9SRob Herring pr_err("failed to map apmu registers\n"); 237df5338d9SRob Herring return; 238df5338d9SRob Herring } 239df5338d9SRob Herring 240df5338d9SRob Herring mmp_clk_init(np, &pxa_unit->unit, PXA1928_APMU_NR_CLKS); 241df5338d9SRob Herring 242df5338d9SRob Herring pxa1928_axi_periph_clk_init(pxa_unit); 243df5338d9SRob Herring } 244df5338d9SRob Herring CLK_OF_DECLARE(pxa1928_apmu_clk, "marvell,pxa1928-apmu", pxa1928_apmu_clk_init); 245df5338d9SRob Herring 246df5338d9SRob Herring static void __init pxa1928_apbc_clk_init(struct device_node *np) 247df5338d9SRob Herring { 248df5338d9SRob Herring struct pxa1928_clk_unit *pxa_unit; 249df5338d9SRob Herring 250df5338d9SRob Herring pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); 251df5338d9SRob Herring if (!pxa_unit) 252df5338d9SRob Herring return; 253df5338d9SRob Herring 254df5338d9SRob Herring pxa_unit->apbc_base = of_iomap(np, 0); 255df5338d9SRob Herring if (!pxa_unit->apbc_base) { 256df5338d9SRob Herring pr_err("failed to map apbc registers\n"); 257df5338d9SRob Herring return; 258df5338d9SRob Herring } 259df5338d9SRob Herring 260df5338d9SRob Herring mmp_clk_init(np, &pxa_unit->unit, PXA1928_APBC_NR_CLKS); 261df5338d9SRob Herring 262df5338d9SRob Herring pxa1928_apb_periph_clk_init(pxa_unit); 263df5338d9SRob Herring pxa1928_clk_reset_init(np, pxa_unit); 264df5338d9SRob Herring } 265df5338d9SRob Herring CLK_OF_DECLARE(pxa1928_apbc_clk, "marvell,pxa1928-apbc", pxa1928_apbc_clk_init); 266