Home | History | Annotate | Line # | Download | only in nxp
imx_ahcisata.c revision 1.3
      1  1.3   thorpej /*	$NetBSD: imx_ahcisata.c,v 1.3 2021/01/27 03:10:20 thorpej Exp $	*/
      2  1.1     skrll 
      3  1.1     skrll /*-
      4  1.1     skrll  * Copyright (c) 2019 Genetec Corporation.  All rights reserved.
      5  1.1     skrll  * Written by Hashimoto Kenichi for Genetec Corporation.
      6  1.1     skrll  *
      7  1.1     skrll  * Redistribution and use in source and binary forms, with or without
      8  1.1     skrll  * modification, are permitted provided that the following conditions
      9  1.1     skrll  * are met:
     10  1.1     skrll  * 1. Redistributions of source code must retain the above copyright
     11  1.1     skrll  *    notice, this list of conditions and the following disclaimer.
     12  1.1     skrll  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1     skrll  *    notice, this list of conditions and the following disclaimer in the
     14  1.1     skrll  *    documentation and/or other materials provided with the distribution.
     15  1.1     skrll  *
     16  1.1     skrll  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  1.1     skrll  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  1.1     skrll  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  1.1     skrll  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  1.1     skrll  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  1.1     skrll  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22  1.1     skrll  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  1.1     skrll  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  1.1     skrll  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  1.1     skrll  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  1.1     skrll  * SUCH DAMAGE.
     27  1.1     skrll  */
     28  1.1     skrll 
     29  1.1     skrll #include <sys/cdefs.h>
     30  1.3   thorpej __KERNEL_RCSID(0, "$NetBSD: imx_ahcisata.c,v 1.3 2021/01/27 03:10:20 thorpej Exp $");
     31  1.1     skrll 
     32  1.1     skrll #include <sys/param.h>
     33  1.1     skrll #include <sys/bus.h>
     34  1.1     skrll #include <sys/device.h>
     35  1.1     skrll #include <sys/intr.h>
     36  1.1     skrll #include <sys/systm.h>
     37  1.1     skrll #include <sys/kernel.h>
     38  1.1     skrll 
     39  1.1     skrll #include <dev/ata/atavar.h>
     40  1.1     skrll #include <dev/ic/ahcisatavar.h>
     41  1.1     skrll 
     42  1.1     skrll #include <arm/nxp/imx_ahcisatareg.h>
     43  1.1     skrll #include <arm/nxp/imx6_iomuxreg.h>
     44  1.1     skrll #include <arm/nxp/imx6_ccmreg.h>
     45  1.1     skrll #include <arm/nxp/imx6_ccmvar.h>
     46  1.1     skrll 
     47  1.1     skrll #include <dev/fdt/fdtvar.h>
     48  1.1     skrll 
     49  1.1     skrll static int imx_ahcisata_match(device_t, cfdata_t, void *);
     50  1.1     skrll static void imx_ahcisata_attach(device_t, device_t, void *);
     51  1.1     skrll 
     52  1.1     skrll struct imx_ahcisata_softc {
     53  1.1     skrll 	struct ahci_softc sc;
     54  1.1     skrll 
     55  1.1     skrll 	device_t sc_dev;
     56  1.1     skrll 	bus_space_tag_t sc_iot;
     57  1.1     skrll 	bus_space_handle_t sc_ioh;
     58  1.1     skrll 	bus_space_handle_t sc_gpr_ioh;
     59  1.1     skrll 	void *sc_ih;
     60  1.1     skrll 
     61  1.1     skrll 	u_int sc_tx_level;
     62  1.1     skrll 	u_int sc_tx_boost;
     63  1.1     skrll 	u_int sc_tx_atten;
     64  1.1     skrll 	u_int sc_rx_eq;
     65  1.1     skrll 	u_int sc_ss;
     66  1.1     skrll 
     67  1.1     skrll 	struct clk *sc_clk_sata;
     68  1.1     skrll 	struct clk *sc_clk_sata_ref;
     69  1.1     skrll 	struct clk *sc_clk_ahb;
     70  1.1     skrll };
     71  1.1     skrll 
     72  1.1     skrll static int imx_ahcisata_init(struct imx_ahcisata_softc *);
     73  1.1     skrll static int imx_ahcisata_phy_ctrl(struct imx_ahcisata_softc *, uint32_t, int);
     74  1.1     skrll static int imx_ahcisata_phy_addr(struct imx_ahcisata_softc *, uint32_t);
     75  1.1     skrll static int imx_ahcisata_phy_write(struct imx_ahcisata_softc *, uint32_t, uint16_t);
     76  1.1     skrll static int imx_ahcisata_phy_read(struct imx_ahcisata_softc *, uint32_t);
     77  1.1     skrll static int imx_ahcisata_init_clocks(struct imx_ahcisata_softc *);
     78  1.1     skrll 
     79  1.1     skrll CFATTACH_DECL_NEW(imx_ahcisata, sizeof(struct imx_ahcisata_softc),
     80  1.1     skrll 	imx_ahcisata_match, imx_ahcisata_attach, NULL, NULL);
     81  1.1     skrll 
     82  1.3   thorpej static const struct device_compatible_entry compat_data[] = {
     83  1.3   thorpej 	{ .compat = "fsl,imx6q-ahci" },
     84  1.3   thorpej 	DEVICE_COMPAT_EOL
     85  1.3   thorpej };
     86  1.3   thorpej 
     87  1.1     skrll static int
     88  1.1     skrll imx_ahcisata_match(device_t parent, cfdata_t cf, void *aux)
     89  1.1     skrll {
     90  1.1     skrll 	struct fdt_attach_args * const faa = aux;
     91  1.1     skrll 
     92  1.3   thorpej 	return of_compatible_match(faa->faa_phandle, compat_data);
     93  1.1     skrll }
     94  1.1     skrll 
     95  1.1     skrll static void
     96  1.1     skrll imx_ahcisata_attach(device_t parent, device_t self, void *aux)
     97  1.1     skrll {
     98  1.1     skrll 	struct imx_ahcisata_softc * const sc = device_private(self);
     99  1.1     skrll 	struct fdt_attach_args * const faa = aux;
    100  1.1     skrll 	const int phandle = faa->faa_phandle;
    101  1.1     skrll 	bus_addr_t ahci_addr;
    102  1.1     skrll 	bus_size_t ahci_size;
    103  1.1     skrll 	bus_addr_t addr;
    104  1.1     skrll 	bus_size_t size;
    105  1.1     skrll 	char intrstr[128];
    106  1.1     skrll 	int error;
    107  1.1     skrll 
    108  1.1     skrll 	if (fdtbus_get_reg(phandle, 0, &ahci_addr, &ahci_size) != 0) {
    109  1.1     skrll 		aprint_error(": couldn't get ahci registers\n");
    110  1.1     skrll 		return;
    111  1.1     skrll 	}
    112  1.1     skrll 
    113  1.1     skrll 	if (of_getprop_uint32(phandle, "fsl,transmit-level-mV", &sc->sc_tx_level) != 0)
    114  1.1     skrll 		sc->sc_tx_level = 1104;
    115  1.1     skrll 	if (of_getprop_uint32(phandle, "fsl,transmit-boost-mdB", &sc->sc_tx_boost) != 0)
    116  1.1     skrll 		sc->sc_tx_boost = 3330;
    117  1.1     skrll 	if (of_getprop_uint32(phandle, "fsl,transmit-atten-16ths", &sc->sc_tx_atten) != 0)
    118  1.1     skrll 		sc->sc_tx_atten = 9;
    119  1.1     skrll 	if (of_getprop_uint32(phandle, "fsl,receive-eq-mdB", &sc->sc_rx_eq) != 0)
    120  1.1     skrll 		sc->sc_rx_eq = 3000;
    121  1.1     skrll 	if (of_getprop_bool(phandle, "fsl,no-spread-spectrum") == false)
    122  1.1     skrll 		sc->sc_ss = 1;
    123  1.1     skrll 	else
    124  1.1     skrll 		sc->sc_ss = 0;
    125  1.1     skrll 
    126  1.1     skrll 	sc->sc_clk_sata = fdtbus_clock_get(phandle, "sata");
    127  1.1     skrll 	if (sc->sc_clk_sata == NULL) {
    128  1.1     skrll 		aprint_error(": couldn't get clock sata\n");
    129  1.1     skrll 		return;
    130  1.1     skrll 	}
    131  1.1     skrll 	sc->sc_clk_sata_ref = fdtbus_clock_get(phandle, "sata_ref");
    132  1.1     skrll 	if (sc->sc_clk_sata_ref == NULL) {
    133  1.1     skrll 		aprint_error(": couldn't get clock sata_ref\n");
    134  1.1     skrll 		return;
    135  1.1     skrll 	}
    136  1.1     skrll 	sc->sc_clk_ahb = fdtbus_clock_get(phandle, "ahb");
    137  1.1     skrll 	if (sc->sc_clk_ahb == NULL) {
    138  1.1     skrll 		aprint_error(": couldn't get clock ahb\n");
    139  1.1     skrll 		return;
    140  1.1     skrll 	}
    141  1.1     skrll 
    142  1.1     skrll 	aprint_naive("\n");
    143  1.1     skrll 	aprint_normal(": AHCI Controller\n");
    144  1.1     skrll 
    145  1.1     skrll 	aprint_debug_dev(self, "tx level %d [mV]\n", sc->sc_tx_level);
    146  1.1     skrll 	aprint_debug_dev(self, "tx boost %d [mdB]\n", sc->sc_tx_boost);
    147  1.1     skrll 	aprint_debug_dev(self, "tx atten %d [16ths]\n", sc->sc_tx_atten);
    148  1.1     skrll 	aprint_debug_dev(self, "rx eq    %d [mdB]\n", sc->sc_rx_eq);
    149  1.1     skrll 	aprint_debug_dev(self, "ss       %d\n", sc->sc_ss);
    150  1.1     skrll 
    151  1.1     skrll 	sc->sc_dev = self;
    152  1.1     skrll 
    153  1.1     skrll 	sc->sc.sc_atac.atac_dev = self;
    154  1.1     skrll 	sc->sc.sc_ahci_ports = 1;
    155  1.1     skrll 	sc->sc.sc_dmat = faa->faa_dmat;
    156  1.1     skrll 	sc->sc.sc_ahcit = faa->faa_bst;
    157  1.1     skrll 	sc->sc.sc_ahcis = ahci_size;
    158  1.1     skrll 	error = bus_space_map(sc->sc.sc_ahcit, ahci_addr, ahci_size, 0,
    159  1.1     skrll 	    &sc->sc.sc_ahcih);
    160  1.1     skrll 	if (error) {
    161  1.1     skrll 		aprint_error(": couldn't map ahci registers: %d\n", error);
    162  1.1     skrll 		return;
    163  1.1     skrll 	}
    164  1.1     skrll 
    165  1.1     skrll 	sc->sc_iot = sc->sc.sc_ahcit;
    166  1.1     skrll 	sc->sc_ioh = sc->sc.sc_ahcih;
    167  1.1     skrll 
    168  1.1     skrll 	const int gpr_phandle = OF_finddevice("/soc/aips-bus/iomuxc-gpr");
    169  1.1     skrll 	fdtbus_get_reg(gpr_phandle, 0, &addr, &size);
    170  1.1     skrll 	if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_gpr_ioh)) {
    171  1.1     skrll 		aprint_error_dev(self, "Cannot map registers\n");
    172  1.1     skrll 		return;
    173  1.1     skrll 	}
    174  1.1     skrll 
    175  1.1     skrll 	if (imx_ahcisata_init_clocks(sc) != 0) {
    176  1.1     skrll 		aprint_error_dev(self, "couldn't init clocks\n");
    177  1.1     skrll 		return;
    178  1.1     skrll 	}
    179  1.1     skrll 
    180  1.1     skrll 	if (imx_ahcisata_init(sc) != 0) {
    181  1.1     skrll 		aprint_error_dev(self, "couldn't init ahci\n");
    182  1.1     skrll 		return;
    183  1.1     skrll 	}
    184  1.1     skrll 
    185  1.1     skrll 	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
    186  1.1     skrll 		aprint_error_dev(self, "failed to decode interrupt\n");
    187  1.1     skrll 		return;
    188  1.1     skrll 	}
    189  1.1     skrll 
    190  1.2  jmcneill 	sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_BIO, 0,
    191  1.2  jmcneill 	    ahci_intr, &sc->sc, device_xname(self));
    192  1.1     skrll 	if (sc->sc_ih == NULL) {
    193  1.1     skrll 		aprint_error_dev(self, "failed to establish interrupt on %s\n",
    194  1.1     skrll 		    intrstr);
    195  1.1     skrll 		return;
    196  1.1     skrll 	}
    197  1.1     skrll 	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
    198  1.1     skrll 
    199  1.1     skrll 	ahci_attach(&sc->sc);
    200  1.1     skrll }
    201  1.1     skrll 
    202  1.1     skrll static int
    203  1.1     skrll imx_ahcisata_phy_ctrl(struct imx_ahcisata_softc *sc, uint32_t bitmask, int on)
    204  1.1     skrll {
    205  1.1     skrll 	uint32_t v;
    206  1.1     skrll 	int timeout;
    207  1.1     skrll 
    208  1.1     skrll 	v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR);
    209  1.1     skrll 	if (on)
    210  1.1     skrll 		v |= bitmask;
    211  1.1     skrll 	else
    212  1.1     skrll 		v &= ~bitmask;
    213  1.1     skrll 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR, v);
    214  1.1     skrll 
    215  1.1     skrll 	for (timeout = 5000; timeout > 0; --timeout) {
    216  1.1     skrll 		v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYSR);
    217  1.1     skrll 		if (!!(v & SATA_P0PHYSR_CR_ACK) == !!on)
    218  1.1     skrll 			break;
    219  1.1     skrll 		delay(100);
    220  1.1     skrll 	}
    221  1.1     skrll 
    222  1.1     skrll 	if (timeout > 0)
    223  1.1     skrll 		return 0;
    224  1.1     skrll 
    225  1.1     skrll 	return -1;
    226  1.1     skrll }
    227  1.1     skrll 
    228  1.1     skrll static int
    229  1.1     skrll imx_ahcisata_phy_addr(struct imx_ahcisata_softc *sc, uint32_t addr)
    230  1.1     skrll {
    231  1.1     skrll 	delay(100);
    232  1.1     skrll 
    233  1.1     skrll 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR, addr);
    234  1.1     skrll 
    235  1.1     skrll 	if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_ADDR, 1) != 0)
    236  1.1     skrll 		return -1;
    237  1.1     skrll 	if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_ADDR, 0) != 0)
    238  1.1     skrll 		return -1;
    239  1.1     skrll 
    240  1.1     skrll 	return 0;
    241  1.1     skrll }
    242  1.1     skrll 
    243  1.1     skrll static int
    244  1.1     skrll imx_ahcisata_phy_write(struct imx_ahcisata_softc *sc, uint32_t addr,
    245  1.1     skrll                         uint16_t data)
    246  1.1     skrll {
    247  1.1     skrll 	if (imx_ahcisata_phy_addr(sc, addr) != 0)
    248  1.1     skrll 		return -1;
    249  1.1     skrll 
    250  1.1     skrll 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR, data);
    251  1.1     skrll 
    252  1.1     skrll 	if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_DATA, 1) != 0)
    253  1.1     skrll 		return -1;
    254  1.1     skrll 	if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_DATA, 0) != 0)
    255  1.1     skrll 		return -1;
    256  1.1     skrll 
    257  1.1     skrll 	if ((addr == SATA_PHY_CLOCK_RESET) && data) {
    258  1.1     skrll 		/* we can't check ACK after RESET */
    259  1.1     skrll 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR,
    260  1.1     skrll 		    data | SATA_P0PHYCR_CR_WRITE);
    261  1.1     skrll 		return 0;
    262  1.1     skrll 	}
    263  1.1     skrll 
    264  1.1     skrll 	if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_WRITE, 1) != 0)
    265  1.1     skrll 		return -1;
    266  1.1     skrll 	if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_WRITE, 0) != 0)
    267  1.1     skrll 		return -1;
    268  1.1     skrll 
    269  1.1     skrll 	return 0;
    270  1.1     skrll }
    271  1.1     skrll 
    272  1.1     skrll static int
    273  1.1     skrll imx_ahcisata_phy_read(struct imx_ahcisata_softc *sc, uint32_t addr)
    274  1.1     skrll {
    275  1.1     skrll 	uint32_t v;
    276  1.1     skrll 
    277  1.1     skrll 	if (imx_ahcisata_phy_addr(sc, addr) != 0)
    278  1.1     skrll 		return -1;
    279  1.1     skrll 
    280  1.1     skrll 	if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_READ, 1) != 0)
    281  1.1     skrll 		return -1;
    282  1.1     skrll 
    283  1.1     skrll 	v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYSR);
    284  1.1     skrll 
    285  1.1     skrll 	if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_READ, 0) != 0)
    286  1.1     skrll 		return -1;
    287  1.1     skrll 
    288  1.1     skrll 	return SATA_P0PHYSR_CR_DATA_OUT(v);
    289  1.1     skrll }
    290  1.1     skrll 
    291  1.1     skrll const static int tx_level[] = {
    292  1.1     skrll 	 937,
    293  1.1     skrll 	 947,
    294  1.1     skrll 	 957,
    295  1.1     skrll 	 966,
    296  1.1     skrll 	 976,
    297  1.1     skrll 	 986,
    298  1.1     skrll 	 996,
    299  1.1     skrll 	1005,
    300  1.1     skrll 	1015,
    301  1.1     skrll 	1025,
    302  1.1     skrll 	1035,
    303  1.1     skrll 	1045,
    304  1.1     skrll 	1054,
    305  1.1     skrll 	1064,
    306  1.1     skrll 	1074,
    307  1.1     skrll 	1084,
    308  1.1     skrll 	1094,
    309  1.1     skrll 	1104,
    310  1.1     skrll 	1113,
    311  1.1     skrll 	1123,
    312  1.1     skrll 	1133,
    313  1.1     skrll 	1143,
    314  1.1     skrll 	1152,
    315  1.1     skrll 	1162,
    316  1.1     skrll 	1172,
    317  1.1     skrll 	1182,
    318  1.1     skrll 	1191,
    319  1.1     skrll 	1201,
    320  1.1     skrll 	1211,
    321  1.1     skrll 	1221,
    322  1.1     skrll 	1230,
    323  1.1     skrll 	1240,
    324  1.1     skrll };
    325  1.1     skrll 
    326  1.1     skrll const static int tx_boots[] = {
    327  1.1     skrll 	   0,
    328  1.1     skrll 	 370,
    329  1.1     skrll 	 740,
    330  1.1     skrll 	1110,
    331  1.1     skrll 	1480,
    332  1.1     skrll 	1850,
    333  1.1     skrll 	2220,
    334  1.1     skrll 	2590,
    335  1.1     skrll 	2960,
    336  1.1     skrll 	3330,
    337  1.1     skrll 	3700,
    338  1.1     skrll 	4070,
    339  1.1     skrll 	4440,
    340  1.1     skrll 	4810,
    341  1.1     skrll 	5280,
    342  1.1     skrll 	5750,
    343  1.1     skrll };
    344  1.1     skrll 
    345  1.1     skrll const static int tx_atten[] = {
    346  1.1     skrll 	  16,
    347  1.1     skrll 	  14,
    348  1.1     skrll 	  12,
    349  1.1     skrll 	  10,
    350  1.1     skrll 	   9,
    351  1.1     skrll 	   8,
    352  1.1     skrll };
    353  1.1     skrll 
    354  1.1     skrll const static int rx_eq[] = {
    355  1.1     skrll 	 500,
    356  1.1     skrll 	1000,
    357  1.1     skrll 	1500,
    358  1.1     skrll 	2000,
    359  1.1     skrll 	2500,
    360  1.1     skrll 	3000,
    361  1.1     skrll 	3500,
    362  1.1     skrll 	4000,
    363  1.1     skrll };
    364  1.1     skrll 
    365  1.1     skrll static int
    366  1.1     skrll imx_ahcisata_search_regval(const int *values, int count, int val)
    367  1.1     skrll {
    368  1.1     skrll 	for (int i = 0; i < count; i++)
    369  1.1     skrll 		if (values[i] == val)
    370  1.1     skrll 			return i;
    371  1.1     skrll 
    372  1.1     skrll 	return -1;
    373  1.1     skrll }
    374  1.1     skrll 
    375  1.1     skrll static int
    376  1.1     skrll imx_ahcisata_init(struct imx_ahcisata_softc *sc)
    377  1.1     skrll {
    378  1.1     skrll 	uint32_t v;
    379  1.1     skrll 	int timeout;
    380  1.1     skrll 	int pllstat;
    381  1.1     skrll 
    382  1.1     skrll 	v = bus_space_read_4(sc->sc_iot, sc->sc_gpr_ioh, IOMUX_GPR13);
    383  1.1     skrll 	/* clear */
    384  1.1     skrll 	v &= ~(IOMUX_GPR13_SATA_PHY_8 |
    385  1.1     skrll 	    IOMUX_GPR13_SATA_PHY_7 |
    386  1.1     skrll 	    IOMUX_GPR13_SATA_PHY_6 |
    387  1.1     skrll 	    IOMUX_GPR13_SATA_SPEED |
    388  1.1     skrll 	    IOMUX_GPR13_SATA_PHY_5 |
    389  1.1     skrll 	    IOMUX_GPR13_SATA_PHY_4 |
    390  1.1     skrll 	    IOMUX_GPR13_SATA_PHY_3 |
    391  1.1     skrll 	    IOMUX_GPR13_SATA_PHY_2 |
    392  1.1     skrll 	    IOMUX_GPR13_SATA_PHY_1 |
    393  1.1     skrll 	    IOMUX_GPR13_SATA_PHY_0);
    394  1.1     skrll 	/* setting */
    395  1.1     skrll 	struct {
    396  1.1     skrll 		const int *array;
    397  1.1     skrll 		int count;
    398  1.1     skrll 		int val;
    399  1.1     skrll 		int def_val;
    400  1.1     skrll 		int mask;
    401  1.1     skrll 	} gpr13_sata_phy_settings[] = {
    402  1.1     skrll 		{ tx_level, __arraycount(tx_level), sc->sc_tx_level,
    403  1.1     skrll 		  0x11, IOMUX_GPR13_SATA_PHY_2 },
    404  1.1     skrll 		{ tx_boots, __arraycount(tx_boots), sc->sc_tx_boost,
    405  1.1     skrll 		  0x09, IOMUX_GPR13_SATA_PHY_3 },
    406  1.1     skrll 		{ tx_atten, __arraycount(tx_atten), sc->sc_tx_atten,
    407  1.1     skrll 		  0x04, IOMUX_GPR13_SATA_PHY_4 },
    408  1.1     skrll 		{ rx_eq, __arraycount(rx_eq), sc->sc_rx_eq,
    409  1.1     skrll 		  0x05, IOMUX_GPR13_SATA_PHY_8 }
    410  1.1     skrll 	};
    411  1.1     skrll 	for (int i = 0; i < __arraycount(gpr13_sata_phy_settings); i++) {
    412  1.1     skrll 		int val;
    413  1.1     skrll 		val = imx_ahcisata_search_regval(
    414  1.1     skrll 			gpr13_sata_phy_settings[i].array,
    415  1.1     skrll 			gpr13_sata_phy_settings[i].count,
    416  1.1     skrll 			gpr13_sata_phy_settings[i].val);
    417  1.1     skrll 		if (val == -1)
    418  1.1     skrll 			val = gpr13_sata_phy_settings[i].def_val;
    419  1.1     skrll 		v |= __SHIFTIN(val, gpr13_sata_phy_settings[i].mask);
    420  1.1     skrll 	}
    421  1.1     skrll 	v |= __SHIFTIN(0x12, IOMUX_GPR13_SATA_PHY_7);	/* Rx SATA2m */
    422  1.1     skrll 	v |= __SHIFTIN(3, IOMUX_GPR13_SATA_PHY_6);	/* Rx DPLL mode */
    423  1.1     skrll 	v |= __SHIFTIN(1, IOMUX_GPR13_SATA_SPEED);	/* 3.0GHz */
    424  1.1     skrll 	v |= __SHIFTIN(sc->sc_ss, IOMUX_GPR13_SATA_PHY_5);
    425  1.1     skrll 	v |= __SHIFTIN(1, IOMUX_GPR13_SATA_PHY_1);	/* PLL clock enable */
    426  1.1     skrll 	bus_space_write_4(sc->sc_iot, sc->sc_gpr_ioh, IOMUX_GPR13, v);
    427  1.1     skrll 
    428  1.1     skrll 	/* phy reset */
    429  1.1     skrll 	if (imx_ahcisata_phy_write(sc, SATA_PHY_CLOCK_RESET,
    430  1.1     skrll 	    SATA_PHY_CLOCK_RESET_RST) < 0) {
    431  1.1     skrll 		aprint_error_dev(sc->sc_dev, "cannot reset PHY\n");
    432  1.1     skrll 		return -1;
    433  1.1     skrll 	}
    434  1.1     skrll 
    435  1.1     skrll 	for (timeout = 50; timeout > 0; --timeout) {
    436  1.1     skrll 		delay(100);
    437  1.1     skrll 		pllstat = imx_ahcisata_phy_read(sc, SATA_PHY_LANE0_OUT_STAT);
    438  1.1     skrll 		if (pllstat < 0) {
    439  1.1     skrll 			aprint_error_dev(sc->sc_dev,
    440  1.1     skrll 			    "cannot read LANE0 status\n");
    441  1.1     skrll 			break;
    442  1.1     skrll 		}
    443  1.1     skrll 		if (pllstat & SATA_PHY_LANE0_OUT_STAT_RX_PLL_STATE)
    444  1.1     skrll 			break;
    445  1.1     skrll 	}
    446  1.1     skrll 	if (timeout <= 0)
    447  1.1     skrll 		return -1;
    448  1.1     skrll 
    449  1.1     skrll 	/* Support Staggered Spin-up */
    450  1.1     skrll 	v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_CAP);
    451  1.1     skrll 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_CAP, v | SATA_CAP_SSS);
    452  1.1     skrll 
    453  1.1     skrll 	/* Ports Implmented. must set 1 */
    454  1.1     skrll 	v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_PI);
    455  1.1     skrll 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_PI, v | SATA_PI_PI);
    456  1.1     skrll 
    457  1.1     skrll 	/* set 1ms-timer = AHB clock / 1000 */
    458  1.1     skrll 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_TIMER1MS,
    459  1.1     skrll 	    clk_get_rate(sc->sc_clk_ahb) / 1000);
    460  1.1     skrll 
    461  1.1     skrll 	return 0;
    462  1.1     skrll }
    463  1.1     skrll 
    464  1.1     skrll static int
    465  1.1     skrll imx_ahcisata_init_clocks(struct imx_ahcisata_softc *sc)
    466  1.1     skrll {
    467  1.1     skrll 	int error;
    468  1.1     skrll 
    469  1.1     skrll 	error = clk_enable(sc->sc_clk_sata);
    470  1.1     skrll 	if (error) {
    471  1.1     skrll 		aprint_error_dev(sc->sc_dev, "couldn't enable sata: %d\n", error);
    472  1.1     skrll 		return error;
    473  1.1     skrll 	}
    474  1.1     skrll 	error = clk_enable(sc->sc_clk_sata_ref);
    475  1.1     skrll 	if (error) {
    476  1.1     skrll 		aprint_error_dev(sc->sc_dev, "couldn't enable sata-ref: %d\n", error);
    477  1.1     skrll 		return error;
    478  1.1     skrll 	}
    479  1.1     skrll 	error = clk_enable(sc->sc_clk_ahb);
    480  1.1     skrll 	if (error) {
    481  1.1     skrll 		aprint_error_dev(sc->sc_dev, "couldn't enable anb: %d\n", error);
    482  1.1     skrll 		return error;
    483  1.1     skrll 	}
    484  1.1     skrll 
    485  1.1     skrll 	return 0;
    486  1.1     skrll }
    487