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/param.h> 35#include <sys/systm.h> 36#include <sys/bus.h> 37#include <sys/rman.h> 38#include <sys/kernel.h> 39#include <sys/module.h> 40 41#include <machine/bus.h> 42#include <dev/ofw/ofw_bus.h> 43#include <dev/ofw/ofw_bus_subr.h> 44 45#include <dev/ahci/ahci.h> 46#include <dev/clk/clk.h> 47#include <dev/regulator/regulator.h> 48 49/* 50 * Allwinner a1x/a2x/a8x SATA attachment. This is just the AHCI register 51 * set with a few extra implementation-specific registers that need to 52 * be accounted for. There's only one PHY in the system, and it needs 53 * to be trained to bring the link up. In addition, there's some DMA 54 * specific things that need to be done as well. These things are also 55 * just about completely undocumented, except in ugly code in the Linux 56 * SDK Allwinner releases. 57 */ 58 59/* BITx -- Unknown bit that needs to be set/cleared at position x */ 60/* UFx -- Uknown multi-bit field frobbed during init */ 61#define AHCI_BISTAFR 0x00A0 62#define AHCI_BISTCR 0x00A4 63#define AHCI_BISTFCTR 0x00A8 64#define AHCI_BISTSR 0x00AC 65#define AHCI_BISTDECR 0x00B0 66#define AHCI_DIAGNR 0x00B4 67#define AHCI_DIAGNR1 0x00B8 68#define AHCI_OOBR 0x00BC 69#define AHCI_PHYCS0R 0x00C0 70/* Bits 0..17 are a mystery */ 71#define PHYCS0R_BIT18 (1 << 18) 72#define PHYCS0R_POWER_ENABLE (1 << 19) 73#define PHYCS0R_UF1_MASK (7 << 20) /* Unknown Field 1 */ 74#define PHYCS0R_UF1_INIT (3 << 20) 75#define PHYCS0R_BIT23 (1 << 23) 76#define PHYCS0R_UF2_MASK (7 << 24) /* Uknown Field 2 */ 77#define PHYCS0R_UF2_INIT (5 << 24) 78/* Bit 27 mystery */ 79#define PHYCS0R_POWER_STATUS_MASK (7 << 28) 80#define PHYCS0R_PS_GOOD (2 << 28) 81/* Bit 31 mystery */ 82#define AHCI_PHYCS1R 0x00C4 83/* Bits 0..5 are a mystery */ 84#define PHYCS1R_UF1_MASK (3 << 6) 85#define PHYCS1R_UF1_INIT (2 << 6) 86#define PHYCS1R_UF2_MASK (0x1f << 8) 87#define PHYCS1R_UF2_INIT (6 << 8) 88/* Bits 13..14 are a mystery */ 89#define PHYCS1R_BIT15 (1 << 15) 90#define PHYCS1R_UF3_MASK (3 << 16) 91#define PHYCS1R_UF3_INIT (2 << 16) 92/* Bit 18 mystery */ 93#define PHYCS1R_HIGHZ (1 << 19) 94/* Bits 20..27 mystery */ 95#define PHYCS1R_BIT28 (1 << 28) 96/* Bits 29..31 mystery */ 97#define AHCI_PHYCS2R 0x00C8 98/* bits 0..4 mystery */ 99#define PHYCS2R_UF1_MASK (0x1f << 5) 100#define PHYCS2R_UF1_INIT (0x19 << 5) 101/* Bits 10..23 mystery */ 102#define PHYCS2R_CALIBRATE (1 << 24) 103/* Bits 25..31 mystery */ 104#define AHCI_TIMER1MS 0x00E0 105#define AHCI_GPARAM1R 0x00E8 106#define AHCI_GPARAM2R 0x00EC 107#define AHCI_PPARAMR 0x00F0 108#define AHCI_TESTR 0x00F4 109#define AHCI_VERSIONR 0x00F8 110#define AHCI_IDR 0x00FC 111#define AHCI_RWCR 0x00FC 112 113#define AHCI_P0DMACR 0x0070 114#define AHCI_P0PHYCR 0x0078 115#define AHCI_P0PHYSR 0x007C 116 117#define PLL_FREQ 100000000 118 119struct ahci_a10_softc { 120 struct ahci_controller ahci_ctlr; 121 regulator_t ahci_reg; 122 clk_t clk_pll; 123 clk_t clk_gate; 124}; 125 126static void inline 127ahci_set(struct resource *m, bus_size_t off, uint32_t set) 128{ 129 uint32_t val = ATA_INL(m, off); 130 131 val |= set; 132 ATA_OUTL(m, off, val); 133} 134 135static void inline 136ahci_clr(struct resource *m, bus_size_t off, uint32_t clr) 137{ 138 uint32_t val = ATA_INL(m, off); 139 140 val &= ~clr; 141 ATA_OUTL(m, off, val); 142} 143 144static void inline 145ahci_mask_set(struct resource *m, bus_size_t off, uint32_t mask, uint32_t set) 146{ 147 uint32_t val = ATA_INL(m, off); 148 149 val &= mask; 150 val |= set; 151 ATA_OUTL(m, off, val); 152} 153 154/* 155 * Should this be phy_reset or phy_init 156 */ 157#define PHY_RESET_TIMEOUT 1000 158static void 159ahci_a10_phy_reset(device_t dev) 160{ 161 uint32_t to, val; 162 struct ahci_controller *ctlr = device_get_softc(dev); 163 164 /* 165 * Here starts the magic -- most of the comments are based 166 * on guesswork, names of routines and printf error 167 * messages. The code works, but it will do that even if the 168 * comments are 100% BS. 169 */ 170 171 /* 172 * Lock out other access while we initialize. Or at least that 173 * seems to be the case based on Linux SDK #defines. Maybe this 174 * put things into reset? 175 */ 176 ATA_OUTL(ctlr->r_mem, AHCI_RWCR, 0); 177 DELAY(100); 178 179 /* 180 * Set bit 19 in PHYCS1R. Guessing this disables driving the PHY 181 * port for a bit while we reset things. 182 */ 183 ahci_set(ctlr->r_mem, AHCI_PHYCS1R, PHYCS1R_HIGHZ); 184 185 /* 186 * Frob PHYCS0R... 187 */ 188 ahci_mask_set(ctlr->r_mem, AHCI_PHYCS0R, 189 ~PHYCS0R_UF2_MASK, 190 PHYCS0R_UF2_INIT | PHYCS0R_BIT23 | PHYCS0R_BIT18); 191 192 /* 193 * Set three fields in PHYCS1R 194 */ 195 ahci_mask_set(ctlr->r_mem, AHCI_PHYCS1R, 196 ~(PHYCS1R_UF1_MASK | PHYCS1R_UF2_MASK | PHYCS1R_UF3_MASK), 197 PHYCS1R_UF1_INIT | PHYCS1R_UF2_INIT | PHYCS1R_UF3_INIT); 198 199 /* 200 * Two more mystery bits in PHYCS1R. -- can these be combined above? 201 */ 202 ahci_set(ctlr->r_mem, AHCI_PHYCS1R, PHYCS1R_BIT15 | PHYCS1R_BIT28); 203 204 /* 205 * Now clear that first mysery bit. Perhaps this starts 206 * driving the PHY again so we can power it up and start 207 * talking to the SATA drive, if any below. 208 */ 209 ahci_clr(ctlr->r_mem, AHCI_PHYCS1R, PHYCS1R_HIGHZ); 210 211 /* 212 * Frob PHYCS0R again... 213 */ 214 ahci_mask_set(ctlr->r_mem, AHCI_PHYCS0R, 215 ~PHYCS0R_UF1_MASK, PHYCS0R_UF1_INIT); 216 217 /* 218 * Frob PHYCS2R, because 25 means something? 219 */ 220 ahci_mask_set(ctlr->r_mem, AHCI_PHYCS2R, ~PHYCS2R_UF1_MASK, 221 PHYCS2R_UF1_INIT); 222 223 DELAY(100); /* WAG */ 224 225 /* 226 * Turn on the power to the PHY and wait for it to report back 227 * good? 228 */ 229 ahci_set(ctlr->r_mem, AHCI_PHYCS0R, PHYCS0R_POWER_ENABLE); 230 for (to = PHY_RESET_TIMEOUT; to > 0; to--) { 231 val = ATA_INL(ctlr->r_mem, AHCI_PHYCS0R); 232 if ((val & PHYCS0R_POWER_STATUS_MASK) == PHYCS0R_PS_GOOD) 233 break; 234 DELAY(10); 235 } 236 if (to == 0 && bootverbose) 237 device_printf(dev, "PHY Power Failed PHYCS0R = %#x\n", val); 238 239 /* 240 * Calibrate the clocks between the device and the host. This appears 241 * to be an automated process that clears the bit when it is done. 242 */ 243 ahci_set(ctlr->r_mem, AHCI_PHYCS2R, PHYCS2R_CALIBRATE); 244 for (to = PHY_RESET_TIMEOUT; to > 0; to--) { 245 val = ATA_INL(ctlr->r_mem, AHCI_PHYCS2R); 246 if ((val & PHYCS2R_CALIBRATE) == 0) 247 break; 248 DELAY(10); 249 } 250 if (to == 0 && bootverbose) 251 device_printf(dev, "PHY Cal Failed PHYCS2R %#x\n", val); 252 253 /* 254 * OK, let things settle down a bit. 255 */ 256 DELAY(1000); 257 258 /* 259 * Go back into normal mode now that we've calibrated the PHY. 260 */ 261 ATA_OUTL(ctlr->r_mem, AHCI_RWCR, 7); 262} 263 264static void 265ahci_a10_ch_start(struct ahci_channel *ch) 266{ 267 uint32_t reg; 268 269 /* 270 * Magical values from Allwinner SDK, setup the DMA before start 271 * operations on this channel. 272 */ 273 reg = ATA_INL(ch->r_mem, AHCI_P0DMACR); 274 reg &= ~0xff00; 275 reg |= 0x4400; 276 ATA_OUTL(ch->r_mem, AHCI_P0DMACR, reg); 277} 278 279static int 280ahci_a10_ctlr_reset(device_t dev) 281{ 282 283 ahci_a10_phy_reset(dev); 284 285 return (ahci_ctlr_reset(dev)); 286} 287 288static int 289ahci_a10_probe(device_t dev) 290{ 291 292 if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-a10-ahci")) 293 return (ENXIO); 294 device_set_desc(dev, "Allwinner Integrated AHCI controller"); 295 296 return (BUS_PROBE_DEFAULT); 297} 298 299static int 300ahci_a10_attach(device_t dev) 301{ 302 int error; 303 struct ahci_a10_softc *sc; 304 struct ahci_controller *ctlr; 305 306 sc = device_get_softc(dev); 307 ctlr = &sc->ahci_ctlr; 308 309 ctlr->quirks = AHCI_Q_NOPMP; 310 ctlr->vendorid = 0; 311 ctlr->deviceid = 0; 312 ctlr->subvendorid = 0; 313 ctlr->subdeviceid = 0; 314 ctlr->r_rid = 0; 315 if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 316 &ctlr->r_rid, RF_ACTIVE))) 317 return (ENXIO); 318 319 /* Enable the (optional) regulator */ 320 if (regulator_get_by_ofw_property(dev, 0, "target-supply", 321 &sc->ahci_reg) == 0) { 322 error = regulator_enable(sc->ahci_reg); 323 if (error != 0) { 324 device_printf(dev, "Could not enable regulator\n"); 325 goto fail; 326 } 327 } 328 329 /* Enable clocks */ 330 error = clk_get_by_ofw_index(dev, 0, 0, &sc->clk_gate); 331 if (error != 0) { 332 device_printf(dev, "Cannot get gate clock\n"); 333 goto fail; 334 } 335 error = clk_get_by_ofw_index(dev, 0, 1, &sc->clk_pll); 336 if (error != 0) { 337 device_printf(dev, "Cannot get PLL clock\n"); 338 goto fail; 339 } 340 error = clk_set_freq(sc->clk_pll, PLL_FREQ, CLK_SET_ROUND_DOWN); 341 if (error != 0) { 342 device_printf(dev, "Cannot set PLL frequency\n"); 343 goto fail; 344 } 345 error = clk_enable(sc->clk_pll); 346 if (error != 0) { 347 device_printf(dev, "Cannot enable PLL\n"); 348 goto fail; 349 } 350 error = clk_enable(sc->clk_gate); 351 if (error != 0) { 352 device_printf(dev, "Cannot enable clk gate\n"); 353 goto fail; 354 } 355 356 /* Reset controller */ 357 if ((error = ahci_a10_ctlr_reset(dev)) != 0) 358 goto fail; 359 360 /* 361 * No MSI registers on this platform. 362 */ 363 ctlr->msi = 0; 364 ctlr->numirqs = 1; 365 366 /* Channel start callback(). */ 367 ctlr->ch_start = ahci_a10_ch_start; 368 369 /* 370 * Note: ahci_attach will release ctlr->r_mem on errors automatically 371 */ 372 return (ahci_attach(dev)); 373 374fail: 375 if (sc->ahci_reg != NULL) 376 regulator_disable(sc->ahci_reg); 377 if (sc->clk_gate != NULL) 378 clk_release(sc->clk_gate); 379 if (sc->clk_pll != NULL) 380 clk_release(sc->clk_pll); 381 bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); 382 return (error); 383} 384 385static int 386ahci_a10_detach(device_t dev) 387{ 388 struct ahci_a10_softc *sc; 389 struct ahci_controller *ctlr; 390 391 sc = device_get_softc(dev); 392 ctlr = &sc->ahci_ctlr; 393 394 if (sc->ahci_reg != NULL) 395 regulator_disable(sc->ahci_reg); 396 if (sc->clk_gate != NULL) 397 clk_release(sc->clk_gate); 398 if (sc->clk_pll != NULL) 399 clk_release(sc->clk_pll); 400 bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); 401 return (ahci_detach(dev)); 402} 403 404static device_method_t ahci_ata_methods[] = { 405 DEVMETHOD(device_probe, ahci_a10_probe), 406 DEVMETHOD(device_attach, ahci_a10_attach), 407 DEVMETHOD(device_detach, ahci_a10_detach), 408 DEVMETHOD(bus_print_child, ahci_print_child), 409 DEVMETHOD(bus_alloc_resource, ahci_alloc_resource), 410 DEVMETHOD(bus_release_resource, ahci_release_resource), 411 DEVMETHOD(bus_setup_intr, ahci_setup_intr), 412 DEVMETHOD(bus_teardown_intr,ahci_teardown_intr), 413 DEVMETHOD(bus_child_location, ahci_child_location), 414 DEVMETHOD_END 415}; 416 417static driver_t ahci_ata_driver = { 418 "ahci", 419 ahci_ata_methods, 420 sizeof(struct ahci_a10_softc) 421}; 422 423DRIVER_MODULE(a10_ahci, simplebus, ahci_ata_driver, 0, 0); 424