1 /*- 2 * Copyright (c) 2015 Luiz Otavio O Souza <loos@freebsd.org> All rights reserved. 3 * Copyright (c) 2014-2015 M. Warner Losh <imp@FreeBSD.org> 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * The magic-bit-bang sequence used in this code may be based on a linux 27 * platform driver in the Allwinner SDK from Allwinner Technology Co., Ltd. 28 * www.allwinnertech.com, by Daniel Wang <danielwang@allwinnertech.com> 29 * though none of the original code was copied. 30 */ 31 32 #include "opt_bus.h" 33 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/bus.h> 40 #include <sys/rman.h> 41 #include <sys/kernel.h> 42 #include <sys/module.h> 43 44 #include <machine/bus.h> 45 #include <dev/ofw/ofw_bus.h> 46 #include <dev/ofw/ofw_bus_subr.h> 47 48 #include <dev/ahci/ahci.h> 49 #include <dev/extres/clk/clk.h> 50 51 /* 52 * Allwinner a1x/a2x/a8x SATA attachment. This is just the AHCI register 53 * set with a few extra implementation-specific registers that need to 54 * be accounted for. There's only one PHY in the system, and it needs 55 * to be trained to bring the link up. In addition, there's some DMA 56 * specific things that need to be done as well. These things are also 57 * just about completely undocumented, except in ugly code in the Linux 58 * SDK Allwinner releases. 59 */ 60 61 /* BITx -- Unknown bit that needs to be set/cleared at position x */ 62 /* UFx -- Uknown multi-bit field frobbed during init */ 63 #define AHCI_BISTAFR 0x00A0 64 #define AHCI_BISTCR 0x00A4 65 #define AHCI_BISTFCTR 0x00A8 66 #define AHCI_BISTSR 0x00AC 67 #define AHCI_BISTDECR 0x00B0 68 #define AHCI_DIAGNR 0x00B4 69 #define AHCI_DIAGNR1 0x00B8 70 #define AHCI_OOBR 0x00BC 71 #define AHCI_PHYCS0R 0x00C0 72 /* Bits 0..17 are a mystery */ 73 #define PHYCS0R_BIT18 (1 << 18) 74 #define PHYCS0R_POWER_ENABLE (1 << 19) 75 #define PHYCS0R_UF1_MASK (7 << 20) /* Unknown Field 1 */ 76 #define PHYCS0R_UF1_INIT (3 << 20) 77 #define PHYCS0R_BIT23 (1 << 23) 78 #define PHYCS0R_UF2_MASK (7 << 24) /* Uknown Field 2 */ 79 #define PHYCS0R_UF2_INIT (5 << 24) 80 /* Bit 27 mystery */ 81 #define PHYCS0R_POWER_STATUS_MASK (7 << 28) 82 #define PHYCS0R_PS_GOOD (2 << 28) 83 /* Bit 31 mystery */ 84 #define AHCI_PHYCS1R 0x00C4 85 /* Bits 0..5 are a mystery */ 86 #define PHYCS1R_UF1_MASK (3 << 6) 87 #define PHYCS1R_UF1_INIT (2 << 6) 88 #define PHYCS1R_UF2_MASK (0x1f << 8) 89 #define PHYCS1R_UF2_INIT (6 << 8) 90 /* Bits 13..14 are a mystery */ 91 #define PHYCS1R_BIT15 (1 << 15) 92 #define PHYCS1R_UF3_MASK (3 << 16) 93 #define PHYCS1R_UF3_INIT (2 << 16) 94 /* Bit 18 mystery */ 95 #define PHYCS1R_HIGHZ (1 << 19) 96 /* Bits 20..27 mystery */ 97 #define PHYCS1R_BIT28 (1 << 28) 98 /* Bits 29..31 mystery */ 99 #define AHCI_PHYCS2R 0x00C8 100 /* bits 0..4 mystery */ 101 #define PHYCS2R_UF1_MASK (0x1f << 5) 102 #define PHYCS2R_UF1_INIT (0x19 << 5) 103 /* Bits 10..23 mystery */ 104 #define PHYCS2R_CALIBRATE (1 << 24) 105 /* Bits 25..31 mystery */ 106 #define AHCI_TIMER1MS 0x00E0 107 #define AHCI_GPARAM1R 0x00E8 108 #define AHCI_GPARAM2R 0x00EC 109 #define AHCI_PPARAMR 0x00F0 110 #define AHCI_TESTR 0x00F4 111 #define AHCI_VERSIONR 0x00F8 112 #define AHCI_IDR 0x00FC 113 #define AHCI_RWCR 0x00FC 114 115 #define AHCI_P0DMACR 0x0070 116 #define AHCI_P0PHYCR 0x0078 117 #define AHCI_P0PHYSR 0x007C 118 119 #define PLL_FREQ 100000000 120 121 static void inline 122 ahci_set(struct resource *m, bus_size_t off, uint32_t set) 123 { 124 uint32_t val = ATA_INL(m, off); 125 126 val |= set; 127 ATA_OUTL(m, off, val); 128 } 129 130 static void inline 131 ahci_clr(struct resource *m, bus_size_t off, uint32_t clr) 132 { 133 uint32_t val = ATA_INL(m, off); 134 135 val &= ~clr; 136 ATA_OUTL(m, off, val); 137 } 138 139 static void inline 140 ahci_mask_set(struct resource *m, bus_size_t off, uint32_t mask, uint32_t set) 141 { 142 uint32_t val = ATA_INL(m, off); 143 144 val &= mask; 145 val |= set; 146 ATA_OUTL(m, off, val); 147 } 148 149 /* 150 * Should this be phy_reset or phy_init 151 */ 152 #define PHY_RESET_TIMEOUT 1000 153 static void 154 ahci_a10_phy_reset(device_t dev) 155 { 156 uint32_t to, val; 157 struct ahci_controller *ctlr = device_get_softc(dev); 158 159 /* 160 * Here starts the magic -- most of the comments are based 161 * on guesswork, names of routines and printf error 162 * messages. The code works, but it will do that even if the 163 * comments are 100% BS. 164 */ 165 166 /* 167 * Lock out other access while we initialize. Or at least that 168 * seems to be the case based on Linux SDK #defines. Maybe this 169 * put things into reset? 170 */ 171 ATA_OUTL(ctlr->r_mem, AHCI_RWCR, 0); 172 DELAY(100); 173 174 /* 175 * Set bit 19 in PHYCS1R. Guessing this disables driving the PHY 176 * port for a bit while we reset things. 177 */ 178 ahci_set(ctlr->r_mem, AHCI_PHYCS1R, PHYCS1R_HIGHZ); 179 180 /* 181 * Frob PHYCS0R... 182 */ 183 ahci_mask_set(ctlr->r_mem, AHCI_PHYCS0R, 184 ~PHYCS0R_UF2_MASK, 185 PHYCS0R_UF2_INIT | PHYCS0R_BIT23 | PHYCS0R_BIT18); 186 187 /* 188 * Set three fields in PHYCS1R 189 */ 190 ahci_mask_set(ctlr->r_mem, AHCI_PHYCS1R, 191 ~(PHYCS1R_UF1_MASK | PHYCS1R_UF2_MASK | PHYCS1R_UF3_MASK), 192 PHYCS1R_UF1_INIT | PHYCS1R_UF2_INIT | PHYCS1R_UF3_INIT); 193 194 /* 195 * Two more mystery bits in PHYCS1R. -- can these be combined above? 196 */ 197 ahci_set(ctlr->r_mem, AHCI_PHYCS1R, PHYCS1R_BIT15 | PHYCS1R_BIT28); 198 199 /* 200 * Now clear that first mysery bit. Perhaps this starts 201 * driving the PHY again so we can power it up and start 202 * talking to the SATA drive, if any below. 203 */ 204 ahci_clr(ctlr->r_mem, AHCI_PHYCS1R, PHYCS1R_HIGHZ); 205 206 /* 207 * Frob PHYCS0R again... 208 */ 209 ahci_mask_set(ctlr->r_mem, AHCI_PHYCS0R, 210 ~PHYCS0R_UF1_MASK, PHYCS0R_UF1_INIT); 211 212 /* 213 * Frob PHYCS2R, because 25 means something? 214 */ 215 ahci_mask_set(ctlr->r_mem, AHCI_PHYCS2R, ~PHYCS2R_UF1_MASK, 216 PHYCS2R_UF1_INIT); 217 218 DELAY(100); /* WAG */ 219 220 /* 221 * Turn on the power to the PHY and wait for it to report back 222 * good? 223 */ 224 ahci_set(ctlr->r_mem, AHCI_PHYCS0R, PHYCS0R_POWER_ENABLE); 225 for (to = PHY_RESET_TIMEOUT; to > 0; to--) { 226 val = ATA_INL(ctlr->r_mem, AHCI_PHYCS0R); 227 if ((val & PHYCS0R_POWER_STATUS_MASK) == PHYCS0R_PS_GOOD) 228 break; 229 DELAY(10); 230 } 231 if (to == 0 && bootverbose) 232 device_printf(dev, "PHY Power Failed PHYCS0R = %#x\n", val); 233 234 /* 235 * Calibrate the clocks between the device and the host. This appears 236 * to be an automated process that clears the bit when it is done. 237 */ 238 ahci_set(ctlr->r_mem, AHCI_PHYCS2R, PHYCS2R_CALIBRATE); 239 for (to = PHY_RESET_TIMEOUT; to > 0; to--) { 240 val = ATA_INL(ctlr->r_mem, AHCI_PHYCS2R); 241 if ((val & PHYCS2R_CALIBRATE) == 0) 242 break; 243 DELAY(10); 244 } 245 if (to == 0 && bootverbose) 246 device_printf(dev, "PHY Cal Failed PHYCS2R %#x\n", val); 247 248 /* 249 * OK, let things settle down a bit. 250 */ 251 DELAY(1000); 252 253 /* 254 * Go back into normal mode now that we've calibrated the PHY. 255 */ 256 ATA_OUTL(ctlr->r_mem, AHCI_RWCR, 7); 257 } 258 259 static void 260 ahci_a10_ch_start(struct ahci_channel *ch) 261 { 262 uint32_t reg; 263 264 /* 265 * Magical values from Allwinner SDK, setup the DMA before start 266 * operations on this channel. 267 */ 268 reg = ATA_INL(ch->r_mem, AHCI_P0DMACR); 269 reg &= ~0xff00; 270 reg |= 0x4400; 271 ATA_OUTL(ch->r_mem, AHCI_P0DMACR, reg); 272 } 273 274 static int 275 ahci_a10_ctlr_reset(device_t dev) 276 { 277 278 ahci_a10_phy_reset(dev); 279 280 return (ahci_ctlr_reset(dev)); 281 } 282 283 static int 284 ahci_a10_probe(device_t dev) 285 { 286 287 if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-a10-ahci")) 288 return (ENXIO); 289 device_set_desc(dev, "Allwinner Integrated AHCI controller"); 290 291 return (BUS_PROBE_DEFAULT); 292 } 293 294 static int 295 ahci_a10_attach(device_t dev) 296 { 297 int error; 298 struct ahci_controller *ctlr; 299 clk_t clk_pll, clk_gate; 300 301 ctlr = device_get_softc(dev); 302 clk_pll = clk_gate = NULL; 303 304 ctlr->quirks = AHCI_Q_NOPMP; 305 ctlr->vendorid = 0; 306 ctlr->deviceid = 0; 307 ctlr->subvendorid = 0; 308 ctlr->subdeviceid = 0; 309 ctlr->r_rid = 0; 310 if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 311 &ctlr->r_rid, RF_ACTIVE))) 312 return (ENXIO); 313 314 /* Enable clocks */ 315 error = clk_get_by_ofw_index(dev, 0, 0, &clk_gate); 316 if (error != 0) { 317 device_printf(dev, "Cannot get gate clock\n"); 318 goto fail; 319 } 320 error = clk_get_by_ofw_index(dev, 0, 1, &clk_pll); 321 if (error != 0) { 322 device_printf(dev, "Cannot get PLL clock\n"); 323 goto fail; 324 } 325 error = clk_set_freq(clk_pll, PLL_FREQ, CLK_SET_ROUND_DOWN); 326 if (error != 0) { 327 device_printf(dev, "Cannot set PLL frequency\n"); 328 goto fail; 329 } 330 error = clk_enable(clk_pll); 331 if (error != 0) { 332 device_printf(dev, "Cannot enable PLL\n"); 333 goto fail; 334 } 335 error = clk_enable(clk_gate); 336 if (error != 0) { 337 device_printf(dev, "Cannot enable clk gate\n"); 338 goto fail; 339 } 340 341 /* Reset controller */ 342 if ((error = ahci_a10_ctlr_reset(dev)) != 0) 343 goto fail; 344 345 /* 346 * No MSI registers on this platform. 347 */ 348 ctlr->msi = 0; 349 ctlr->numirqs = 1; 350 351 /* Channel start callback(). */ 352 ctlr->ch_start = ahci_a10_ch_start; 353 354 /* 355 * Note: ahci_attach will release ctlr->r_mem on errors automatically 356 */ 357 return (ahci_attach(dev)); 358 359 fail: 360 if (clk_gate != NULL) 361 clk_release(clk_gate); 362 if (clk_pll != NULL) 363 clk_release(clk_pll); 364 bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); 365 return (error); 366 } 367 368 static int 369 ahci_a10_detach(device_t dev) 370 { 371 372 return (ahci_detach(dev)); 373 } 374 375 static device_method_t ahci_ata_methods[] = { 376 DEVMETHOD(device_probe, ahci_a10_probe), 377 DEVMETHOD(device_attach, ahci_a10_attach), 378 DEVMETHOD(device_detach, ahci_a10_detach), 379 DEVMETHOD(bus_print_child, ahci_print_child), 380 DEVMETHOD(bus_alloc_resource, ahci_alloc_resource), 381 DEVMETHOD(bus_release_resource, ahci_release_resource), 382 DEVMETHOD(bus_setup_intr, ahci_setup_intr), 383 DEVMETHOD(bus_teardown_intr,ahci_teardown_intr), 384 DEVMETHOD(bus_child_location_str, ahci_child_location_str), 385 DEVMETHOD_END 386 }; 387 388 static driver_t ahci_ata_driver = { 389 "ahci", 390 ahci_ata_methods, 391 sizeof(struct ahci_controller) 392 }; 393 394 DRIVER_MODULE(a10_ahci, simplebus, ahci_ata_driver, ahci_devclass, 0, 0); 395