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