0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/clk-provider.h>
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/of_address.h>
0013 #include <linux/of_device.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/slab.h>
0016
0017 #include <dt-bindings/clock/bm1880-clock.h>
0018
0019 #define BM1880_CLK_MPLL_CTL 0x00
0020 #define BM1880_CLK_SPLL_CTL 0x04
0021 #define BM1880_CLK_FPLL_CTL 0x08
0022 #define BM1880_CLK_DDRPLL_CTL 0x0c
0023
0024 #define BM1880_CLK_ENABLE0 0x00
0025 #define BM1880_CLK_ENABLE1 0x04
0026 #define BM1880_CLK_SELECT 0x20
0027 #define BM1880_CLK_DIV0 0x40
0028 #define BM1880_CLK_DIV1 0x44
0029 #define BM1880_CLK_DIV2 0x48
0030 #define BM1880_CLK_DIV3 0x4c
0031 #define BM1880_CLK_DIV4 0x50
0032 #define BM1880_CLK_DIV5 0x54
0033 #define BM1880_CLK_DIV6 0x58
0034 #define BM1880_CLK_DIV7 0x5c
0035 #define BM1880_CLK_DIV8 0x60
0036 #define BM1880_CLK_DIV9 0x64
0037 #define BM1880_CLK_DIV10 0x68
0038 #define BM1880_CLK_DIV11 0x6c
0039 #define BM1880_CLK_DIV12 0x70
0040 #define BM1880_CLK_DIV13 0x74
0041 #define BM1880_CLK_DIV14 0x78
0042 #define BM1880_CLK_DIV15 0x7c
0043 #define BM1880_CLK_DIV16 0x80
0044 #define BM1880_CLK_DIV17 0x84
0045 #define BM1880_CLK_DIV18 0x88
0046 #define BM1880_CLK_DIV19 0x8c
0047 #define BM1880_CLK_DIV20 0x90
0048 #define BM1880_CLK_DIV21 0x94
0049 #define BM1880_CLK_DIV22 0x98
0050 #define BM1880_CLK_DIV23 0x9c
0051 #define BM1880_CLK_DIV24 0xa0
0052 #define BM1880_CLK_DIV25 0xa4
0053 #define BM1880_CLK_DIV26 0xa8
0054 #define BM1880_CLK_DIV27 0xac
0055 #define BM1880_CLK_DIV28 0xb0
0056
0057 #define to_bm1880_pll_clk(_hw) container_of(_hw, struct bm1880_pll_hw_clock, hw)
0058 #define to_bm1880_div_clk(_hw) container_of(_hw, struct bm1880_div_hw_clock, hw)
0059
0060 static DEFINE_SPINLOCK(bm1880_clk_lock);
0061
0062 struct bm1880_clock_data {
0063 void __iomem *pll_base;
0064 void __iomem *sys_base;
0065 struct clk_hw_onecell_data hw_data;
0066 };
0067
0068 struct bm1880_gate_clock {
0069 unsigned int id;
0070 const char *name;
0071 const char *parent;
0072 u32 gate_reg;
0073 s8 gate_shift;
0074 unsigned long flags;
0075 };
0076
0077 struct bm1880_mux_clock {
0078 unsigned int id;
0079 const char *name;
0080 const char * const *parents;
0081 s8 num_parents;
0082 u32 reg;
0083 s8 shift;
0084 unsigned long flags;
0085 };
0086
0087 struct bm1880_div_clock {
0088 unsigned int id;
0089 const char *name;
0090 u32 reg;
0091 u8 shift;
0092 u8 width;
0093 u32 initval;
0094 const struct clk_div_table *table;
0095 unsigned long flags;
0096 };
0097
0098 struct bm1880_div_hw_clock {
0099 struct bm1880_div_clock div;
0100 void __iomem *base;
0101 spinlock_t *lock;
0102 struct clk_hw hw;
0103 struct clk_init_data init;
0104 };
0105
0106 struct bm1880_composite_clock {
0107 unsigned int id;
0108 const char *name;
0109 const char *parent;
0110 const char * const *parents;
0111 unsigned int num_parents;
0112 unsigned long flags;
0113
0114 u32 gate_reg;
0115 u32 mux_reg;
0116 u32 div_reg;
0117
0118 s8 gate_shift;
0119 s8 mux_shift;
0120 s8 div_shift;
0121 s8 div_width;
0122 s16 div_initval;
0123 const struct clk_div_table *table;
0124 };
0125
0126 struct bm1880_pll_clock {
0127 unsigned int id;
0128 const char *name;
0129 u32 reg;
0130 unsigned long flags;
0131 };
0132
0133 struct bm1880_pll_hw_clock {
0134 struct bm1880_pll_clock pll;
0135 void __iomem *base;
0136 struct clk_hw hw;
0137 struct clk_init_data init;
0138 };
0139
0140 static const struct clk_ops bm1880_pll_ops;
0141 static const struct clk_ops bm1880_clk_div_ops;
0142
0143 #define GATE_DIV(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \
0144 _div_shift, _div_width, _div_initval, _table, \
0145 _flags) { \
0146 .id = _id, \
0147 .parent = _parent, \
0148 .name = _name, \
0149 .gate_reg = _gate_reg, \
0150 .gate_shift = _gate_shift, \
0151 .div_reg = _div_reg, \
0152 .div_shift = _div_shift, \
0153 .div_width = _div_width, \
0154 .div_initval = _div_initval, \
0155 .table = _table, \
0156 .mux_shift = -1, \
0157 .flags = _flags, \
0158 }
0159
0160 #define GATE_MUX(_id, _name, _parents, _gate_reg, _gate_shift, \
0161 _mux_reg, _mux_shift, _flags) { \
0162 .id = _id, \
0163 .parents = _parents, \
0164 .num_parents = ARRAY_SIZE(_parents), \
0165 .name = _name, \
0166 .gate_reg = _gate_reg, \
0167 .gate_shift = _gate_shift, \
0168 .div_shift = -1, \
0169 .mux_reg = _mux_reg, \
0170 .mux_shift = _mux_shift, \
0171 .flags = _flags, \
0172 }
0173
0174 #define CLK_PLL(_id, _name, _parent, _reg, _flags) { \
0175 .pll.id = _id, \
0176 .pll.name = _name, \
0177 .pll.reg = _reg, \
0178 .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, _parent, \
0179 &bm1880_pll_ops, \
0180 _flags), \
0181 }
0182
0183 #define CLK_DIV(_id, _name, _parent, _reg, _shift, _width, _initval, \
0184 _table, _flags) { \
0185 .div.id = _id, \
0186 .div.name = _name, \
0187 .div.reg = _reg, \
0188 .div.shift = _shift, \
0189 .div.width = _width, \
0190 .div.initval = _initval, \
0191 .div.table = _table, \
0192 .hw.init = CLK_HW_INIT_HW(_name, _parent, \
0193 &bm1880_clk_div_ops, \
0194 _flags), \
0195 }
0196
0197 static struct clk_parent_data bm1880_pll_parent[] = {
0198 { .fw_name = "osc", .name = "osc" },
0199 };
0200
0201
0202
0203
0204
0205 static struct bm1880_pll_hw_clock bm1880_pll_clks[] = {
0206 CLK_PLL(BM1880_CLK_MPLL, "clk_mpll", bm1880_pll_parent,
0207 BM1880_CLK_MPLL_CTL, 0),
0208 CLK_PLL(BM1880_CLK_SPLL, "clk_spll", bm1880_pll_parent,
0209 BM1880_CLK_SPLL_CTL, 0),
0210 CLK_PLL(BM1880_CLK_FPLL, "clk_fpll", bm1880_pll_parent,
0211 BM1880_CLK_FPLL_CTL, 0),
0212 CLK_PLL(BM1880_CLK_DDRPLL, "clk_ddrpll", bm1880_pll_parent,
0213 BM1880_CLK_DDRPLL_CTL, 0),
0214 };
0215
0216
0217
0218
0219
0220 static const struct bm1880_gate_clock bm1880_gate_clks[] = {
0221 { BM1880_CLK_AHB_ROM, "clk_ahb_rom", "clk_mux_axi6",
0222 BM1880_CLK_ENABLE0, 2, 0 },
0223 { BM1880_CLK_AXI_SRAM, "clk_axi_sram", "clk_axi1",
0224 BM1880_CLK_ENABLE0, 3, 0 },
0225
0226
0227
0228
0229 { BM1880_CLK_DDR_AXI, "clk_ddr_axi", "clk_mux_axi6",
0230 BM1880_CLK_ENABLE0, 4, CLK_IS_CRITICAL },
0231 { BM1880_CLK_APB_EFUSE, "clk_apb_efuse", "clk_mux_axi6",
0232 BM1880_CLK_ENABLE0, 6, 0 },
0233 { BM1880_CLK_AXI5_EMMC, "clk_axi5_emmc", "clk_axi5",
0234 BM1880_CLK_ENABLE0, 7, 0 },
0235 { BM1880_CLK_AXI5_SD, "clk_axi5_sd", "clk_axi5",
0236 BM1880_CLK_ENABLE0, 10, 0 },
0237 { BM1880_CLK_AXI4_ETH0, "clk_axi4_eth0", "clk_axi4",
0238 BM1880_CLK_ENABLE0, 14, 0 },
0239 { BM1880_CLK_AXI4_ETH1, "clk_axi4_eth1", "clk_axi4",
0240 BM1880_CLK_ENABLE0, 16, 0 },
0241 { BM1880_CLK_AXI1_GDMA, "clk_axi1_gdma", "clk_axi1",
0242 BM1880_CLK_ENABLE0, 17, 0 },
0243
0244 { BM1880_CLK_APB_GPIO, "clk_apb_gpio", "clk_mux_axi6",
0245 BM1880_CLK_ENABLE0, 18, CLK_IGNORE_UNUSED },
0246 { BM1880_CLK_APB_GPIO_INTR, "clk_apb_gpio_intr", "clk_mux_axi6",
0247 BM1880_CLK_ENABLE0, 19, CLK_IGNORE_UNUSED },
0248 { BM1880_CLK_AXI1_MINER, "clk_axi1_miner", "clk_axi1",
0249 BM1880_CLK_ENABLE0, 21, 0 },
0250 { BM1880_CLK_AHB_SF, "clk_ahb_sf", "clk_mux_axi6",
0251 BM1880_CLK_ENABLE0, 22, 0 },
0252
0253
0254
0255
0256 { BM1880_CLK_SDMA_AXI, "clk_sdma_axi", "clk_axi5",
0257 BM1880_CLK_ENABLE0, 23, CLK_IS_CRITICAL },
0258 { BM1880_CLK_APB_I2C, "clk_apb_i2c", "clk_mux_axi6",
0259 BM1880_CLK_ENABLE0, 25, 0 },
0260 { BM1880_CLK_APB_WDT, "clk_apb_wdt", "clk_mux_axi6",
0261 BM1880_CLK_ENABLE0, 26, 0 },
0262 { BM1880_CLK_APB_JPEG, "clk_apb_jpeg", "clk_axi6",
0263 BM1880_CLK_ENABLE0, 27, 0 },
0264 { BM1880_CLK_AXI5_NF, "clk_axi5_nf", "clk_axi5",
0265 BM1880_CLK_ENABLE0, 29, 0 },
0266 { BM1880_CLK_APB_NF, "clk_apb_nf", "clk_axi6",
0267 BM1880_CLK_ENABLE0, 30, 0 },
0268 { BM1880_CLK_APB_PWM, "clk_apb_pwm", "clk_mux_axi6",
0269 BM1880_CLK_ENABLE1, 0, 0 },
0270 { BM1880_CLK_RV, "clk_rv", "clk_mux_rv",
0271 BM1880_CLK_ENABLE1, 1, 0 },
0272 { BM1880_CLK_APB_SPI, "clk_apb_spi", "clk_mux_axi6",
0273 BM1880_CLK_ENABLE1, 2, 0 },
0274 { BM1880_CLK_UART_500M, "clk_uart_500m", "clk_div_uart_500m",
0275 BM1880_CLK_ENABLE1, 4, 0 },
0276 { BM1880_CLK_APB_UART, "clk_apb_uart", "clk_axi6",
0277 BM1880_CLK_ENABLE1, 5, 0 },
0278 { BM1880_CLK_APB_I2S, "clk_apb_i2s", "clk_axi6",
0279 BM1880_CLK_ENABLE1, 6, 0 },
0280 { BM1880_CLK_AXI4_USB, "clk_axi4_usb", "clk_axi4",
0281 BM1880_CLK_ENABLE1, 7, 0 },
0282 { BM1880_CLK_APB_USB, "clk_apb_usb", "clk_axi6",
0283 BM1880_CLK_ENABLE1, 8, 0 },
0284 { BM1880_CLK_12M_USB, "clk_12m_usb", "clk_div_12m_usb",
0285 BM1880_CLK_ENABLE1, 11, 0 },
0286 { BM1880_CLK_APB_VIDEO, "clk_apb_video", "clk_axi6",
0287 BM1880_CLK_ENABLE1, 12, 0 },
0288 { BM1880_CLK_APB_VPP, "clk_apb_vpp", "clk_axi6",
0289 BM1880_CLK_ENABLE1, 15, 0 },
0290 { BM1880_CLK_AXI6, "clk_axi6", "clk_mux_axi6",
0291 BM1880_CLK_ENABLE1, 21, 0 },
0292 };
0293
0294 static const char * const clk_a53_parents[] = { "clk_spll", "clk_mpll" };
0295 static const char * const clk_rv_parents[] = { "clk_div_1_rv", "clk_div_0_rv" };
0296 static const char * const clk_axi1_parents[] = { "clk_div_1_axi1", "clk_div_0_axi1" };
0297 static const char * const clk_axi6_parents[] = { "clk_div_1_axi6", "clk_div_0_axi6" };
0298
0299 static const struct bm1880_mux_clock bm1880_mux_clks[] = {
0300 { BM1880_CLK_MUX_RV, "clk_mux_rv", clk_rv_parents, 2,
0301 BM1880_CLK_SELECT, 1, 0 },
0302 { BM1880_CLK_MUX_AXI6, "clk_mux_axi6", clk_axi6_parents, 2,
0303 BM1880_CLK_SELECT, 3, 0 },
0304 };
0305
0306 static const struct clk_div_table bm1880_div_table_0[] = {
0307 { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
0308 { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 },
0309 { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 },
0310 { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 },
0311 { 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 },
0312 { 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 },
0313 { 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 },
0314 { 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 },
0315 { 0, 0 }
0316 };
0317
0318 static const struct clk_div_table bm1880_div_table_1[] = {
0319 { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
0320 { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 },
0321 { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 },
0322 { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 },
0323 { 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 },
0324 { 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 },
0325 { 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 },
0326 { 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 },
0327 { 127, 128 }, { 0, 0 }
0328 };
0329
0330 static const struct clk_div_table bm1880_div_table_2[] = {
0331 { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
0332 { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 },
0333 { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 },
0334 { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 },
0335 { 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 },
0336 { 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 },
0337 { 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 },
0338 { 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 },
0339 { 127, 128 }, { 255, 256 }, { 0, 0 }
0340 };
0341
0342 static const struct clk_div_table bm1880_div_table_3[] = {
0343 { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
0344 { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 },
0345 { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 },
0346 { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 },
0347 { 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 },
0348 { 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 },
0349 { 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 },
0350 { 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 },
0351 { 127, 128 }, { 255, 256 }, { 511, 512 }, { 0, 0 }
0352 };
0353
0354 static const struct clk_div_table bm1880_div_table_4[] = {
0355 { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
0356 { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 },
0357 { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 },
0358 { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 },
0359 { 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 },
0360 { 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 },
0361 { 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 },
0362 { 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 },
0363 { 127, 128 }, { 255, 256 }, { 511, 512 }, { 65535, 65536 },
0364 { 0, 0 }
0365 };
0366
0367
0368
0369
0370
0371 static struct bm1880_div_hw_clock bm1880_div_clks[] = {
0372 CLK_DIV(BM1880_CLK_DIV_0_RV, "clk_div_0_rv", &bm1880_pll_clks[1].hw,
0373 BM1880_CLK_DIV12, 16, 5, 1, bm1880_div_table_0, 0),
0374 CLK_DIV(BM1880_CLK_DIV_1_RV, "clk_div_1_rv", &bm1880_pll_clks[2].hw,
0375 BM1880_CLK_DIV13, 16, 5, 1, bm1880_div_table_0, 0),
0376 CLK_DIV(BM1880_CLK_DIV_UART_500M, "clk_div_uart_500m", &bm1880_pll_clks[2].hw,
0377 BM1880_CLK_DIV15, 16, 7, 3, bm1880_div_table_1, 0),
0378 CLK_DIV(BM1880_CLK_DIV_0_AXI1, "clk_div_0_axi1", &bm1880_pll_clks[0].hw,
0379 BM1880_CLK_DIV21, 16, 5, 2, bm1880_div_table_0,
0380 0),
0381 CLK_DIV(BM1880_CLK_DIV_1_AXI1, "clk_div_1_axi1", &bm1880_pll_clks[2].hw,
0382 BM1880_CLK_DIV22, 16, 5, 3, bm1880_div_table_0,
0383 0),
0384 CLK_DIV(BM1880_CLK_DIV_0_AXI6, "clk_div_0_axi6", &bm1880_pll_clks[2].hw,
0385 BM1880_CLK_DIV27, 16, 5, 15, bm1880_div_table_0,
0386 0),
0387 CLK_DIV(BM1880_CLK_DIV_1_AXI6, "clk_div_1_axi6", &bm1880_pll_clks[0].hw,
0388 BM1880_CLK_DIV28, 16, 5, 11, bm1880_div_table_0,
0389 0),
0390 CLK_DIV(BM1880_CLK_DIV_12M_USB, "clk_div_12m_usb", &bm1880_pll_clks[2].hw,
0391 BM1880_CLK_DIV18, 16, 7, 125, bm1880_div_table_1, 0),
0392 };
0393
0394
0395
0396
0397
0398 static struct bm1880_composite_clock bm1880_composite_clks[] = {
0399
0400
0401
0402
0403 GATE_MUX(BM1880_CLK_A53, "clk_a53", clk_a53_parents,
0404 BM1880_CLK_ENABLE0, 0, BM1880_CLK_SELECT, 0,
0405 CLK_IS_CRITICAL),
0406 GATE_DIV(BM1880_CLK_50M_A53, "clk_50m_a53", "clk_fpll",
0407 BM1880_CLK_ENABLE0, 1, BM1880_CLK_DIV0, 16, 5, 30,
0408 bm1880_div_table_0, CLK_IS_CRITICAL),
0409 GATE_DIV(BM1880_CLK_EFUSE, "clk_efuse", "clk_fpll",
0410 BM1880_CLK_ENABLE0, 5, BM1880_CLK_DIV1, 16, 7, 60,
0411 bm1880_div_table_1, 0),
0412 GATE_DIV(BM1880_CLK_EMMC, "clk_emmc", "clk_fpll",
0413 BM1880_CLK_ENABLE0, 8, BM1880_CLK_DIV2, 16, 5, 15,
0414 bm1880_div_table_0, 0),
0415 GATE_DIV(BM1880_CLK_100K_EMMC, "clk_100k_emmc", "clk_div_12m_usb",
0416 BM1880_CLK_ENABLE0, 9, BM1880_CLK_DIV3, 16, 8, 120,
0417 bm1880_div_table_2, 0),
0418 GATE_DIV(BM1880_CLK_SD, "clk_sd", "clk_fpll",
0419 BM1880_CLK_ENABLE0, 11, BM1880_CLK_DIV4, 16, 5, 15,
0420 bm1880_div_table_0, 0),
0421 GATE_DIV(BM1880_CLK_100K_SD, "clk_100k_sd", "clk_div_12m_usb",
0422 BM1880_CLK_ENABLE0, 12, BM1880_CLK_DIV5, 16, 8, 120,
0423 bm1880_div_table_2, 0),
0424 GATE_DIV(BM1880_CLK_500M_ETH0, "clk_500m_eth0", "clk_fpll",
0425 BM1880_CLK_ENABLE0, 13, BM1880_CLK_DIV6, 16, 5, 3,
0426 bm1880_div_table_0, 0),
0427 GATE_DIV(BM1880_CLK_500M_ETH1, "clk_500m_eth1", "clk_fpll",
0428 BM1880_CLK_ENABLE0, 15, BM1880_CLK_DIV7, 16, 5, 3,
0429 bm1880_div_table_0, 0),
0430
0431 GATE_DIV(BM1880_CLK_GPIO_DB, "clk_gpio_db", "clk_div_12m_usb",
0432 BM1880_CLK_ENABLE0, 20, BM1880_CLK_DIV8, 16, 16, 120,
0433 bm1880_div_table_4, CLK_IGNORE_UNUSED),
0434 GATE_DIV(BM1880_CLK_SDMA_AUD, "clk_sdma_aud", "clk_fpll",
0435 BM1880_CLK_ENABLE0, 24, BM1880_CLK_DIV9, 16, 7, 61,
0436 bm1880_div_table_1, 0),
0437 GATE_DIV(BM1880_CLK_JPEG_AXI, "clk_jpeg_axi", "clk_fpll",
0438 BM1880_CLK_ENABLE0, 28, BM1880_CLK_DIV10, 16, 5, 4,
0439 bm1880_div_table_0, 0),
0440 GATE_DIV(BM1880_CLK_NF, "clk_nf", "clk_fpll",
0441 BM1880_CLK_ENABLE0, 31, BM1880_CLK_DIV11, 16, 5, 30,
0442 bm1880_div_table_0, 0),
0443 GATE_DIV(BM1880_CLK_TPU_AXI, "clk_tpu_axi", "clk_spll",
0444 BM1880_CLK_ENABLE1, 3, BM1880_CLK_DIV14, 16, 5, 1,
0445 bm1880_div_table_0, 0),
0446 GATE_DIV(BM1880_CLK_125M_USB, "clk_125m_usb", "clk_fpll",
0447 BM1880_CLK_ENABLE1, 9, BM1880_CLK_DIV16, 16, 5, 12,
0448 bm1880_div_table_0, 0),
0449 GATE_DIV(BM1880_CLK_33K_USB, "clk_33k_usb", "clk_div_12m_usb",
0450 BM1880_CLK_ENABLE1, 10, BM1880_CLK_DIV17, 16, 9, 363,
0451 bm1880_div_table_3, 0),
0452 GATE_DIV(BM1880_CLK_VIDEO_AXI, "clk_video_axi", "clk_fpll",
0453 BM1880_CLK_ENABLE1, 13, BM1880_CLK_DIV19, 16, 5, 4,
0454 bm1880_div_table_0, 0),
0455 GATE_DIV(BM1880_CLK_VPP_AXI, "clk_vpp_axi", "clk_fpll",
0456 BM1880_CLK_ENABLE1, 14, BM1880_CLK_DIV20, 16, 5, 4,
0457 bm1880_div_table_0, 0),
0458 GATE_MUX(BM1880_CLK_AXI1, "clk_axi1", clk_axi1_parents,
0459 BM1880_CLK_ENABLE1, 15, BM1880_CLK_SELECT, 2, 0),
0460 GATE_DIV(BM1880_CLK_AXI2, "clk_axi2", "clk_fpll",
0461 BM1880_CLK_ENABLE1, 17, BM1880_CLK_DIV23, 16, 5, 3,
0462 bm1880_div_table_0, 0),
0463 GATE_DIV(BM1880_CLK_AXI3, "clk_axi3", "clk_mux_rv",
0464 BM1880_CLK_ENABLE1, 18, BM1880_CLK_DIV24, 16, 5, 2,
0465 bm1880_div_table_0, 0),
0466 GATE_DIV(BM1880_CLK_AXI4, "clk_axi4", "clk_fpll",
0467 BM1880_CLK_ENABLE1, 19, BM1880_CLK_DIV25, 16, 5, 6,
0468 bm1880_div_table_0, 0),
0469 GATE_DIV(BM1880_CLK_AXI5, "clk_axi5", "clk_fpll",
0470 BM1880_CLK_ENABLE1, 20, BM1880_CLK_DIV26, 16, 5, 15,
0471 bm1880_div_table_0, 0),
0472 };
0473
0474 static unsigned long bm1880_pll_rate_calc(u32 regval, unsigned long parent_rate)
0475 {
0476 u64 numerator;
0477 u32 fbdiv, refdiv;
0478 u32 postdiv1, postdiv2, denominator;
0479
0480 fbdiv = (regval >> 16) & 0xfff;
0481 refdiv = regval & 0x1f;
0482 postdiv1 = (regval >> 8) & 0x7;
0483 postdiv2 = (regval >> 12) & 0x7;
0484
0485 numerator = parent_rate * fbdiv;
0486 denominator = refdiv * postdiv1 * postdiv2;
0487 do_div(numerator, denominator);
0488
0489 return (unsigned long)numerator;
0490 }
0491
0492 static unsigned long bm1880_pll_recalc_rate(struct clk_hw *hw,
0493 unsigned long parent_rate)
0494 {
0495 struct bm1880_pll_hw_clock *pll_hw = to_bm1880_pll_clk(hw);
0496 unsigned long rate;
0497 u32 regval;
0498
0499 regval = readl(pll_hw->base + pll_hw->pll.reg);
0500 rate = bm1880_pll_rate_calc(regval, parent_rate);
0501
0502 return rate;
0503 }
0504
0505 static const struct clk_ops bm1880_pll_ops = {
0506 .recalc_rate = bm1880_pll_recalc_rate,
0507 };
0508
0509 static struct clk_hw *bm1880_clk_register_pll(struct bm1880_pll_hw_clock *pll_clk,
0510 void __iomem *sys_base)
0511 {
0512 struct clk_hw *hw;
0513 int err;
0514
0515 pll_clk->base = sys_base;
0516 hw = &pll_clk->hw;
0517
0518 err = clk_hw_register(NULL, hw);
0519 if (err)
0520 return ERR_PTR(err);
0521
0522 return hw;
0523 }
0524
0525 static int bm1880_clk_register_plls(struct bm1880_pll_hw_clock *clks,
0526 int num_clks,
0527 struct bm1880_clock_data *data)
0528 {
0529 struct clk_hw *hw;
0530 void __iomem *pll_base = data->pll_base;
0531 int i;
0532
0533 for (i = 0; i < num_clks; i++) {
0534 struct bm1880_pll_hw_clock *bm1880_clk = &clks[i];
0535
0536 hw = bm1880_clk_register_pll(bm1880_clk, pll_base);
0537 if (IS_ERR(hw)) {
0538 pr_err("%s: failed to register clock %s\n",
0539 __func__, bm1880_clk->pll.name);
0540 goto err_clk;
0541 }
0542
0543 data->hw_data.hws[clks[i].pll.id] = hw;
0544 }
0545
0546 return 0;
0547
0548 err_clk:
0549 while (i--)
0550 clk_hw_unregister(data->hw_data.hws[clks[i].pll.id]);
0551
0552 return PTR_ERR(hw);
0553 }
0554
0555 static int bm1880_clk_register_mux(const struct bm1880_mux_clock *clks,
0556 int num_clks,
0557 struct bm1880_clock_data *data)
0558 {
0559 struct clk_hw *hw;
0560 void __iomem *sys_base = data->sys_base;
0561 int i;
0562
0563 for (i = 0; i < num_clks; i++) {
0564 hw = clk_hw_register_mux(NULL, clks[i].name,
0565 clks[i].parents,
0566 clks[i].num_parents,
0567 clks[i].flags,
0568 sys_base + clks[i].reg,
0569 clks[i].shift, 1, 0,
0570 &bm1880_clk_lock);
0571 if (IS_ERR(hw)) {
0572 pr_err("%s: failed to register clock %s\n",
0573 __func__, clks[i].name);
0574 goto err_clk;
0575 }
0576
0577 data->hw_data.hws[clks[i].id] = hw;
0578 }
0579
0580 return 0;
0581
0582 err_clk:
0583 while (i--)
0584 clk_hw_unregister_mux(data->hw_data.hws[clks[i].id]);
0585
0586 return PTR_ERR(hw);
0587 }
0588
0589 static unsigned long bm1880_clk_div_recalc_rate(struct clk_hw *hw,
0590 unsigned long parent_rate)
0591 {
0592 struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw);
0593 struct bm1880_div_clock *div = &div_hw->div;
0594 void __iomem *reg_addr = div_hw->base + div->reg;
0595 unsigned int val;
0596 unsigned long rate;
0597
0598 if (!(readl(reg_addr) & BIT(3))) {
0599 val = div->initval;
0600 } else {
0601 val = readl(reg_addr) >> div->shift;
0602 val &= clk_div_mask(div->width);
0603 }
0604
0605 rate = divider_recalc_rate(hw, parent_rate, val, div->table,
0606 div->flags, div->width);
0607
0608 return rate;
0609 }
0610
0611 static long bm1880_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
0612 unsigned long *prate)
0613 {
0614 struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw);
0615 struct bm1880_div_clock *div = &div_hw->div;
0616 void __iomem *reg_addr = div_hw->base + div->reg;
0617
0618 if (div->flags & CLK_DIVIDER_READ_ONLY) {
0619 u32 val;
0620
0621 val = readl(reg_addr) >> div->shift;
0622 val &= clk_div_mask(div->width);
0623
0624 return divider_ro_round_rate(hw, rate, prate, div->table,
0625 div->width, div->flags,
0626 val);
0627 }
0628
0629 return divider_round_rate(hw, rate, prate, div->table,
0630 div->width, div->flags);
0631 }
0632
0633 static int bm1880_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
0634 unsigned long parent_rate)
0635 {
0636 struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw);
0637 struct bm1880_div_clock *div = &div_hw->div;
0638 void __iomem *reg_addr = div_hw->base + div->reg;
0639 unsigned long flags = 0;
0640 int value;
0641 u32 val;
0642
0643 value = divider_get_val(rate, parent_rate, div->table,
0644 div->width, div_hw->div.flags);
0645 if (value < 0)
0646 return value;
0647
0648 if (div_hw->lock)
0649 spin_lock_irqsave(div_hw->lock, flags);
0650 else
0651 __acquire(div_hw->lock);
0652
0653 val = readl(reg_addr);
0654 val &= ~(clk_div_mask(div->width) << div_hw->div.shift);
0655 val |= (u32)value << div->shift;
0656 writel(val, reg_addr);
0657
0658 if (div_hw->lock)
0659 spin_unlock_irqrestore(div_hw->lock, flags);
0660 else
0661 __release(div_hw->lock);
0662
0663 return 0;
0664 }
0665
0666 static const struct clk_ops bm1880_clk_div_ops = {
0667 .recalc_rate = bm1880_clk_div_recalc_rate,
0668 .round_rate = bm1880_clk_div_round_rate,
0669 .set_rate = bm1880_clk_div_set_rate,
0670 };
0671
0672 static struct clk_hw *bm1880_clk_register_div(struct bm1880_div_hw_clock *div_clk,
0673 void __iomem *sys_base)
0674 {
0675 struct clk_hw *hw;
0676 int err;
0677
0678 div_clk->div.flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO;
0679 div_clk->base = sys_base;
0680 div_clk->lock = &bm1880_clk_lock;
0681
0682 hw = &div_clk->hw;
0683 err = clk_hw_register(NULL, hw);
0684 if (err)
0685 return ERR_PTR(err);
0686
0687 return hw;
0688 }
0689
0690 static int bm1880_clk_register_divs(struct bm1880_div_hw_clock *clks,
0691 int num_clks,
0692 struct bm1880_clock_data *data)
0693 {
0694 struct clk_hw *hw;
0695 void __iomem *sys_base = data->sys_base;
0696 unsigned int i, id;
0697
0698 for (i = 0; i < num_clks; i++) {
0699 struct bm1880_div_hw_clock *bm1880_clk = &clks[i];
0700
0701 hw = bm1880_clk_register_div(bm1880_clk, sys_base);
0702 if (IS_ERR(hw)) {
0703 pr_err("%s: failed to register clock %s\n",
0704 __func__, bm1880_clk->div.name);
0705 goto err_clk;
0706 }
0707
0708 id = clks[i].div.id;
0709 data->hw_data.hws[id] = hw;
0710 }
0711
0712 return 0;
0713
0714 err_clk:
0715 while (i--)
0716 clk_hw_unregister(data->hw_data.hws[clks[i].div.id]);
0717
0718 return PTR_ERR(hw);
0719 }
0720
0721 static int bm1880_clk_register_gate(const struct bm1880_gate_clock *clks,
0722 int num_clks,
0723 struct bm1880_clock_data *data)
0724 {
0725 struct clk_hw *hw;
0726 void __iomem *sys_base = data->sys_base;
0727 int i;
0728
0729 for (i = 0; i < num_clks; i++) {
0730 hw = clk_hw_register_gate(NULL, clks[i].name,
0731 clks[i].parent,
0732 clks[i].flags,
0733 sys_base + clks[i].gate_reg,
0734 clks[i].gate_shift, 0,
0735 &bm1880_clk_lock);
0736 if (IS_ERR(hw)) {
0737 pr_err("%s: failed to register clock %s\n",
0738 __func__, clks[i].name);
0739 goto err_clk;
0740 }
0741
0742 data->hw_data.hws[clks[i].id] = hw;
0743 }
0744
0745 return 0;
0746
0747 err_clk:
0748 while (i--)
0749 clk_hw_unregister_gate(data->hw_data.hws[clks[i].id]);
0750
0751 return PTR_ERR(hw);
0752 }
0753
0754 static struct clk_hw *bm1880_clk_register_composite(struct bm1880_composite_clock *clks,
0755 void __iomem *sys_base)
0756 {
0757 struct clk_hw *hw;
0758 struct clk_mux *mux = NULL;
0759 struct clk_gate *gate = NULL;
0760 struct bm1880_div_hw_clock *div_hws = NULL;
0761 struct clk_hw *mux_hw = NULL, *gate_hw = NULL, *div_hw = NULL;
0762 const struct clk_ops *mux_ops = NULL, *gate_ops = NULL, *div_ops = NULL;
0763 const char * const *parent_names;
0764 const char *parent;
0765 int num_parents;
0766 int ret;
0767
0768 if (clks->mux_shift >= 0) {
0769 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
0770 if (!mux)
0771 return ERR_PTR(-ENOMEM);
0772
0773 mux->reg = sys_base + clks->mux_reg;
0774 mux->mask = 1;
0775 mux->shift = clks->mux_shift;
0776 mux_hw = &mux->hw;
0777 mux_ops = &clk_mux_ops;
0778 mux->lock = &bm1880_clk_lock;
0779
0780 parent_names = clks->parents;
0781 num_parents = clks->num_parents;
0782 } else {
0783 parent = clks->parent;
0784 parent_names = &parent;
0785 num_parents = 1;
0786 }
0787
0788 if (clks->gate_shift >= 0) {
0789 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
0790 if (!gate) {
0791 ret = -ENOMEM;
0792 goto err_out;
0793 }
0794
0795 gate->reg = sys_base + clks->gate_reg;
0796 gate->bit_idx = clks->gate_shift;
0797 gate->lock = &bm1880_clk_lock;
0798
0799 gate_hw = &gate->hw;
0800 gate_ops = &clk_gate_ops;
0801 }
0802
0803 if (clks->div_shift >= 0) {
0804 div_hws = kzalloc(sizeof(*div_hws), GFP_KERNEL);
0805 if (!div_hws) {
0806 ret = -ENOMEM;
0807 goto err_out;
0808 }
0809
0810 div_hws->base = sys_base;
0811 div_hws->div.reg = clks->div_reg;
0812 div_hws->div.shift = clks->div_shift;
0813 div_hws->div.width = clks->div_width;
0814 div_hws->div.table = clks->table;
0815 div_hws->div.initval = clks->div_initval;
0816 div_hws->lock = &bm1880_clk_lock;
0817 div_hws->div.flags = CLK_DIVIDER_ONE_BASED |
0818 CLK_DIVIDER_ALLOW_ZERO;
0819
0820 div_hw = &div_hws->hw;
0821 div_ops = &bm1880_clk_div_ops;
0822 }
0823
0824 hw = clk_hw_register_composite(NULL, clks->name, parent_names,
0825 num_parents, mux_hw, mux_ops, div_hw,
0826 div_ops, gate_hw, gate_ops,
0827 clks->flags);
0828
0829 if (IS_ERR(hw)) {
0830 ret = PTR_ERR(hw);
0831 goto err_out;
0832 }
0833
0834 return hw;
0835
0836 err_out:
0837 kfree(div_hws);
0838 kfree(gate);
0839 kfree(mux);
0840
0841 return ERR_PTR(ret);
0842 }
0843
0844 static int bm1880_clk_register_composites(struct bm1880_composite_clock *clks,
0845 int num_clks,
0846 struct bm1880_clock_data *data)
0847 {
0848 struct clk_hw *hw;
0849 void __iomem *sys_base = data->sys_base;
0850 int i;
0851
0852 for (i = 0; i < num_clks; i++) {
0853 struct bm1880_composite_clock *bm1880_clk = &clks[i];
0854
0855 hw = bm1880_clk_register_composite(bm1880_clk, sys_base);
0856 if (IS_ERR(hw)) {
0857 pr_err("%s: failed to register clock %s\n",
0858 __func__, bm1880_clk->name);
0859 goto err_clk;
0860 }
0861
0862 data->hw_data.hws[clks[i].id] = hw;
0863 }
0864
0865 return 0;
0866
0867 err_clk:
0868 while (i--)
0869 clk_hw_unregister_composite(data->hw_data.hws[clks[i].id]);
0870
0871 return PTR_ERR(hw);
0872 }
0873
0874 static int bm1880_clk_probe(struct platform_device *pdev)
0875 {
0876 struct bm1880_clock_data *clk_data;
0877 void __iomem *pll_base, *sys_base;
0878 struct device *dev = &pdev->dev;
0879 struct resource *res;
0880 int num_clks, i;
0881
0882 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0883 pll_base = devm_ioremap_resource(&pdev->dev, res);
0884 if (IS_ERR(pll_base))
0885 return PTR_ERR(pll_base);
0886
0887 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
0888 sys_base = devm_ioremap_resource(&pdev->dev, res);
0889 if (IS_ERR(sys_base))
0890 return PTR_ERR(sys_base);
0891
0892 num_clks = ARRAY_SIZE(bm1880_pll_clks) +
0893 ARRAY_SIZE(bm1880_div_clks) +
0894 ARRAY_SIZE(bm1880_mux_clks) +
0895 ARRAY_SIZE(bm1880_composite_clks) +
0896 ARRAY_SIZE(bm1880_gate_clks);
0897
0898 clk_data = devm_kzalloc(dev, struct_size(clk_data, hw_data.hws,
0899 num_clks), GFP_KERNEL);
0900 if (!clk_data)
0901 return -ENOMEM;
0902
0903 clk_data->pll_base = pll_base;
0904 clk_data->sys_base = sys_base;
0905
0906 for (i = 0; i < num_clks; i++)
0907 clk_data->hw_data.hws[i] = ERR_PTR(-ENOENT);
0908
0909 clk_data->hw_data.num = num_clks;
0910
0911 bm1880_clk_register_plls(bm1880_pll_clks,
0912 ARRAY_SIZE(bm1880_pll_clks),
0913 clk_data);
0914
0915 bm1880_clk_register_divs(bm1880_div_clks,
0916 ARRAY_SIZE(bm1880_div_clks),
0917 clk_data);
0918
0919 bm1880_clk_register_mux(bm1880_mux_clks,
0920 ARRAY_SIZE(bm1880_mux_clks),
0921 clk_data);
0922
0923 bm1880_clk_register_composites(bm1880_composite_clks,
0924 ARRAY_SIZE(bm1880_composite_clks),
0925 clk_data);
0926
0927 bm1880_clk_register_gate(bm1880_gate_clks,
0928 ARRAY_SIZE(bm1880_gate_clks),
0929 clk_data);
0930
0931 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
0932 &clk_data->hw_data);
0933 }
0934
0935 static const struct of_device_id bm1880_of_match[] = {
0936 { .compatible = "bitmain,bm1880-clk", },
0937 {}
0938 };
0939 MODULE_DEVICE_TABLE(of, bm1880_of_match);
0940
0941 static struct platform_driver bm1880_clk_driver = {
0942 .driver = {
0943 .name = "bm1880-clk",
0944 .of_match_table = bm1880_of_match,
0945 },
0946 .probe = bm1880_clk_probe,
0947 };
0948 module_platform_driver(bm1880_clk_driver);
0949
0950 MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
0951 MODULE_DESCRIPTION("Clock driver for Bitmain BM1880 SoC");
0952 MODULE_LICENSE("GPL v2");