1 /* $OpenBSD: imxanatop.c,v 1.6 2021/10/24 17:52:26 mpi Exp $ */ 2 /* 3 * Copyright (c) 2016 Mark Kettenis <kettenis@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/systm.h> 20 #include <sys/device.h> 21 #include <sys/malloc.h> 22 23 #include <machine/bus.h> 24 #include <machine/fdt.h> 25 26 #include <dev/ofw/openfirm.h> 27 #include <dev/ofw/ofw_misc.h> 28 #include <dev/ofw/ofw_regulator.h> 29 #include <dev/ofw/fdt.h> 30 31 #include <dev/fdt/imxanatopvar.h> 32 33 #define ANALOG_PLL_ARM 0x0000 34 #define ANALOG_PLL_ARM_SET 0x0004 35 #define ANALOG_PLL_ARM_CLR 0x0008 36 #define ANALOG_PLL_ARM_DIV_SELECT_MASK 0x7f 37 #define ANALOG_PLL_ARM_BYPASS (1 << 16) 38 #define ANALOG_PLL_USB1 0x0010 39 #define ANALOG_PLL_USB1_SET 0x0014 40 #define ANALOG_PLL_USB1_CLR 0x0018 41 #define ANALOG_PLL_USB1_DIV_SELECT_MASK 0x1 42 #define ANALOG_PLL_USB1_EN_USB_CLKS (1 << 6) 43 #define ANALOG_PLL_USB1_POWER (1 << 12) 44 #define ANALOG_PLL_USB1_ENABLE (1 << 13) 45 #define ANALOG_PLL_USB1_BYPASS (1 << 16) 46 #define ANALOG_PLL_USB1_LOCK (1U << 31) 47 #define ANALOG_PLL_USB2 0x0020 48 #define ANALOG_PLL_USB2_SET 0x0024 49 #define ANALOG_PLL_USB2_CLR 0x0028 50 #define ANALOG_PLL_USB2_DIV_SELECT_MASK 0x1 51 #define ANALOG_PLL_USB2_EN_USB_CLKS (1 << 6) 52 #define ANALOG_PLL_USB2_POWER (1 << 12) 53 #define ANALOG_PLL_USB2_ENABLE (1 << 13) 54 #define ANALOG_PLL_USB2_BYPASS (1 << 16) 55 #define ANALOG_PLL_USB2_LOCK (1U << 31) 56 #define ANALOG_PLL_SYS 0x0030 57 #define ANALOG_PLL_SYS_DIV_SELECT_MASK 0x1 58 #define ANALOG_PLL_ENET 0x00e0 59 #define ANALOG_PLL_ENET_SET 0x00e4 60 #define ANALOG_PLL_ENET_CLR 0x00e8 61 #define ANALOG_PLL_ENET_DIV_125M (1 << 11) 62 #define ANALOG_PLL_ENET_POWERDOWN (1 << 12) 63 #define ANALOG_PLL_ENET_ENABLE (1 << 13) 64 #define ANALOG_PLL_ENET_BYPASS (1 << 16) 65 #define ANALOG_PLL_ENET_125M_PCIE (1 << 19) 66 #define ANALOG_PLL_ENET_100M_SATA (1 << 20) 67 #define ANALOG_PLL_ENET_LOCK (1U << 31) 68 #define ANALOG_PFD_480 0x00f0 69 #define ANALOG_PFD_480_SET 0x00f4 70 #define ANALOG_PFD_480_CLR 0x00f8 71 #define ANALOG_PFD_480_PFDx_FRAC(x, y) (((x) >> ((y) << 3)) & 0x3f) 72 #define ANALOG_PFD_528 0x0100 73 #define ANALOG_PFD_528_SET 0x0104 74 #define ANALOG_PFD_528_CLR 0x0108 75 #define ANALOG_PFD_528_PFDx_FRAC(x, y) (((x) >> ((y) << 3)) & 0x3f) 76 #define ANALOG_USB1_CHRG_DETECT 0x01b0 77 #define ANALOG_USB1_CHRG_DETECT_SET 0x01b4 78 #define ANALOG_USB1_CHRG_DETECT_CLR 0x01b8 79 #define ANALOG_USB1_CHRG_DETECT_CHK_CHRG_B (1 << 19) 80 #define ANALOG_USB1_CHRG_DETECT_EN_B (1 << 20) 81 #define ANALOG_USB2_CHRG_DETECT 0x0210 82 #define ANALOG_USB2_CHRG_DETECT_SET 0x0214 83 #define ANALOG_USB2_CHRG_DETECT_CLR 0x0218 84 #define ANALOG_USB2_CHRG_DETECT_CHK_CHRG_B (1 << 19) 85 #define ANALOG_USB2_CHRG_DETECT_EN_B (1 << 20) 86 #define ANALOG_DIGPROG 0x0260 87 #define ANALOG_DIGPROG_MINOR_MASK 0xff 88 89 #define HCLK_FREQ 24000000 90 91 #define HREAD4(sc, reg) \ 92 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) 93 #define HWRITE4(sc, reg, val) \ 94 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 95 #define HSET4(sc, reg, bits) \ 96 HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits)) 97 #define HCLR4(sc, reg, bits) \ 98 HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits)) 99 100 struct imxanatop_softc { 101 struct device sc_dev; 102 bus_space_tag_t sc_iot; 103 bus_space_handle_t sc_ioh; 104 }; 105 106 struct imxanatop_softc *imxanatop_sc; 107 108 struct imxanatop_regulator { 109 struct imxanatop_softc *ir_sc; 110 111 uint32_t ir_reg_offset; 112 uint32_t ir_vol_bit_shift; 113 uint32_t ir_vol_bit_width; 114 uint32_t ir_min_bit_val; 115 uint32_t ir_min_voltage; 116 uint32_t ir_max_voltage; 117 118 uint32_t ir_delay_reg_offset; 119 uint32_t ir_delay_bit_shift; 120 uint32_t ir_delay_bit_width; 121 122 struct regulator_device ir_rd; 123 }; 124 125 int imxanatop_match(struct device *, void *, void *); 126 void imxanatop_attach(struct device *, struct device *, void *); 127 128 const struct cfattach imxanatop_ca = { 129 sizeof(struct imxanatop_softc), imxanatop_match, imxanatop_attach 130 }; 131 132 struct cfdriver imxanatop_cd = { 133 NULL, "imxanatop", DV_DULL 134 }; 135 136 void imxanatop_attach_regulator(struct imxanatop_softc *, int); 137 uint32_t imxanatop_get_voltage(void *); 138 int imxanatop_set_voltage(void *, uint32_t); 139 140 int 141 imxanatop_match(struct device *parent, void *match, void *aux) 142 { 143 struct fdt_attach_args *faa = aux; 144 145 if (OF_is_compatible(faa->fa_node, "fsl,imx6q-anatop")) 146 return 10; /* Must beat simplebus(4) and syscon(4). */ 147 148 return 0; 149 } 150 151 void 152 imxanatop_attach(struct device *parent, struct device *self, void *aux) 153 { 154 struct imxanatop_softc *sc = (struct imxanatop_softc *)self; 155 struct fdt_attach_args *faa = aux; 156 int node; 157 158 if (faa->fa_nreg < 1) { 159 printf(": no registers\n"); 160 return; 161 } 162 163 sc->sc_iot = faa->fa_iot; 164 165 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 166 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 167 printf(": can't map registers\n"); 168 return; 169 } 170 171 regmap_register(faa->fa_node, sc->sc_iot, sc->sc_ioh, 172 faa->fa_reg[0].size); 173 174 printf("\n"); 175 176 for (node = OF_child(faa->fa_node); node; node = OF_peer(node)) 177 if (OF_is_compatible(node, "fsl,anatop-regulator")) 178 imxanatop_attach_regulator(sc, node); 179 180 imxanatop_sc = sc; 181 } 182 183 void 184 imxanatop_attach_regulator(struct imxanatop_softc *sc, int node) 185 { 186 struct imxanatop_regulator *ir; 187 188 ir = malloc(sizeof(*ir), M_DEVBUF, M_WAITOK | M_ZERO); 189 ir->ir_sc = sc; 190 191 ir->ir_reg_offset = OF_getpropint(node, "anatop-reg-offset", -1); 192 ir->ir_vol_bit_shift = OF_getpropint(node, "anatop-vol-bit-shift", -1); 193 ir->ir_vol_bit_width = OF_getpropint(node, "anatop-vol-bit-width", -1); 194 ir->ir_min_bit_val = OF_getpropint(node, "anatop-min-bit-val", -1); 195 ir->ir_min_voltage = OF_getpropint(node, "anatop-min-voltage", -1); 196 ir->ir_max_voltage = OF_getpropint(node, "anatop-max-voltage", -1); 197 if (ir->ir_reg_offset == -1 || ir->ir_vol_bit_shift == -1 || 198 ir->ir_vol_bit_width == -1 || ir->ir_min_bit_val == -1 || 199 ir->ir_min_voltage == -1 || ir->ir_max_voltage == -1) { 200 free(ir, M_DEVBUF, sizeof(*ir)); 201 return; 202 } 203 204 ir->ir_delay_reg_offset = 205 OF_getpropint(node, "anatop-delay-reg-offset", 0); 206 ir->ir_delay_bit_shift = 207 OF_getpropint(node, "anatop-delay-bit-shift", 0); 208 ir->ir_delay_bit_width = 209 OF_getpropint(node, "anatop-delay-bit-width", 0); 210 211 ir->ir_rd.rd_node = node; 212 ir->ir_rd.rd_cookie = ir; 213 ir->ir_rd.rd_get_voltage = imxanatop_get_voltage; 214 ir->ir_rd.rd_set_voltage = imxanatop_set_voltage; 215 regulator_register(&ir->ir_rd); 216 } 217 218 uint32_t 219 imxanatop_get_voltage(void *cookie) 220 { 221 struct imxanatop_regulator *ir = cookie; 222 uint32_t bit_val; 223 224 bit_val = HREAD4(ir->ir_sc, ir->ir_reg_offset) >> ir->ir_vol_bit_shift; 225 bit_val &= ((1 << ir->ir_vol_bit_width) - 1); 226 return (ir->ir_min_voltage + (bit_val - ir->ir_min_bit_val) * 25000); 227 } 228 229 int 230 imxanatop_set_voltage(void *cookie, uint32_t voltage) 231 { 232 struct imxanatop_regulator *ir = cookie; 233 uint32_t bit_val, old_bit_val, reg; 234 int steps, usecs; 235 236 if (voltage < ir->ir_min_voltage || voltage > ir->ir_max_voltage) 237 return -1; 238 239 bit_val = ir->ir_min_bit_val + (voltage - ir->ir_min_voltage) / 25000; 240 reg = HREAD4(ir->ir_sc, ir->ir_reg_offset); 241 old_bit_val = (reg >> ir->ir_vol_bit_shift); 242 old_bit_val &= ((1 << ir->ir_vol_bit_width) -1); 243 reg &= ~((1 << ir->ir_vol_bit_width) - 1) << ir->ir_vol_bit_shift; 244 reg |= (bit_val << ir->ir_vol_bit_shift); 245 HWRITE4(ir->ir_sc, ir->ir_reg_offset, reg); 246 247 steps = bit_val - old_bit_val; 248 if (steps > 0 && ir->ir_delay_bit_width > 0) { 249 reg = HREAD4(ir->ir_sc, ir->ir_delay_reg_offset); 250 reg >>= ir->ir_delay_bit_shift; 251 reg &= ((1 << ir->ir_delay_bit_width) - 1); 252 usecs = ((reg + 1) * steps * 64 * 1000000) / 24000000; 253 delay(usecs); 254 } 255 256 return 0; 257 } 258 259 uint32_t 260 imxanatop_decode_pll(enum imxanatop_clocks pll, uint32_t freq) 261 { 262 struct imxanatop_softc *sc = imxanatop_sc; 263 uint32_t div; 264 265 KASSERT(sc != NULL); 266 267 switch (pll) { 268 case ARM_PLL1: 269 if (HREAD4(sc, ANALOG_PLL_ARM) 270 & ANALOG_PLL_ARM_BYPASS) 271 return freq; 272 div = HREAD4(sc, ANALOG_PLL_ARM) 273 & ANALOG_PLL_ARM_DIV_SELECT_MASK; 274 return (freq * div) / 2; 275 case SYS_PLL2: 276 div = HREAD4(sc, ANALOG_PLL_SYS) 277 & ANALOG_PLL_SYS_DIV_SELECT_MASK; 278 return freq * (20 + (div << 1)); 279 case USB1_PLL3: 280 div = HREAD4(sc, ANALOG_PLL_USB2) 281 & ANALOG_PLL_USB2_DIV_SELECT_MASK; 282 return freq * (20 + (div << 1)); 283 default: 284 return 0; 285 } 286 } 287 288 uint32_t 289 imxanatop_get_pll2_pfd(unsigned int pfd) 290 { 291 struct imxanatop_softc *sc = imxanatop_sc; 292 KASSERT(sc != NULL); 293 294 return imxanatop_decode_pll(SYS_PLL2, HCLK_FREQ) * 18ULL 295 / ANALOG_PFD_528_PFDx_FRAC(HREAD4(sc, ANALOG_PFD_528), pfd); 296 } 297 298 uint32_t 299 imxanatop_get_pll3_pfd(unsigned int pfd) 300 { 301 struct imxanatop_softc *sc = imxanatop_sc; 302 KASSERT(sc != NULL); 303 304 return imxanatop_decode_pll(USB1_PLL3, HCLK_FREQ) * 18ULL 305 / ANALOG_PFD_480_PFDx_FRAC(HREAD4(sc, ANALOG_PFD_480), pfd); 306 } 307