1401 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * R9A06G032 clock driver4 *5 * Copyright (C) 2018 Renesas Electronics Europe Limited6 *7 * Michel Pollet <michel.pollet@bp.renesas.com>, <buserror@gmail.com>8 */9 10#include <linux/clk.h>11#include <linux/clk-provider.h>12#include <linux/delay.h>13#include <linux/init.h>14#include <linux/io.h>15#include <linux/kernel.h>16#include <linux/math64.h>17#include <linux/of.h>18#include <linux/of_address.h>19#include <linux/of_platform.h>20#include <linux/platform_device.h>21#include <linux/pm_clock.h>22#include <linux/pm_domain.h>23#include <linux/slab.h>24#include <linux/soc/renesas/r9a06g032-sysctrl.h>25#include <linux/spinlock.h>26#include <dt-bindings/clock/r9a06g032-sysctrl.h>27 28#define R9A06G032_SYSCTRL_USB 0x0029#define R9A06G032_SYSCTRL_USB_H2MODE (1<<1)30#define R9A06G032_SYSCTRL_DMAMUX 0xA031 32/**33 * struct regbit - describe one bit in a register34 * @reg: offset of register relative to base address,35 * expressed in units of 32-bit words (not bytes),36 * @bit: which bit (0 to 31) in the register37 *38 * This structure is used to compactly encode the location39 * of a single bit in a register. Five bits are needed to40 * encode the bit number. With uint16_t data type, this41 * leaves 11 bits to encode a register offset up to 2047.42 *43 * Since registers are aligned on 32-bit boundaries, the44 * offset will be specified in 32-bit words rather than bytes.45 * This allows encoding an offset up to 0x1FFC (8188) bytes.46 *47 * Helper macro RB() takes care of converting the register48 * offset from bytes to 32-bit words.49 */50struct regbit {51 u16 bit:5;52 u16 reg:11;53};54 55#define RB(_reg, _bit) ((struct regbit) { \56 .reg = (_reg) / 4, \57 .bit = (_bit) \58})59 60/**61 * struct r9a06g032_gate - clock-related control bits62 * @gate: clock enable/disable63 * @reset: clock module reset (active low)64 * @ready: enables NoC forwarding of read/write requests to device,65 * (eg. device is ready to handle read/write requests)66 * @midle: request to idle the NoC interconnect67 *68 * Each of these fields describes a single bit in a register,69 * which controls some aspect of clock gating. The @gate field70 * is mandatory, this one enables/disables the clock. The71 * other fields are optional, with zero indicating "not used".72 *73 * In most cases there is a @reset bit which needs to be74 * de-asserted to bring the module out of reset.75 *76 * Modules may also need to signal when they are @ready to77 * handle requests (read/writes) from the NoC interconnect.78 *79 * Similarly, the @midle bit is used to idle the master.80 */81struct r9a06g032_gate {82 struct regbit gate, reset, ready, midle;83 /* Unused fields omitted to save space */84 /* struct regbit scon, mirack, mistat */;85};86 87enum gate_type {88 K_GATE = 0, /* gate which enable/disable */89 K_FFC, /* fixed factor clock */90 K_DIV, /* divisor */91 K_BITSEL, /* special for UARTs */92 K_DUALGATE /* special for UARTs */93};94 95/**96 * struct r9a06g032_clkdesc - describe a single clock97 * @name: string describing this clock98 * @managed: boolean indicating if this clock should be99 * started/stopped as part of power management100 * @type: see enum @gate_type101 * @index: the ID of this clock element102 * @source: the ID+1 of the parent clock element.103 * Root clock uses ID of ~0 (PARENT_ID);104 * @gate: clock enable/disable105 * @div: substructure for clock divider106 * @div.min: smallest permitted clock divider107 * @div.max: largest permitted clock divider108 * @div.reg: clock divider register offset, in 32-bit words109 * @div.table: optional list of fixed clock divider values;110 * must be in ascending order, zero for unused111 * @ffc: substructure for fixed-factor clocks112 * @ffc.div: divisor for fixed-factor clock113 * @ffc.mul: multiplier for fixed-factor clock114 * @dual: substructure for dual clock gates115 * @dual.group: UART group, 0=UART0/1/2, 1=UART3/4/5/6/7116 * @dual.sel: select either g1/r1 or g2/r2 as clock source117 * @dual.g1: 1st source gate (clock enable/disable)118 * @dual.r1: 1st source reset (module reset)119 * @dual.g2: 2nd source gate (clock enable/disable)120 * @dual.r2: 2nd source reset (module reset)121 *122 * Describes a single element in the clock tree hierarchy.123 * As there are quite a large number of clock elements, this124 * structure is packed tightly to conserve space.125 */126struct r9a06g032_clkdesc {127 const char *name;128 uint32_t managed:1;129 enum gate_type type:3;130 uint32_t index:8;131 uint32_t source:8; /* source index + 1 (0 == none) */132 union {133 /* type = K_GATE */134 struct r9a06g032_gate gate;135 /* type = K_DIV */136 struct {137 unsigned int min:10, max:10, reg:10;138 u16 table[4];139 } div;140 /* type = K_FFC */141 struct {142 u16 div, mul;143 } ffc;144 /* type = K_DUALGATE */145 struct {146 uint16_t group:1;147 struct regbit sel, g1, r1, g2, r2;148 } dual;149 };150};151 152/*153 * The last three arguments are not currently used,154 * but are kept in the r9a06g032_clocks table below.155 */156#define I_GATE(_clk, _rst, _rdy, _midle, _scon, _mirack, _mistat) { \157 .gate = _clk, \158 .reset = _rst, \159 .ready = _rdy, \160 .midle = _midle, \161 /* .scon = _scon, */ \162 /* .mirack = _mirack, */ \163 /* .mistat = _mistat */ \164}165#define D_GATE(_idx, _n, _src, ...) { \166 .type = K_GATE, \167 .index = R9A06G032_##_idx, \168 .source = 1 + R9A06G032_##_src, \169 .name = _n, \170 .gate = I_GATE(__VA_ARGS__) \171}172#define D_MODULE(_idx, _n, _src, ...) { \173 .type = K_GATE, \174 .index = R9A06G032_##_idx, \175 .source = 1 + R9A06G032_##_src, \176 .name = _n, \177 .managed = 1, \178 .gate = I_GATE(__VA_ARGS__) \179}180#define D_ROOT(_idx, _n, _mul, _div) { \181 .type = K_FFC, \182 .index = R9A06G032_##_idx, \183 .name = _n, \184 .ffc.div = _div, \185 .ffc.mul = _mul \186}187#define D_FFC(_idx, _n, _src, _div) { \188 .type = K_FFC, \189 .index = R9A06G032_##_idx, \190 .source = 1 + R9A06G032_##_src, \191 .name = _n, \192 .ffc.div = _div, \193 .ffc.mul = 1 \194}195#define D_DIV(_idx, _n, _src, _reg, _min, _max, ...) { \196 .type = K_DIV, \197 .index = R9A06G032_##_idx, \198 .source = 1 + R9A06G032_##_src, \199 .name = _n, \200 .div.reg = _reg, \201 .div.min = _min, \202 .div.max = _max, \203 .div.table = { __VA_ARGS__ } \204}205#define D_UGATE(_idx, _n, _src, _g, _g1, _r1, _g2, _r2) { \206 .type = K_DUALGATE, \207 .index = R9A06G032_##_idx, \208 .source = 1 + R9A06G032_##_src, \209 .name = _n, \210 .dual = { \211 .group = _g, \212 .g1 = _g1, \213 .r1 = _r1, \214 .g2 = _g2, \215 .r2 = _r2 \216 }, \217}218 219/* Internal clock IDs */220#define R9A06G032_CLKOUT 0221#define R9A06G032_CLKOUT_D10 2222#define R9A06G032_CLKOUT_D16 3223#define R9A06G032_CLKOUT_D160 4224#define R9A06G032_CLKOUT_D1OR2 5225#define R9A06G032_CLKOUT_D20 6226#define R9A06G032_CLKOUT_D40 7227#define R9A06G032_CLKOUT_D5 8228#define R9A06G032_CLKOUT_D8 9229#define R9A06G032_DIV_ADC 10230#define R9A06G032_DIV_I2C 11231#define R9A06G032_DIV_NAND 12232#define R9A06G032_DIV_P1_PG 13233#define R9A06G032_DIV_P2_PG 14234#define R9A06G032_DIV_P3_PG 15235#define R9A06G032_DIV_P4_PG 16236#define R9A06G032_DIV_P5_PG 17237#define R9A06G032_DIV_P6_PG 18238#define R9A06G032_DIV_QSPI0 19239#define R9A06G032_DIV_QSPI1 20240#define R9A06G032_DIV_REF_SYNC 21241#define R9A06G032_DIV_SDIO0 22242#define R9A06G032_DIV_SDIO1 23243#define R9A06G032_DIV_SWITCH 24244#define R9A06G032_DIV_UART 25245#define R9A06G032_DIV_MOTOR 64246#define R9A06G032_CLK_DDRPHY_PLLCLK_D4 78247#define R9A06G032_CLK_ECAT100_D4 79248#define R9A06G032_CLK_HSR100_D2 80249#define R9A06G032_CLK_REF_SYNC_D4 81250#define R9A06G032_CLK_REF_SYNC_D8 82251#define R9A06G032_CLK_SERCOS100_D2 83252#define R9A06G032_DIV_CA7 84253 254#define R9A06G032_UART_GROUP_012 154255#define R9A06G032_UART_GROUP_34567 155256 257#define R9A06G032_CLOCK_COUNT (R9A06G032_UART_GROUP_34567 + 1)258 259static const struct r9a06g032_clkdesc r9a06g032_clocks[] = {260 D_ROOT(CLKOUT, "clkout", 25, 1),261 D_ROOT(CLK_PLL_USB, "clk_pll_usb", 12, 10),262 D_FFC(CLKOUT_D10, "clkout_d10", CLKOUT, 10),263 D_FFC(CLKOUT_D16, "clkout_d16", CLKOUT, 16),264 D_FFC(CLKOUT_D160, "clkout_d160", CLKOUT, 160),265 D_DIV(CLKOUT_D1OR2, "clkout_d1or2", CLKOUT, 0, 1, 2),266 D_FFC(CLKOUT_D20, "clkout_d20", CLKOUT, 20),267 D_FFC(CLKOUT_D40, "clkout_d40", CLKOUT, 40),268 D_FFC(CLKOUT_D5, "clkout_d5", CLKOUT, 5),269 D_FFC(CLKOUT_D8, "clkout_d8", CLKOUT, 8),270 D_DIV(DIV_ADC, "div_adc", CLKOUT, 77, 50, 250),271 D_DIV(DIV_I2C, "div_i2c", CLKOUT, 78, 12, 16),272 D_DIV(DIV_NAND, "div_nand", CLKOUT, 82, 12, 32),273 D_DIV(DIV_P1_PG, "div_p1_pg", CLKOUT, 68, 12, 200),274 D_DIV(DIV_P2_PG, "div_p2_pg", CLKOUT, 62, 12, 128),275 D_DIV(DIV_P3_PG, "div_p3_pg", CLKOUT, 64, 8, 128),276 D_DIV(DIV_P4_PG, "div_p4_pg", CLKOUT, 66, 8, 128),277 D_DIV(DIV_P5_PG, "div_p5_pg", CLKOUT, 71, 10, 40),278 D_DIV(DIV_P6_PG, "div_p6_pg", CLKOUT, 18, 12, 64),279 D_DIV(DIV_QSPI0, "div_qspi0", CLKOUT, 73, 3, 7),280 D_DIV(DIV_QSPI1, "div_qspi1", CLKOUT, 25, 3, 7),281 D_DIV(DIV_REF_SYNC, "div_ref_sync", CLKOUT, 56, 2, 16, 2, 4, 8, 16),282 D_DIV(DIV_SDIO0, "div_sdio0", CLKOUT, 74, 20, 128),283 D_DIV(DIV_SDIO1, "div_sdio1", CLKOUT, 75, 20, 128),284 D_DIV(DIV_SWITCH, "div_switch", CLKOUT, 37, 5, 40),285 D_DIV(DIV_UART, "div_uart", CLKOUT, 79, 12, 128),286 D_GATE(CLK_25_PG4, "clk_25_pg4", CLKOUT_D40, RB(0xe8, 9),287 RB(0xe8, 10), RB(0xe8, 11), RB(0x00, 0),288 RB(0x15c, 3), RB(0x00, 0), RB(0x00, 0)),289 D_GATE(CLK_25_PG5, "clk_25_pg5", CLKOUT_D40, RB(0xe8, 12),290 RB(0xe8, 13), RB(0xe8, 14), RB(0x00, 0),291 RB(0x15c, 4), RB(0x00, 0), RB(0x00, 0)),292 D_GATE(CLK_25_PG6, "clk_25_pg6", CLKOUT_D40, RB(0xe8, 15),293 RB(0xe8, 16), RB(0xe8, 17), RB(0x00, 0),294 RB(0x15c, 5), RB(0x00, 0), RB(0x00, 0)),295 D_GATE(CLK_25_PG7, "clk_25_pg7", CLKOUT_D40, RB(0xe8, 18),296 RB(0xe8, 19), RB(0xe8, 20), RB(0x00, 0),297 RB(0x15c, 6), RB(0x00, 0), RB(0x00, 0)),298 D_GATE(CLK_25_PG8, "clk_25_pg8", CLKOUT_D40, RB(0xe8, 21),299 RB(0xe8, 22), RB(0xe8, 23), RB(0x00, 0),300 RB(0x15c, 7), RB(0x00, 0), RB(0x00, 0)),301 D_GATE(CLK_ADC, "clk_adc", DIV_ADC, RB(0x3c, 10),302 RB(0x3c, 11), RB(0x00, 0), RB(0x00, 0),303 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),304 D_GATE(CLK_ECAT100, "clk_ecat100", CLKOUT_D10, RB(0x80, 5),305 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),306 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),307 D_GATE(CLK_HSR100, "clk_hsr100", CLKOUT_D10, RB(0x90, 3),308 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),309 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),310 D_GATE(CLK_I2C0, "clk_i2c0", DIV_I2C, RB(0x3c, 6),311 RB(0x3c, 7), RB(0x00, 0), RB(0x00, 0),312 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),313 D_GATE(CLK_I2C1, "clk_i2c1", DIV_I2C, RB(0x3c, 8),314 RB(0x3c, 9), RB(0x00, 0), RB(0x00, 0),315 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),316 D_GATE(CLK_MII_REF, "clk_mii_ref", CLKOUT_D40, RB(0x68, 2),317 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),318 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),319 D_GATE(CLK_NAND, "clk_nand", DIV_NAND, RB(0x50, 4),320 RB(0x50, 5), RB(0x00, 0), RB(0x00, 0),321 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),322 D_GATE(CLK_NOUSBP2_PG6, "clk_nousbp2_pg6", DIV_P2_PG, RB(0xec, 20),323 RB(0xec, 21), RB(0x00, 0), RB(0x00, 0),324 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),325 D_GATE(CLK_P1_PG2, "clk_p1_pg2", DIV_P1_PG, RB(0x10c, 2),326 RB(0x10c, 3), RB(0x00, 0), RB(0x00, 0),327 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),328 D_GATE(CLK_P1_PG3, "clk_p1_pg3", DIV_P1_PG, RB(0x10c, 4),329 RB(0x10c, 5), RB(0x00, 0), RB(0x00, 0),330 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),331 D_GATE(CLK_P1_PG4, "clk_p1_pg4", DIV_P1_PG, RB(0x10c, 6),332 RB(0x10c, 7), RB(0x00, 0), RB(0x00, 0),333 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),334 D_GATE(CLK_P4_PG3, "clk_p4_pg3", DIV_P4_PG, RB(0x104, 4),335 RB(0x104, 5), RB(0x00, 0), RB(0x00, 0),336 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),337 D_GATE(CLK_P4_PG4, "clk_p4_pg4", DIV_P4_PG, RB(0x104, 6),338 RB(0x104, 7), RB(0x00, 0), RB(0x00, 0),339 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),340 D_GATE(CLK_P6_PG1, "clk_p6_pg1", DIV_P6_PG, RB(0x114, 0),341 RB(0x114, 1), RB(0x114, 2), RB(0x00, 0),342 RB(0x16c, 0), RB(0x00, 0), RB(0x00, 0)),343 D_GATE(CLK_P6_PG2, "clk_p6_pg2", DIV_P6_PG, RB(0x114, 3),344 RB(0x114, 4), RB(0x114, 5), RB(0x00, 0),345 RB(0x16c, 1), RB(0x00, 0), RB(0x00, 0)),346 D_GATE(CLK_P6_PG3, "clk_p6_pg3", DIV_P6_PG, RB(0x114, 6),347 RB(0x114, 7), RB(0x114, 8), RB(0x00, 0),348 RB(0x16c, 2), RB(0x00, 0), RB(0x00, 0)),349 D_GATE(CLK_P6_PG4, "clk_p6_pg4", DIV_P6_PG, RB(0x114, 9),350 RB(0x114, 10), RB(0x114, 11), RB(0x00, 0),351 RB(0x16c, 3), RB(0x00, 0), RB(0x00, 0)),352 D_MODULE(CLK_PCI_USB, "clk_pci_usb", CLKOUT_D40, RB(0x1c, 6),353 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),354 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),355 D_GATE(CLK_QSPI0, "clk_qspi0", DIV_QSPI0, RB(0x54, 4),356 RB(0x54, 5), RB(0x00, 0), RB(0x00, 0),357 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),358 D_GATE(CLK_QSPI1, "clk_qspi1", DIV_QSPI1, RB(0x90, 4),359 RB(0x90, 5), RB(0x00, 0), RB(0x00, 0),360 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),361 D_GATE(CLK_RGMII_REF, "clk_rgmii_ref", CLKOUT_D8, RB(0x68, 0),362 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),363 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),364 D_GATE(CLK_RMII_REF, "clk_rmii_ref", CLKOUT_D20, RB(0x68, 1),365 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),366 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),367 D_GATE(CLK_SDIO0, "clk_sdio0", DIV_SDIO0, RB(0x0c, 4),368 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),369 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),370 D_GATE(CLK_SDIO1, "clk_sdio1", DIV_SDIO1, RB(0xc8, 4),371 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),372 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),373 D_GATE(CLK_SERCOS100, "clk_sercos100", CLKOUT_D10, RB(0x84, 5),374 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),375 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),376 D_GATE(CLK_SLCD, "clk_slcd", DIV_P1_PG, RB(0x10c, 0),377 RB(0x10c, 1), RB(0x00, 0), RB(0x00, 0),378 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),379 D_GATE(CLK_SPI0, "clk_spi0", DIV_P3_PG, RB(0xfc, 0),380 RB(0xfc, 1), RB(0x00, 0), RB(0x00, 0),381 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),382 D_GATE(CLK_SPI1, "clk_spi1", DIV_P3_PG, RB(0xfc, 2),383 RB(0xfc, 3), RB(0x00, 0), RB(0x00, 0),384 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),385 D_GATE(CLK_SPI2, "clk_spi2", DIV_P3_PG, RB(0xfc, 4),386 RB(0xfc, 5), RB(0x00, 0), RB(0x00, 0),387 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),388 D_GATE(CLK_SPI3, "clk_spi3", DIV_P3_PG, RB(0xfc, 6),389 RB(0xfc, 7), RB(0x00, 0), RB(0x00, 0),390 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),391 D_GATE(CLK_SPI4, "clk_spi4", DIV_P4_PG, RB(0x104, 0),392 RB(0x104, 1), RB(0x00, 0), RB(0x00, 0),393 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),394 D_GATE(CLK_SPI5, "clk_spi5", DIV_P4_PG, RB(0x104, 2),395 RB(0x104, 3), RB(0x00, 0), RB(0x00, 0),396 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),397 D_GATE(CLK_SWITCH, "clk_switch", DIV_SWITCH, RB(0x130, 2),398 RB(0x130, 3), RB(0x00, 0), RB(0x00, 0),399 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),400 D_DIV(DIV_MOTOR, "div_motor", CLKOUT_D5, 84, 2, 8),401 D_MODULE(HCLK_ECAT125, "hclk_ecat125", CLKOUT_D8, RB(0x80, 0),402 RB(0x80, 1), RB(0x00, 0), RB(0x80, 2),403 RB(0x00, 0), RB(0x88, 0), RB(0x88, 1)),404 D_MODULE(HCLK_PINCONFIG, "hclk_pinconfig", CLKOUT_D40, RB(0xe8, 0),405 RB(0xe8, 1), RB(0xe8, 2), RB(0x00, 0),406 RB(0x15c, 0), RB(0x00, 0), RB(0x00, 0)),407 D_MODULE(HCLK_SERCOS, "hclk_sercos", CLKOUT_D10, RB(0x84, 0),408 RB(0x84, 2), RB(0x00, 0), RB(0x84, 1),409 RB(0x00, 0), RB(0x8c, 0), RB(0x8c, 1)),410 D_MODULE(HCLK_SGPIO2, "hclk_sgpio2", DIV_P5_PG, RB(0x118, 3),411 RB(0x118, 4), RB(0x118, 5), RB(0x00, 0),412 RB(0x168, 1), RB(0x00, 0), RB(0x00, 0)),413 D_MODULE(HCLK_SGPIO3, "hclk_sgpio3", DIV_P5_PG, RB(0x118, 6),414 RB(0x118, 7), RB(0x118, 8), RB(0x00, 0),415 RB(0x168, 2), RB(0x00, 0), RB(0x00, 0)),416 D_MODULE(HCLK_SGPIO4, "hclk_sgpio4", DIV_P5_PG, RB(0x118, 9),417 RB(0x118, 10), RB(0x118, 11), RB(0x00, 0),418 RB(0x168, 3), RB(0x00, 0), RB(0x00, 0)),419 D_MODULE(HCLK_TIMER0, "hclk_timer0", CLKOUT_D40, RB(0xe8, 3),420 RB(0xe8, 4), RB(0xe8, 5), RB(0x00, 0),421 RB(0x15c, 1), RB(0x00, 0), RB(0x00, 0)),422 D_MODULE(HCLK_TIMER1, "hclk_timer1", CLKOUT_D40, RB(0xe8, 6),423 RB(0xe8, 7), RB(0xe8, 8), RB(0x00, 0),424 RB(0x15c, 2), RB(0x00, 0), RB(0x00, 0)),425 D_MODULE(HCLK_USBF, "hclk_usbf", CLKOUT_D8, RB(0x1c, 3),426 RB(0x00, 0), RB(0x00, 0), RB(0x1c, 4),427 RB(0x00, 0), RB(0x20, 2), RB(0x20, 3)),428 D_MODULE(HCLK_USBH, "hclk_usbh", CLKOUT_D8, RB(0x1c, 0),429 RB(0x1c, 1), RB(0x00, 0), RB(0x1c, 2),430 RB(0x00, 0), RB(0x20, 0), RB(0x20, 1)),431 D_MODULE(HCLK_USBPM, "hclk_usbpm", CLKOUT_D8, RB(0x1c, 5),432 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),433 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),434 D_GATE(CLK_48_PG_F, "clk_48_pg_f", CLK_48, RB(0xf0, 12),435 RB(0xf0, 13), RB(0x00, 0), RB(0xf0, 14),436 RB(0x00, 0), RB(0x160, 4), RB(0x160, 5)),437 D_GATE(CLK_48_PG4, "clk_48_pg4", CLK_48, RB(0xf0, 9),438 RB(0xf0, 10), RB(0xf0, 11), RB(0x00, 0),439 RB(0x160, 3), RB(0x00, 0), RB(0x00, 0)),440 D_FFC(CLK_DDRPHY_PLLCLK_D4, "clk_ddrphy_pllclk_d4", CLK_DDRPHY_PLLCLK, 4),441 D_FFC(CLK_ECAT100_D4, "clk_ecat100_d4", CLK_ECAT100, 4),442 D_FFC(CLK_HSR100_D2, "clk_hsr100_d2", CLK_HSR100, 2),443 D_FFC(CLK_REF_SYNC_D4, "clk_ref_sync_d4", CLK_REF_SYNC, 4),444 D_FFC(CLK_REF_SYNC_D8, "clk_ref_sync_d8", CLK_REF_SYNC, 8),445 D_FFC(CLK_SERCOS100_D2, "clk_sercos100_d2", CLK_SERCOS100, 2),446 D_DIV(DIV_CA7, "div_ca7", CLK_REF_SYNC, 57, 1, 4, 1, 2, 4),447 D_MODULE(HCLK_CAN0, "hclk_can0", CLK_48, RB(0xf0, 3),448 RB(0xf0, 4), RB(0xf0, 5), RB(0x00, 0),449 RB(0x160, 1), RB(0x00, 0), RB(0x00, 0)),450 D_MODULE(HCLK_CAN1, "hclk_can1", CLK_48, RB(0xf0, 6),451 RB(0xf0, 7), RB(0xf0, 8), RB(0x00, 0),452 RB(0x160, 2), RB(0x00, 0), RB(0x00, 0)),453 D_MODULE(HCLK_DELTASIGMA, "hclk_deltasigma", DIV_MOTOR, RB(0x3c, 15),454 RB(0x3c, 16), RB(0x3c, 17), RB(0x00, 0),455 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),456 D_MODULE(HCLK_PWMPTO, "hclk_pwmpto", DIV_MOTOR, RB(0x3c, 12),457 RB(0x3c, 13), RB(0x3c, 14), RB(0x00, 0),458 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),459 D_MODULE(HCLK_RSV, "hclk_rsv", CLK_48, RB(0xf0, 0),460 RB(0xf0, 1), RB(0xf0, 2), RB(0x00, 0),461 RB(0x160, 0), RB(0x00, 0), RB(0x00, 0)),462 D_MODULE(HCLK_SGPIO0, "hclk_sgpio0", DIV_MOTOR, RB(0x3c, 0),463 RB(0x3c, 1), RB(0x3c, 2), RB(0x00, 0),464 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),465 D_MODULE(HCLK_SGPIO1, "hclk_sgpio1", DIV_MOTOR, RB(0x3c, 3),466 RB(0x3c, 4), RB(0x3c, 5), RB(0x00, 0),467 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),468 D_DIV(RTOS_MDC, "rtos_mdc", CLK_REF_SYNC, 100, 80, 640, 80, 160, 320, 640),469 D_GATE(CLK_CM3, "clk_cm3", CLK_REF_SYNC_D4, RB(0x174, 0),470 RB(0x174, 1), RB(0x00, 0), RB(0x174, 2),471 RB(0x00, 0), RB(0x178, 0), RB(0x178, 1)),472 D_GATE(CLK_DDRC, "clk_ddrc", CLK_DDRPHY_PLLCLK_D4, RB(0x64, 3),473 RB(0x64, 4), RB(0x00, 0), RB(0x00, 0),474 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),475 D_GATE(CLK_ECAT25, "clk_ecat25", CLK_ECAT100_D4, RB(0x80, 3),476 RB(0x80, 4), RB(0x00, 0), RB(0x00, 0),477 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),478 D_GATE(CLK_HSR50, "clk_hsr50", CLK_HSR100_D2, RB(0x90, 4),479 RB(0x90, 5), RB(0x00, 0), RB(0x00, 0),480 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),481 D_GATE(CLK_HW_RTOS, "clk_hw_rtos", CLK_REF_SYNC_D4, RB(0x18c, 0),482 RB(0x18c, 1), RB(0x00, 0), RB(0x00, 0),483 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),484 D_GATE(CLK_SERCOS50, "clk_sercos50", CLK_SERCOS100_D2, RB(0x84, 4),485 RB(0x84, 3), RB(0x00, 0), RB(0x00, 0),486 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),487 D_MODULE(HCLK_ADC, "hclk_adc", CLK_REF_SYNC_D8, RB(0x34, 15),488 RB(0x34, 16), RB(0x34, 17), RB(0x00, 0),489 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),490 D_MODULE(HCLK_CM3, "hclk_cm3", CLK_REF_SYNC_D4, RB(0x184, 0),491 RB(0x184, 1), RB(0x184, 2), RB(0x00, 0),492 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),493 D_MODULE(HCLK_CRYPTO_EIP150, "hclk_crypto_eip150", CLK_REF_SYNC_D4, RB(0x24, 3),494 RB(0x24, 4), RB(0x24, 5), RB(0x00, 0),495 RB(0x28, 2), RB(0x00, 0), RB(0x00, 0)),496 D_MODULE(HCLK_CRYPTO_EIP93, "hclk_crypto_eip93", CLK_REF_SYNC_D4, RB(0x24, 0),497 RB(0x24, 1), RB(0x00, 0), RB(0x24, 2),498 RB(0x00, 0), RB(0x28, 0), RB(0x28, 1)),499 D_MODULE(HCLK_DDRC, "hclk_ddrc", CLK_REF_SYNC_D4, RB(0x64, 0),500 RB(0x64, 2), RB(0x00, 0), RB(0x64, 1),501 RB(0x00, 0), RB(0x74, 0), RB(0x74, 1)),502 D_MODULE(HCLK_DMA0, "hclk_dma0", CLK_REF_SYNC_D4, RB(0x4c, 0),503 RB(0x4c, 1), RB(0x4c, 2), RB(0x4c, 3),504 RB(0x58, 0), RB(0x58, 1), RB(0x58, 2)),505 D_MODULE(HCLK_DMA1, "hclk_dma1", CLK_REF_SYNC_D4, RB(0x4c, 4),506 RB(0x4c, 5), RB(0x4c, 6), RB(0x4c, 7),507 RB(0x58, 3), RB(0x58, 4), RB(0x58, 5)),508 D_MODULE(HCLK_GMAC0, "hclk_gmac0", CLK_REF_SYNC_D4, RB(0x6c, 0),509 RB(0x6c, 1), RB(0x6c, 2), RB(0x6c, 3),510 RB(0x78, 0), RB(0x78, 1), RB(0x78, 2)),511 D_MODULE(HCLK_GMAC1, "hclk_gmac1", CLK_REF_SYNC_D4, RB(0x70, 0),512 RB(0x70, 1), RB(0x70, 2), RB(0x70, 3),513 RB(0x7c, 0), RB(0x7c, 1), RB(0x7c, 2)),514 D_MODULE(HCLK_GPIO0, "hclk_gpio0", CLK_REF_SYNC_D4, RB(0x40, 18),515 RB(0x40, 19), RB(0x40, 20), RB(0x00, 0),516 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),517 D_MODULE(HCLK_GPIO1, "hclk_gpio1", CLK_REF_SYNC_D4, RB(0x40, 21),518 RB(0x40, 22), RB(0x40, 23), RB(0x00, 0),519 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),520 D_MODULE(HCLK_GPIO2, "hclk_gpio2", CLK_REF_SYNC_D4, RB(0x44, 9),521 RB(0x44, 10), RB(0x44, 11), RB(0x00, 0),522 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),523 D_MODULE(HCLK_HSR, "hclk_hsr", CLK_HSR100_D2, RB(0x90, 0),524 RB(0x90, 2), RB(0x00, 0), RB(0x90, 1),525 RB(0x00, 0), RB(0x98, 0), RB(0x98, 1)),526 D_MODULE(HCLK_I2C0, "hclk_i2c0", CLK_REF_SYNC_D8, RB(0x34, 9),527 RB(0x34, 10), RB(0x34, 11), RB(0x00, 0),528 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),529 D_MODULE(HCLK_I2C1, "hclk_i2c1", CLK_REF_SYNC_D8, RB(0x34, 12),530 RB(0x34, 13), RB(0x34, 14), RB(0x00, 0),531 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),532 D_MODULE(HCLK_LCD, "hclk_lcd", CLK_REF_SYNC_D4, RB(0xf4, 0),533 RB(0xf4, 1), RB(0xf4, 2), RB(0x00, 0),534 RB(0x164, 0), RB(0x00, 0), RB(0x00, 0)),535 D_MODULE(HCLK_MSEBI_M, "hclk_msebi_m", CLK_REF_SYNC_D4, RB(0x2c, 4),536 RB(0x2c, 5), RB(0x2c, 6), RB(0x00, 0),537 RB(0x30, 3), RB(0x00, 0), RB(0x00, 0)),538 D_MODULE(HCLK_MSEBI_S, "hclk_msebi_s", CLK_REF_SYNC_D4, RB(0x2c, 0),539 RB(0x2c, 1), RB(0x2c, 2), RB(0x2c, 3),540 RB(0x30, 0), RB(0x30, 1), RB(0x30, 2)),541 D_MODULE(HCLK_NAND, "hclk_nand", CLK_REF_SYNC_D4, RB(0x50, 0),542 RB(0x50, 1), RB(0x50, 2), RB(0x50, 3),543 RB(0x5c, 0), RB(0x5c, 1), RB(0x5c, 2)),544 D_MODULE(HCLK_PG_I, "hclk_pg_i", CLK_REF_SYNC_D4, RB(0xf4, 12),545 RB(0xf4, 13), RB(0x00, 0), RB(0xf4, 14),546 RB(0x00, 0), RB(0x164, 4), RB(0x164, 5)),547 D_MODULE(HCLK_PG19, "hclk_pg19", CLK_REF_SYNC_D4, RB(0x44, 12),548 RB(0x44, 13), RB(0x44, 14), RB(0x00, 0),549 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),550 D_MODULE(HCLK_PG20, "hclk_pg20", CLK_REF_SYNC_D4, RB(0x44, 15),551 RB(0x44, 16), RB(0x44, 17), RB(0x00, 0),552 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),553 D_MODULE(HCLK_PG3, "hclk_pg3", CLK_REF_SYNC_D4, RB(0xf4, 6),554 RB(0xf4, 7), RB(0xf4, 8), RB(0x00, 0),555 RB(0x164, 2), RB(0x00, 0), RB(0x00, 0)),556 D_MODULE(HCLK_PG4, "hclk_pg4", CLK_REF_SYNC_D4, RB(0xf4, 9),557 RB(0xf4, 10), RB(0xf4, 11), RB(0x00, 0),558 RB(0x164, 3), RB(0x00, 0), RB(0x00, 0)),559 D_MODULE(HCLK_QSPI0, "hclk_qspi0", CLK_REF_SYNC_D4, RB(0x54, 0),560 RB(0x54, 1), RB(0x54, 2), RB(0x54, 3),561 RB(0x60, 0), RB(0x60, 1), RB(0x60, 2)),562 D_MODULE(HCLK_QSPI1, "hclk_qspi1", CLK_REF_SYNC_D4, RB(0x90, 0),563 RB(0x90, 1), RB(0x90, 2), RB(0x90, 3),564 RB(0x98, 0), RB(0x98, 1), RB(0x98, 2)),565 D_MODULE(HCLK_ROM, "hclk_rom", CLK_REF_SYNC_D4, RB(0x154, 0),566 RB(0x154, 1), RB(0x154, 2), RB(0x00, 0),567 RB(0x170, 0), RB(0x00, 0), RB(0x00, 0)),568 D_MODULE(HCLK_RTC, "hclk_rtc", CLK_REF_SYNC_D8, RB(0x140, 0),569 RB(0x140, 3), RB(0x00, 0), RB(0x140, 2),570 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),571 D_MODULE(HCLK_SDIO0, "hclk_sdio0", CLK_REF_SYNC_D4, RB(0x0c, 0),572 RB(0x0c, 1), RB(0x0c, 2), RB(0x0c, 3),573 RB(0x10, 0), RB(0x10, 1), RB(0x10, 2)),574 D_MODULE(HCLK_SDIO1, "hclk_sdio1", CLK_REF_SYNC_D4, RB(0xc8, 0),575 RB(0xc8, 1), RB(0xc8, 2), RB(0xc8, 3),576 RB(0xcc, 0), RB(0xcc, 1), RB(0xcc, 2)),577 D_MODULE(HCLK_SEMAP, "hclk_semap", CLK_REF_SYNC_D4, RB(0xf4, 3),578 RB(0xf4, 4), RB(0xf4, 5), RB(0x00, 0),579 RB(0x164, 1), RB(0x00, 0), RB(0x00, 0)),580 D_MODULE(HCLK_SPI0, "hclk_spi0", CLK_REF_SYNC_D4, RB(0x40, 0),581 RB(0x40, 1), RB(0x40, 2), RB(0x00, 0),582 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),583 D_MODULE(HCLK_SPI1, "hclk_spi1", CLK_REF_SYNC_D4, RB(0x40, 3),584 RB(0x40, 4), RB(0x40, 5), RB(0x00, 0),585 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),586 D_MODULE(HCLK_SPI2, "hclk_spi2", CLK_REF_SYNC_D4, RB(0x40, 6),587 RB(0x40, 7), RB(0x40, 8), RB(0x00, 0),588 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),589 D_MODULE(HCLK_SPI3, "hclk_spi3", CLK_REF_SYNC_D4, RB(0x40, 9),590 RB(0x40, 10), RB(0x40, 11), RB(0x00, 0),591 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),592 D_MODULE(HCLK_SPI4, "hclk_spi4", CLK_REF_SYNC_D4, RB(0x40, 12),593 RB(0x40, 13), RB(0x40, 14), RB(0x00, 0),594 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),595 D_MODULE(HCLK_SPI5, "hclk_spi5", CLK_REF_SYNC_D4, RB(0x40, 15),596 RB(0x40, 16), RB(0x40, 17), RB(0x00, 0),597 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),598 D_MODULE(HCLK_SWITCH, "hclk_switch", CLK_REF_SYNC_D4, RB(0x130, 0),599 RB(0x00, 0), RB(0x130, 1), RB(0x00, 0),600 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),601 D_MODULE(HCLK_SWITCH_RG, "hclk_switch_rg", CLK_REF_SYNC_D4, RB(0x188, 0),602 RB(0x188, 1), RB(0x188, 2), RB(0x00, 0),603 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),604 D_MODULE(HCLK_UART0, "hclk_uart0", CLK_REF_SYNC_D8, RB(0x34, 0),605 RB(0x34, 1), RB(0x34, 2), RB(0x00, 0),606 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),607 D_MODULE(HCLK_UART1, "hclk_uart1", CLK_REF_SYNC_D8, RB(0x34, 3),608 RB(0x34, 4), RB(0x34, 5), RB(0x00, 0),609 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),610 D_MODULE(HCLK_UART2, "hclk_uart2", CLK_REF_SYNC_D8, RB(0x34, 6),611 RB(0x34, 7), RB(0x34, 8), RB(0x00, 0),612 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),613 D_MODULE(HCLK_UART3, "hclk_uart3", CLK_REF_SYNC_D4, RB(0x40, 24),614 RB(0x40, 25), RB(0x40, 26), RB(0x00, 0),615 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),616 D_MODULE(HCLK_UART4, "hclk_uart4", CLK_REF_SYNC_D4, RB(0x40, 27),617 RB(0x40, 28), RB(0x40, 29), RB(0x00, 0),618 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),619 D_MODULE(HCLK_UART5, "hclk_uart5", CLK_REF_SYNC_D4, RB(0x44, 0),620 RB(0x44, 1), RB(0x44, 2), RB(0x00, 0),621 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),622 D_MODULE(HCLK_UART6, "hclk_uart6", CLK_REF_SYNC_D4, RB(0x44, 3),623 RB(0x44, 4), RB(0x44, 5), RB(0x00, 0),624 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),625 D_MODULE(HCLK_UART7, "hclk_uart7", CLK_REF_SYNC_D4, RB(0x44, 6),626 RB(0x44, 7), RB(0x44, 8), RB(0x00, 0),627 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),628 /*629 * These are not hardware clocks, but are needed to handle the special630 * case where we have a 'selector bit' that doesn't just change the631 * parent for a clock, but also the gate it's supposed to use.632 */633 {634 .index = R9A06G032_UART_GROUP_012,635 .name = "uart_group_012",636 .type = K_BITSEL,637 .source = 1 + R9A06G032_DIV_UART,638 /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */639 .dual.sel = RB(0x34, 30),640 .dual.group = 0,641 },642 {643 .index = R9A06G032_UART_GROUP_34567,644 .name = "uart_group_34567",645 .type = K_BITSEL,646 .source = 1 + R9A06G032_DIV_P2_PG,647 /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */648 .dual.sel = RB(0xec, 24),649 .dual.group = 1,650 },651 D_UGATE(CLK_UART0, "clk_uart0", UART_GROUP_012, 0,652 RB(0x34, 18), RB(0x34, 19), RB(0x34, 20), RB(0x34, 21)),653 D_UGATE(CLK_UART1, "clk_uart1", UART_GROUP_012, 0,654 RB(0x34, 22), RB(0x34, 23), RB(0x34, 24), RB(0x34, 25)),655 D_UGATE(CLK_UART2, "clk_uart2", UART_GROUP_012, 0,656 RB(0x34, 26), RB(0x34, 27), RB(0x34, 28), RB(0x34, 29)),657 D_UGATE(CLK_UART3, "clk_uart3", UART_GROUP_34567, 1,658 RB(0xec, 0), RB(0xec, 1), RB(0xec, 2), RB(0xec, 3)),659 D_UGATE(CLK_UART4, "clk_uart4", UART_GROUP_34567, 1,660 RB(0xec, 4), RB(0xec, 5), RB(0xec, 6), RB(0xec, 7)),661 D_UGATE(CLK_UART5, "clk_uart5", UART_GROUP_34567, 1,662 RB(0xec, 8), RB(0xec, 9), RB(0xec, 10), RB(0xec, 11)),663 D_UGATE(CLK_UART6, "clk_uart6", UART_GROUP_34567, 1,664 RB(0xec, 12), RB(0xec, 13), RB(0xec, 14), RB(0xec, 15)),665 D_UGATE(CLK_UART7, "clk_uart7", UART_GROUP_34567, 1,666 RB(0xec, 16), RB(0xec, 17), RB(0xec, 18), RB(0xec, 19)),667};668 669struct r9a06g032_priv {670 struct clk_onecell_data data;671 spinlock_t lock; /* protects concurrent access to gates */672 void __iomem *reg;673};674 675static struct r9a06g032_priv *sysctrl_priv;676 677/* Exported helper to access the DMAMUX register */678int r9a06g032_sysctrl_set_dmamux(u32 mask, u32 val)679{680 unsigned long flags;681 u32 dmamux;682 683 if (!sysctrl_priv)684 return -EPROBE_DEFER;685 686 spin_lock_irqsave(&sysctrl_priv->lock, flags);687 688 dmamux = readl(sysctrl_priv->reg + R9A06G032_SYSCTRL_DMAMUX);689 dmamux &= ~mask;690 dmamux |= val & mask;691 writel(dmamux, sysctrl_priv->reg + R9A06G032_SYSCTRL_DMAMUX);692 693 spin_unlock_irqrestore(&sysctrl_priv->lock, flags);694 695 return 0;696}697EXPORT_SYMBOL_GPL(r9a06g032_sysctrl_set_dmamux);698 699static void clk_rdesc_set(struct r9a06g032_priv *clocks,700 struct regbit rb, unsigned int on)701{702 u32 __iomem *reg = clocks->reg + (rb.reg * 4);703 u32 val;704 705 if (!rb.reg && !rb.bit)706 return;707 708 val = readl(reg);709 val = (val & ~BIT(rb.bit)) | ((!!on) << rb.bit);710 writel(val, reg);711}712 713static int clk_rdesc_get(struct r9a06g032_priv *clocks, struct regbit rb)714{715 u32 __iomem *reg = clocks->reg + (rb.reg * 4);716 u32 val = readl(reg);717 718 return !!(val & BIT(rb.bit));719}720 721/*722 * This implements the R9A06G032 clock gate 'driver'. We cannot use the system's723 * clock gate framework as the gates on the R9A06G032 have a special enabling724 * sequence, therefore we use this little proxy.725 */726struct r9a06g032_clk_gate {727 struct clk_hw hw;728 struct r9a06g032_priv *clocks;729 u16 index;730 731 struct r9a06g032_gate gate;732};733 734#define to_r9a06g032_gate(_hw) container_of(_hw, struct r9a06g032_clk_gate, hw)735 736static int create_add_module_clock(struct of_phandle_args *clkspec,737 struct device *dev)738{739 struct clk *clk;740 int error;741 742 clk = of_clk_get_from_provider(clkspec);743 if (IS_ERR(clk))744 return PTR_ERR(clk);745 746 error = pm_clk_create(dev);747 if (error) {748 clk_put(clk);749 return error;750 }751 752 error = pm_clk_add_clk(dev, clk);753 if (error) {754 pm_clk_destroy(dev);755 clk_put(clk);756 }757 758 return error;759}760 761static int r9a06g032_attach_dev(struct generic_pm_domain *pd,762 struct device *dev)763{764 struct device_node *np = dev->of_node;765 struct of_phandle_args clkspec;766 int i = 0;767 int error;768 int index;769 770 while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i++,771 &clkspec)) {772 if (clkspec.np != pd->dev.of_node)773 continue;774 775 index = clkspec.args[0];776 if (index < R9A06G032_CLOCK_COUNT &&777 r9a06g032_clocks[index].managed) {778 error = create_add_module_clock(&clkspec, dev);779 of_node_put(clkspec.np);780 if (error)781 return error;782 }783 }784 785 return 0;786}787 788static void r9a06g032_detach_dev(struct generic_pm_domain *unused, struct device *dev)789{790 if (!pm_clk_no_clocks(dev))791 pm_clk_destroy(dev);792}793 794static int r9a06g032_add_clk_domain(struct device *dev)795{796 struct device_node *np = dev->of_node;797 struct generic_pm_domain *pd;798 799 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);800 if (!pd)801 return -ENOMEM;802 803 pd->name = np->name;804 pd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON |805 GENPD_FLAG_ACTIVE_WAKEUP;806 pd->attach_dev = r9a06g032_attach_dev;807 pd->detach_dev = r9a06g032_detach_dev;808 pm_genpd_init(pd, &pm_domain_always_on_gov, false);809 810 of_genpd_add_provider_simple(np, pd);811 return 0;812}813 814static void815r9a06g032_clk_gate_set(struct r9a06g032_priv *clocks,816 struct r9a06g032_gate *g, int on)817{818 unsigned long flags;819 820 WARN_ON(!g->gate.reg && !g->gate.bit);821 822 spin_lock_irqsave(&clocks->lock, flags);823 clk_rdesc_set(clocks, g->gate, on);824 /* De-assert reset */825 clk_rdesc_set(clocks, g->reset, 1);826 spin_unlock_irqrestore(&clocks->lock, flags);827 828 /* Hardware manual recommends 5us delay after enabling clock & reset */829 udelay(5);830 831 /* If the peripheral is memory mapped (i.e. an AXI slave), there is an832 * associated SLVRDY bit in the System Controller that needs to be set833 * so that the FlexWAY bus fabric passes on the read/write requests.834 */835 spin_lock_irqsave(&clocks->lock, flags);836 clk_rdesc_set(clocks, g->ready, on);837 /* Clear 'Master Idle Request' bit */838 clk_rdesc_set(clocks, g->midle, !on);839 spin_unlock_irqrestore(&clocks->lock, flags);840 841 /* Note: We don't wait for FlexWAY Socket Connection signal */842}843 844static int r9a06g032_clk_gate_enable(struct clk_hw *hw)845{846 struct r9a06g032_clk_gate *g = to_r9a06g032_gate(hw);847 848 r9a06g032_clk_gate_set(g->clocks, &g->gate, 1);849 return 0;850}851 852static void r9a06g032_clk_gate_disable(struct clk_hw *hw)853{854 struct r9a06g032_clk_gate *g = to_r9a06g032_gate(hw);855 856 r9a06g032_clk_gate_set(g->clocks, &g->gate, 0);857}858 859static int r9a06g032_clk_gate_is_enabled(struct clk_hw *hw)860{861 struct r9a06g032_clk_gate *g = to_r9a06g032_gate(hw);862 863 /* if clock is in reset, the gate might be on, and still not 'be' on */864 if (g->gate.reset.reg && !clk_rdesc_get(g->clocks, g->gate.reset))865 return 0;866 867 return clk_rdesc_get(g->clocks, g->gate.gate);868}869 870static const struct clk_ops r9a06g032_clk_gate_ops = {871 .enable = r9a06g032_clk_gate_enable,872 .disable = r9a06g032_clk_gate_disable,873 .is_enabled = r9a06g032_clk_gate_is_enabled,874};875 876static struct clk *877r9a06g032_register_gate(struct r9a06g032_priv *clocks,878 const char *parent_name,879 const struct r9a06g032_clkdesc *desc)880{881 struct clk *clk;882 struct r9a06g032_clk_gate *g;883 struct clk_init_data init = {};884 885 g = kzalloc(sizeof(*g), GFP_KERNEL);886 if (!g)887 return NULL;888 889 init.name = desc->name;890 init.ops = &r9a06g032_clk_gate_ops;891 init.flags = CLK_SET_RATE_PARENT;892 init.parent_names = parent_name ? &parent_name : NULL;893 init.num_parents = parent_name ? 1 : 0;894 895 g->clocks = clocks;896 g->index = desc->index;897 g->gate = desc->gate;898 g->hw.init = &init;899 900 /*901 * important here, some clocks are already in use by the CM3, we902 * have to assume they are not Linux's to play with and try to disable903 * at the end of the boot!904 */905 if (r9a06g032_clk_gate_is_enabled(&g->hw)) {906 init.flags |= CLK_IS_CRITICAL;907 pr_debug("%s was enabled, making read-only\n", desc->name);908 }909 910 clk = clk_register(NULL, &g->hw);911 if (IS_ERR(clk)) {912 kfree(g);913 return NULL;914 }915 return clk;916}917 918struct r9a06g032_clk_div {919 struct clk_hw hw;920 struct r9a06g032_priv *clocks;921 u16 index;922 u16 reg;923 u16 min, max;924 u8 table_size;925 u16 table[8]; /* we know there are no more than 8 */926};927 928#define to_r9a06g032_div(_hw) \929 container_of(_hw, struct r9a06g032_clk_div, hw)930 931static unsigned long932r9a06g032_div_recalc_rate(struct clk_hw *hw,933 unsigned long parent_rate)934{935 struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw);936 u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg);937 u32 div = readl(reg);938 939 if (div < clk->min)940 div = clk->min;941 else if (div > clk->max)942 div = clk->max;943 return DIV_ROUND_UP(parent_rate, div);944}945 946/*947 * Attempts to find a value that is in range of min,max,948 * and if a table of set dividers was specified for this949 * register, try to find the fixed divider that is the closest950 * to the target frequency951 */952static long953r9a06g032_div_clamp_div(struct r9a06g032_clk_div *clk,954 unsigned long rate, unsigned long prate)955{956 /* + 1 to cope with rates that have the remainder dropped */957 u32 div = DIV_ROUND_UP(prate, rate + 1);958 int i;959 960 if (div <= clk->min)961 return clk->min;962 if (div >= clk->max)963 return clk->max;964 965 for (i = 0; clk->table_size && i < clk->table_size - 1; i++) {966 if (div >= clk->table[i] && div <= clk->table[i + 1]) {967 unsigned long m = rate -968 DIV_ROUND_UP(prate, clk->table[i]);969 unsigned long p =970 DIV_ROUND_UP(prate, clk->table[i + 1]) -971 rate;972 /*973 * select the divider that generates974 * the value closest to the ideal frequency975 */976 div = p >= m ? clk->table[i] : clk->table[i + 1];977 return div;978 }979 }980 return div;981}982 983static int984r9a06g032_div_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)985{986 struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw);987 u32 div = DIV_ROUND_UP(req->best_parent_rate, req->rate);988 989 pr_devel("%s %pC %ld (prate %ld) (wanted div %u)\n", __func__,990 hw->clk, req->rate, req->best_parent_rate, div);991 pr_devel(" min %d (%ld) max %d (%ld)\n",992 clk->min, DIV_ROUND_UP(req->best_parent_rate, clk->min),993 clk->max, DIV_ROUND_UP(req->best_parent_rate, clk->max));994 995 div = r9a06g032_div_clamp_div(clk, req->rate, req->best_parent_rate);996 /*997 * this is a hack. Currently the serial driver asks for a clock rate998 * that is 16 times the baud rate -- and that is wildly outside the999 * range of the UART divider, somehow there is no provision for that1000 * case of 'let the divider as is if outside range'.1001 * The serial driver *shouldn't* play with these clocks anyway, there's1002 * several uarts attached to this divider, and changing this impacts1003 * everyone.1004 */1005 if (clk->index == R9A06G032_DIV_UART ||1006 clk->index == R9A06G032_DIV_P2_PG) {1007 pr_devel("%s div uart hack!\n", __func__);1008 req->rate = clk_get_rate(hw->clk);1009 return 0;1010 }1011 req->rate = DIV_ROUND_UP(req->best_parent_rate, div);1012 pr_devel("%s %pC %ld / %u = %ld\n", __func__, hw->clk,1013 req->best_parent_rate, div, req->rate);1014 return 0;1015}1016 1017static int1018r9a06g032_div_set_rate(struct clk_hw *hw,1019 unsigned long rate, unsigned long parent_rate)1020{1021 struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw);1022 /* + 1 to cope with rates that have the remainder dropped */1023 u32 div = DIV_ROUND_UP(parent_rate, rate + 1);1024 u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg);1025 1026 pr_devel("%s %pC rate %ld parent %ld div %d\n", __func__, hw->clk,1027 rate, parent_rate, div);1028 1029 /*1030 * Need to write the bit 31 with the divider value to1031 * latch it. Technically we should wait until it has been1032 * cleared too.1033 * TODO: Find whether this callback is sleepable, in case1034 * the hardware /does/ require some sort of spinloop here.1035 */1036 writel(div | BIT(31), reg);1037 1038 return 0;1039}1040 1041static const struct clk_ops r9a06g032_clk_div_ops = {1042 .recalc_rate = r9a06g032_div_recalc_rate,1043 .determine_rate = r9a06g032_div_determine_rate,1044 .set_rate = r9a06g032_div_set_rate,1045};1046 1047static struct clk *1048r9a06g032_register_div(struct r9a06g032_priv *clocks,1049 const char *parent_name,1050 const struct r9a06g032_clkdesc *desc)1051{1052 struct r9a06g032_clk_div *div;1053 struct clk *clk;1054 struct clk_init_data init = {};1055 unsigned int i;1056 1057 div = kzalloc(sizeof(*div), GFP_KERNEL);1058 if (!div)1059 return NULL;1060 1061 init.name = desc->name;1062 init.ops = &r9a06g032_clk_div_ops;1063 init.flags = CLK_SET_RATE_PARENT;1064 init.parent_names = parent_name ? &parent_name : NULL;1065 init.num_parents = parent_name ? 1 : 0;1066 1067 div->clocks = clocks;1068 div->index = desc->index;1069 div->reg = desc->div.reg;1070 div->hw.init = &init;1071 div->min = desc->div.min;1072 div->max = desc->div.max;1073 /* populate (optional) divider table fixed values */1074 for (i = 0; i < ARRAY_SIZE(div->table) &&1075 i < ARRAY_SIZE(desc->div.table) && desc->div.table[i]; i++) {1076 div->table[div->table_size++] = desc->div.table[i];1077 }1078 1079 clk = clk_register(NULL, &div->hw);1080 if (IS_ERR(clk)) {1081 kfree(div);1082 return NULL;1083 }1084 return clk;1085}1086 1087/*1088 * This clock provider handles the case of the R9A06G032 where you have1089 * peripherals that have two potential clock source and two gates, one for1090 * each of the clock source - the used clock source (for all sub clocks)1091 * is selected by a single bit.1092 * That single bit affects all sub-clocks, and therefore needs to change the1093 * active gate (and turn the others off) and force a recalculation of the rates.1094 *1095 * This implements two clock providers, one 'bitselect' that1096 * handles the switch between both parents, and another 'dualgate'1097 * that knows which gate to poke at, depending on the parent's bit position.1098 */1099struct r9a06g032_clk_bitsel {1100 struct clk_hw hw;1101 struct r9a06g032_priv *clocks;1102 u16 index;1103 struct regbit selector; /* selector register + bit */1104};1105 1106#define to_clk_bitselect(_hw) \1107 container_of(_hw, struct r9a06g032_clk_bitsel, hw)1108 1109static u8 r9a06g032_clk_mux_get_parent(struct clk_hw *hw)1110{1111 struct r9a06g032_clk_bitsel *set = to_clk_bitselect(hw);1112 1113 return clk_rdesc_get(set->clocks, set->selector);1114}1115 1116static int r9a06g032_clk_mux_set_parent(struct clk_hw *hw, u8 index)1117{1118 struct r9a06g032_clk_bitsel *set = to_clk_bitselect(hw);1119 1120 /* a single bit in the register selects one of two parent clocks */1121 clk_rdesc_set(set->clocks, set->selector, !!index);1122 1123 return 0;1124}1125 1126static const struct clk_ops clk_bitselect_ops = {1127 .determine_rate = clk_hw_determine_rate_no_reparent,1128 .get_parent = r9a06g032_clk_mux_get_parent,1129 .set_parent = r9a06g032_clk_mux_set_parent,1130};1131 1132static struct clk *1133r9a06g032_register_bitsel(struct r9a06g032_priv *clocks,1134 const char *parent_name,1135 const struct r9a06g032_clkdesc *desc)1136{1137 struct clk *clk;1138 struct r9a06g032_clk_bitsel *g;1139 struct clk_init_data init = {};1140 const char *names[2];1141 1142 /* allocate the gate */1143 g = kzalloc(sizeof(*g), GFP_KERNEL);1144 if (!g)1145 return NULL;1146 1147 names[0] = parent_name;1148 names[1] = "clk_pll_usb";1149 1150 init.name = desc->name;1151 init.ops = &clk_bitselect_ops;1152 init.flags = CLK_SET_RATE_PARENT;1153 init.parent_names = names;1154 init.num_parents = 2;1155 1156 g->clocks = clocks;1157 g->index = desc->index;1158 g->selector = desc->dual.sel;1159 g->hw.init = &init;1160 1161 clk = clk_register(NULL, &g->hw);1162 if (IS_ERR(clk)) {1163 kfree(g);1164 return NULL;1165 }1166 return clk;1167}1168 1169struct r9a06g032_clk_dualgate {1170 struct clk_hw hw;1171 struct r9a06g032_priv *clocks;1172 u16 index;1173 struct regbit selector; /* selector register + bit */1174 struct r9a06g032_gate gate[2];1175};1176 1177#define to_clk_dualgate(_hw) \1178 container_of(_hw, struct r9a06g032_clk_dualgate, hw)1179 1180static int1181r9a06g032_clk_dualgate_setenable(struct r9a06g032_clk_dualgate *g, int enable)1182{1183 u8 sel_bit = clk_rdesc_get(g->clocks, g->selector);1184 1185 /* we always turn off the 'other' gate, regardless */1186 r9a06g032_clk_gate_set(g->clocks, &g->gate[!sel_bit], 0);1187 r9a06g032_clk_gate_set(g->clocks, &g->gate[sel_bit], enable);1188 1189 return 0;1190}1191 1192static int r9a06g032_clk_dualgate_enable(struct clk_hw *hw)1193{1194 struct r9a06g032_clk_dualgate *gate = to_clk_dualgate(hw);1195 1196 r9a06g032_clk_dualgate_setenable(gate, 1);1197 1198 return 0;1199}1200 1201static void r9a06g032_clk_dualgate_disable(struct clk_hw *hw)1202{1203 struct r9a06g032_clk_dualgate *gate = to_clk_dualgate(hw);1204 1205 r9a06g032_clk_dualgate_setenable(gate, 0);1206}1207 1208static int r9a06g032_clk_dualgate_is_enabled(struct clk_hw *hw)1209{1210 struct r9a06g032_clk_dualgate *g = to_clk_dualgate(hw);1211 u8 sel_bit = clk_rdesc_get(g->clocks, g->selector);1212 1213 return clk_rdesc_get(g->clocks, g->gate[sel_bit].gate);1214}1215 1216static const struct clk_ops r9a06g032_clk_dualgate_ops = {1217 .enable = r9a06g032_clk_dualgate_enable,1218 .disable = r9a06g032_clk_dualgate_disable,1219 .is_enabled = r9a06g032_clk_dualgate_is_enabled,1220};1221 1222static struct clk *1223r9a06g032_register_dualgate(struct r9a06g032_priv *clocks,1224 const char *parent_name,1225 const struct r9a06g032_clkdesc *desc,1226 struct regbit sel)1227{1228 struct r9a06g032_clk_dualgate *g;1229 struct clk *clk;1230 struct clk_init_data init = {};1231 1232 /* allocate the gate */1233 g = kzalloc(sizeof(*g), GFP_KERNEL);1234 if (!g)1235 return NULL;1236 g->clocks = clocks;1237 g->index = desc->index;1238 g->selector = sel;1239 g->gate[0].gate = desc->dual.g1;1240 g->gate[0].reset = desc->dual.r1;1241 g->gate[1].gate = desc->dual.g2;1242 g->gate[1].reset = desc->dual.r2;1243 1244 init.name = desc->name;1245 init.ops = &r9a06g032_clk_dualgate_ops;1246 init.flags = CLK_SET_RATE_PARENT;1247 init.parent_names = &parent_name;1248 init.num_parents = 1;1249 g->hw.init = &init;1250 /*1251 * important here, some clocks are already in use by the CM3, we1252 * have to assume they are not Linux's to play with and try to disable1253 * at the end of the boot!1254 */1255 if (r9a06g032_clk_dualgate_is_enabled(&g->hw)) {1256 init.flags |= CLK_IS_CRITICAL;1257 pr_debug("%s was enabled, making read-only\n", desc->name);1258 }1259 1260 clk = clk_register(NULL, &g->hw);1261 if (IS_ERR(clk)) {1262 kfree(g);1263 return NULL;1264 }1265 return clk;1266}1267 1268static void r9a06g032_clocks_del_clk_provider(void *data)1269{1270 of_clk_del_provider(data);1271}1272 1273static void __init r9a06g032_init_h2mode(struct r9a06g032_priv *clocks)1274{1275 struct device_node *usbf_np;1276 u32 usb;1277 1278 for_each_compatible_node(usbf_np, NULL, "renesas,rzn1-usbf") {1279 if (of_device_is_available(usbf_np))1280 break;1281 }1282 1283 usb = readl(clocks->reg + R9A06G032_SYSCTRL_USB);1284 if (usbf_np) {1285 /* 1 host and 1 device mode */1286 usb &= ~R9A06G032_SYSCTRL_USB_H2MODE;1287 of_node_put(usbf_np);1288 } else {1289 /* 2 hosts mode */1290 usb |= R9A06G032_SYSCTRL_USB_H2MODE;1291 }1292 writel(usb, clocks->reg + R9A06G032_SYSCTRL_USB);1293}1294 1295static int __init r9a06g032_clocks_probe(struct platform_device *pdev)1296{1297 struct device *dev = &pdev->dev;1298 struct device_node *np = dev->of_node;1299 struct r9a06g032_priv *clocks;1300 struct clk **clks;1301 struct clk *mclk;1302 unsigned int i;1303 struct regbit uart_group_sel[2];1304 int error;1305 1306 clocks = devm_kzalloc(dev, sizeof(*clocks), GFP_KERNEL);1307 clks = devm_kcalloc(dev, R9A06G032_CLOCK_COUNT, sizeof(struct clk *),1308 GFP_KERNEL);1309 if (!clocks || !clks)1310 return -ENOMEM;1311 1312 spin_lock_init(&clocks->lock);1313 1314 clocks->data.clks = clks;1315 clocks->data.clk_num = R9A06G032_CLOCK_COUNT;1316 1317 mclk = devm_clk_get(dev, "mclk");1318 if (IS_ERR(mclk))1319 return PTR_ERR(mclk);1320 1321 clocks->reg = of_iomap(np, 0);1322 if (WARN_ON(!clocks->reg))1323 return -ENOMEM;1324 1325 r9a06g032_init_h2mode(clocks);1326 1327 for (i = 0; i < ARRAY_SIZE(r9a06g032_clocks); ++i) {1328 const struct r9a06g032_clkdesc *d = &r9a06g032_clocks[i];1329 const char *parent_name = d->source ?1330 __clk_get_name(clocks->data.clks[d->source - 1]) :1331 __clk_get_name(mclk);1332 struct clk *clk = NULL;1333 1334 switch (d->type) {1335 case K_FFC:1336 clk = clk_register_fixed_factor(NULL, d->name,1337 parent_name, 0,1338 d->ffc.mul,1339 d->ffc.div);1340 break;1341 case K_GATE:1342 clk = r9a06g032_register_gate(clocks, parent_name, d);1343 break;1344 case K_DIV:1345 clk = r9a06g032_register_div(clocks, parent_name, d);1346 break;1347 case K_BITSEL:1348 /* keep that selector register around */1349 uart_group_sel[d->dual.group] = d->dual.sel;1350 clk = r9a06g032_register_bitsel(clocks, parent_name, d);1351 break;1352 case K_DUALGATE:1353 clk = r9a06g032_register_dualgate(clocks, parent_name,1354 d,1355 uart_group_sel[d->dual.group]);1356 break;1357 }1358 clocks->data.clks[d->index] = clk;1359 }1360 error = of_clk_add_provider(np, of_clk_src_onecell_get, &clocks->data);1361 if (error)1362 return error;1363 1364 error = devm_add_action_or_reset(dev,1365 r9a06g032_clocks_del_clk_provider, np);1366 if (error)1367 return error;1368 1369 error = r9a06g032_add_clk_domain(dev);1370 if (error)1371 return error;1372 1373 sysctrl_priv = clocks;1374 1375 error = of_platform_populate(np, NULL, NULL, dev);1376 if (error)1377 dev_err(dev, "Failed to populate children (%d)\n", error);1378 1379 return 0;1380}1381 1382static const struct of_device_id r9a06g032_match[] = {1383 { .compatible = "renesas,r9a06g032-sysctrl" },1384 { }1385};1386 1387static struct platform_driver r9a06g032_clock_driver = {1388 .driver = {1389 .name = "renesas,r9a06g032-sysctrl",1390 .of_match_table = r9a06g032_match,1391 },1392};1393 1394static int __init r9a06g032_clocks_init(void)1395{1396 return platform_driver_probe(&r9a06g032_clock_driver,1397 r9a06g032_clocks_probe);1398}1399 1400subsys_initcall(r9a06g032_clocks_init);1401