Index: sys/arch/arm/nvidia/tegra210_car.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/nvidia/tegra210_car.c,v retrieving revision 1.22 diff -u -p -r1.22 tegra210_car.c --- sys/arch/arm/nvidia/tegra210_car.c 12 Dec 2018 09:55:34 -0000 1.22 +++ sys/arch/arm/nvidia/tegra210_car.c 12 Dec 2018 09:56:11 -0000 @@ -29,6 +29,8 @@ #include __KERNEL_RCSID(0, "$NetBSD: tegra210_car.c,v 1.22 2018/12/12 09:55:34 skrll Exp $"); +#define TEGRA210_CAR_DEBUG + #include #include #include @@ -457,6 +459,9 @@ static const char *mux_hda_p[] = { "PLL_P", "PLL_C2", "PLL_C", "PLL_C4_OUT0", NULL, "PLL_C4_OUT1", "CLK_M", "PLL_C4_OUT2" }; +static const char *mux_sata_p[] = + { "PLL_P", "PLL_C", "CLK_M" }; + static struct tegra_clk tegra210_car_clocks[] = { CLK_FIXED("CLK_M", TEGRA210_REF_FREQ), @@ -536,6 +541,13 @@ static struct tegra_clk tegra210_car_clo CAR_CLKSRC_HDA_REG, CAR_CLKSRC_HDA_SRC, mux_hda_p), + CLK_MUX("MUX_SATA_OOB", + CAR_CLKSRC_SATA_OOB_REG , CAR_CLKSRC_SATA_OOB_SRC, + mux_sata_p), + CLK_MUX("MUX_SATA", + CAR_CLKSRC_SATA_REG, CAR_CLKSRC_SATA_SRC, + mux_sata_p), + CLK_DIV("DIV_UARTA", "MUX_UARTA", CAR_CLKSRC_UARTA_REG, CAR_CLKSRC_UART_DIV), CLK_DIV("DIV_UARTB", "MUX_UARTB", @@ -595,6 +607,11 @@ static struct tegra_clk tegra210_car_clo CLK_DIV("DIV_HDA", "MUX_HDA", CAR_CLKSRC_HDA_REG, CAR_CLKSRC_HDA_DIV), + CLK_DIV("DIV_SATA_OOB", "MUX_SATA_OOB", + CAR_CLKSRC_SATA_OOB_REG, CAR_CLKSRC_SATA_OOB_DIV), + CLK_DIV("DIV_SATA", "MUX_SATA", + CAR_CLKSRC_SATA_REG, CAR_CLKSRC_SATA_DIV), + CLK_GATE_SIMPLE("PLL_U_OUT1", "DIV_PLL_U_OUT1", CAR_PLLU_OUTA_REG, CAR_PLLU_OUTA_OUT1_CLKEN), CLK_GATE_SIMPLE("PLL_U_OUT2", "DIV_PLL_U_OUT2", @@ -636,6 +653,9 @@ static struct tegra_clk tegra210_car_clo CLK_GATE_W("HDA2HDMI", "CLK_M", CAR_DEV_W_HDA2HDMICODEC), CLK_GATE_V("HDA2CODEC_2X", "DIV_HDA2CODEC_2X", CAR_DEV_V_HDA2CODEC_2X), CLK_GATE_V("HDA", "DIV_HDA", CAR_DEV_V_HDA), + + CLK_GATE_V("SATA_OOB", "DIV_SATA_OOB", CAR_DEV_V_SATA_OOB), + CLK_GATE_V("SATA", "DIV_SATA", CAR_DEV_V_SATA), }; struct tegra210_init_parent { @@ -661,6 +681,8 @@ struct tegra210_init_parent { { "CML1", NULL, 0, 0 }, { "AFI", NULL, 0, 1 }, { "PCIE", NULL, 0, 1 }, + { "SATA", "PLL_P", 104000000, 0 }, + { "SATA_OOB", "PLL_P", 204000000, 0 }, }; struct tegra210_car_rst { @@ -848,6 +870,7 @@ tegra210_car_parent_init(struct tegra210 static void tegra210_car_utmip_init(struct tegra210_car_softc *sc) { +printf("%s\n", __func__); bus_space_tag_t bst = sc->sc_bst; bus_space_handle_t bsh = sc->sc_bsh; @@ -876,6 +899,8 @@ tegra210_car_utmip_init(struct tegra210_ bus_space_write_4(bst, bsh, CAR_CLK_ENB_U_SET_REG, CAR_DEV_U_AFI); bus_space_write_4(bst, bsh, CAR_CLK_ENB_U_SET_REG, CAR_DEV_U_PCIE); +// SATA? + bus_space_write_4(bst, bsh, CAR_RST_DEV_L_CLR_REG, CAR_DEV_L_USBD); bus_space_write_4(bst, bsh, CAR_RST_DEV_H_CLR_REG, CAR_DEV_H_USB2); bus_space_write_4(bst, bsh, CAR_RST_DEV_W_CLR_REG, CAR_DEV_W_XUSB); @@ -1420,6 +1445,7 @@ tegra210_car_clock_set_rate_div(struct t return EINVAL; } break; + // XXXNH default: if (rate) { raw_div = (parent_rate / rate) * 2; @@ -1681,3 +1707,34 @@ tegra210_car_xusbio_enable_hw_seq(void) tegra_reg_set_clear(bst, bsh, CAR_XUSBIO_PLL_CFG0_REG, CAR_XUSBIO_PLL_CFG0_SEQ_ENABLE, 0); } + +void +tegra210_car_sata_enable_hw_control(void) +{ + device_t dev = device_find_by_driver_unit("tegra210car", 0); + KASSERT(dev != NULL); + struct tegra210_car_softc * const sc = device_private(dev); + bus_space_tag_t bst = sc->sc_bst; + bus_space_handle_t bsh = sc->sc_bsh; + + tegra_reg_set_clear(bst, bsh, CAR_SATA_PLL_CFG0_REG, + 0, + CAR_SATA_PLL_CFG0_PADPLL_RESET_SWCTL); + tegra_reg_set_clear(bst, bsh, CAR_SATA_PLL_CFG0_REG, + CAR_SATA_PLL_CFG0_SEQ_PADPLL_SLEEP_IDDQ | + CAR_SATA_PLL_CFG0_PADPLL_USE_LOCKDET, + 0); +} + +void +tegra210_car_sata_enable_hw_seq(void) +{ + device_t dev = device_find_by_driver_unit("tegra210car", 0); + KASSERT(dev != NULL); + struct tegra210_car_softc * const sc = device_private(dev); + bus_space_tag_t bst = sc->sc_bst; + bus_space_handle_t bsh = sc->sc_bsh; + + tegra_reg_set_clear(bst, bsh, CAR_SATA_PLL_CFG0_REG, + CAR_SATA_PLL_CFG0_SEQ_ENABLE, 0); +} Index: sys/arch/arm/nvidia/tegra210_carreg.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/nvidia/tegra210_carreg.h,v retrieving revision 1.8 diff -u -p -r1.8 tegra210_carreg.h --- sys/arch/arm/nvidia/tegra210_carreg.h 25 Sep 2017 08:55:07 -0000 1.8 +++ sys/arch/arm/nvidia/tegra210_carreg.h 12 Dec 2018 09:56:11 -0000 @@ -552,6 +552,7 @@ #define CAR_SATA_PLL_CFG0_SEQ_STATE __BITS(27,26) #define CAR_SATA_PLL_CFG0_SEQ_START_STATE __BIT(25) #define CAR_SATA_PLL_CFG0_SEQ_ENABLE __BIT(24) +#define CAR_SATA_PLL_CFG0_SEQ_PADPLL_SLEEP_IDDQ __BIT(13) #define CAR_SATA_PLL_CFG0_SEQ_PADPLL_PD_INPUT_VALUE __BIT(7) #define CAR_SATA_PLL_CFG0_SEQ_LANE_PD_INPUT_VALUE __BIT(6) #define CAR_SATA_PLL_CFG0_SEQ_RESET_INPUT_VALUE __BIT(5) @@ -560,6 +561,21 @@ #define CAR_SATA_PLL_CFG0_PADPLL_RESET_OVERRIDE_VALUE __BIT(1) #define CAR_SATA_PLL_CFG0_PADPLL_RESET_SWCTL __BIT(0) + +#if 0 +188#define SATA_PLL_CFG0 0x490 +189#define SATA_PLL_CFG0_PADPLL_RESET_SWCTL BIT(0) +190#define SATA_PLL_CFG0_PADPLL_USE_LOCKDET BIT(2) +191#define SATA_PLL_CFG0_SATA_SEQ_IN_SWCTL BIT(4) +192#define SATA_PLL_CFG0_SATA_SEQ_RESET_INPUT_VALUE BIT(5) +193#define SATA_PLL_CFG0_SATA_SEQ_LANE_PD_INPUT_VALUE BIT(6) +194#define SATA_PLL_CFG0_SATA_SEQ_PADPLL_PD_INPUT_VALUE BIT(7) +196#define SATA_PLL_CFG0_PADPLL_SLEEP_IDDQ BIT(13) +197#define SATA_PLL_CFG0_SEQ_ENABLE BIT(24) +#endif + + + #define CAR_SATA_PLL_CFG1_REG 0x494 #define CAR_SATA_PLL_CFG1_LANE_IDDQ2_PADPLL_RESET_DLY __BITS(31,24) #define CAR_SATA_PLL_CFG1_PADPLL_IDDQ2LANE_SLUMBER_DLY __BITS(23,16) Index: sys/arch/arm/nvidia/tegra210_xusbpad.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/nvidia/tegra210_xusbpad.c,v retrieving revision 1.10 diff -u -p -r1.10 tegra210_xusbpad.c --- sys/arch/arm/nvidia/tegra210_xusbpad.c 12 Dec 2018 09:55:34 -0000 1.10 +++ sys/arch/arm/nvidia/tegra210_xusbpad.c 12 Dec 2018 09:56:11 -0000 @@ -63,7 +63,7 @@ __KERNEL_RCSID(0, "$NetBSD: tegra210_xus #define XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_CLAMP_EN(n) __BIT((n) * 3 + 0) #define XUSB_PADCTL_USB3_PAD_MUX_REG 0x28 -#define XUSB_PADCTL_USB3_PAD_MUX_FORCE_SATA_PAD_IDDQ_DISABLE __BIT(8) +#define XUSB_PADCTL_USB3_PAD_MUX_FORCE_SATA_PAD_IDDQ_DISABLE(n) __BIT(8 + (n)) #define XUSB_PADCTL_USB3_PAD_MUX_FORCE_PCIE_PAD_IDDQ_DISABLE(n) __BIT(1 + (n)) #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADn_CTL_1_REG(n) (0x84 + (n) * 0x40) @@ -93,22 +93,31 @@ __KERNEL_RCSID(0, "$NetBSD: tegra210_xus #define XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_TRK_DONE_RESET_TIMER __BITS(25,19) #define XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_TRK_START_TIMER __BITS(18,12) +// 22.16.7.42 page 1544 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG 0x360 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_PSDIV __BITS(29,28) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_NDIV __BITS(27,20) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_MDIV __BITS(17,16) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_LOCKDET_STATUS __BIT(15) +#define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_MODE __BITS(9,8) +#define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_BYPASS_ENABLE __BIT(7) +#define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREERUN_ENABLE __BIT(6) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_PWR_OVRD __BIT(4) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_ENABLE __BIT(3) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_SLEEP __BITS(2,1) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_IDDQ __BIT(0) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG 0x364 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_CTRL __BITS(27,4) +#define XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_RESET __BIT(3) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_OVRD __BIT(2) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_DONE __BIT(1) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_EN __BIT(0) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_3_REG 0x368 +#define XUSB_PADCTL_UPHY_PLL_P0_CTL_3_LOCKDET_CTRL __BITS(27,4) +#define XUSB_PADCTL_UPHY_PLL_P0_CTL_3_LOCKDET_RESET __BIT(0) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG 0x36c +#define XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TCLKOUT_EN __BIT(28) +#define XUSB_PADCTL_UPHY_PLL_P0_CTL_4_CLKDIST_CTRL __BITS(23,20) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_EN __BIT(15) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_SEL __BITS(13,12) #define XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLKBUF_EN __BIT(8) @@ -126,6 +135,44 @@ __KERNEL_RCSID(0, "$NetBSD: tegra210_xus #define XUSB_PADCTL_UPHY_PLL_P0_CTL_10_REG 0x384 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_11_REG 0x388 +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG 0x860 +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_PSDIV __BITS(29,28) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_NDIV __BITS(27,20) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_MDIV __BITS(17,16) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_1_LOCKDET_STATUS __BIT(15) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_1_MODE __BITS(9,8) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_1_BYPASS_ENABLE __BIT(7) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREERUN_ENABLE __BIT(6) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_1_PWR_OVRD __BIT(4) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_1_ENABLE __BIT(3) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_1_SLEEP __BITS(2,1) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_1_IDDQ __BIT(0) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG 0x864 +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_CTRL __BITS(27,4) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_RESET __BIT(3) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_OVRD __BIT(2) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_DONE __BIT(1) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_EN __BIT(0) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_3_REG 0x868 +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_3_LOCKDET_CTRL __BITS(27,4) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_3_LOCKDET_RESET __BIT(0) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REG 0x86c +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_4_TCLKOUT_EN __BIT(28) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_4_CLKDIST_CTRL __BITS(23,20) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_4_TXCLKREF_EN __BIT(15) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_4_TXCLKREF_SEL __BITS(13,12) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REFCLKBUF_EN __BIT(8) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REFCLK_SEL __BITS(7,4) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_5_REG 0x870 +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_5_DCO_CTRL __BITS(23,16) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_6_REG 0x874 +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_7_REG 0x878 +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG 0x87c +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_DONE __BIT(31) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_OVRD __BIT(15) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_CLK_EN __BIT(13) +#define XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_EN __BIT(12) + #define XUSB_PADCTL_UPHY_USB3_PADn_ECTL_1_REG(n) (0xa60 + (n) * 0x40) #define XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_TX_TERM_CTRL __BITS(19,18) @@ -180,6 +227,7 @@ static const char * tegra210_xusbpad_usb static const char * tegra210_xusbpad_hsic_func[] = { "snps", "xusb" }; static const char * tegra210_xusbpad_pcie_func[] = { "pcie-x1", "usb3-ss", "sata", "pcie-x4" }; +//cf linux tegra210_pex_uphy_enable static void tegra210_xusbpad_uphy_enable_pcie(struct tegra210_xusbpad_softc *sc) { @@ -377,6 +425,156 @@ tegra210_xusbpad_lane_enable_usb2(struct delay(50); } + + +static void +tegra210_xusbpad_uphy_enable_sata(struct tegra210_xusbpad_softc *sc) +{ + uint32_t val; + int retry; + +printf("%s\n", __func__); + /* UPHY PLLs */ + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG, + __SHIFTIN(0x136, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_CTRL), + XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_CTRL); + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_5_REG, + __SHIFTIN(0x2a, XUSB_PADCTL_UPHY_PLL_S0_CTL_5_DCO_CTRL), + XUSB_PADCTL_UPHY_PLL_S0_CTL_5_DCO_CTRL); + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG, + XUSB_PADCTL_UPHY_PLL_S0_CTL_1_PWR_OVRD, 0); + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG, + XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_OVRD, 0); + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG, + XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_OVRD, 0); + + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REG, + __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REFCLK_SEL), + XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REFCLK_SEL); + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REG, + __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_S0_CTL_4_TXCLKREF_SEL), + XUSB_PADCTL_UPHY_PLL_S0_CTL_4_TXCLKREF_SEL); + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REG, + XUSB_PADCTL_UPHY_PLL_S0_CTL_4_TXCLKREF_EN, 0); + + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG, + __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_MDIV), + XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_MDIV); + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG, + __SHIFTIN(0x1e, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_NDIV), + XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_NDIV); + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG, + __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_PSDIV), + XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_PSDIV); + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG, + 0, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_IDDQ); + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG, + 0, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_SLEEP); + + delay(20); + + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REG, + XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REFCLKBUF_EN, 0); + + /* Calibration */ + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG, + XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_EN, 0); + for (retry = 10000; retry > 0; retry--) { + delay(2); + val = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG); + if ((val & XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_DONE) != 0) + break; + } + if (retry == 0) { + aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (1)\n"); + return; + } + + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG, + 0, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_EN); + for (retry = 10000; retry > 0; retry--) { + delay(2); + val = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG); + if ((val & XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_DONE) == 0) + break; + } + if (retry == 0) { + aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (2)\n"); + return; + } + + /* Enable the PLL */ + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG, + XUSB_PADCTL_UPHY_PLL_S0_CTL_1_ENABLE, 0); + for (retry = 10000; retry > 0; retry--) { + delay(2); + val = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG); + if ((val & XUSB_PADCTL_UPHY_PLL_S0_CTL_1_LOCKDET_STATUS) != 0) + break; + } + if (retry == 0) { + aprint_error_dev(sc->sc_dev, "timeout enabling UPHY PLL\n"); + return; + } + + /* RCAL */ + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG, + XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_EN, 0); + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG, + XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_CLK_EN, 0); + for (retry = 10000; retry > 0; retry--) { + delay(2); + val = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG); + if ((val & XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_DONE) != 0) + break; + } + if (retry == 0) { + aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (3)\n"); + return; + } + + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG, + 0, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_EN); + for (retry = 10000; retry > 0; retry--) { + delay(2); + val = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG); + if ((val & XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_DONE) == 0) + break; + } + if (retry == 0) { + aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (4)\n"); + return; + } + + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG, + 0, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_CLK_EN); + + tegra210_car_sata_enable_hw_control(); + + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG, + 0, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_PWR_OVRD); + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG, + 0, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_OVRD); + SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG, + 0, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_OVRD); + + delay(1); + + tegra210_car_sata_enable_hw_seq(); +} + +static void +tegra210_xusbpad_lane_enable_sata(struct tegra210_xusbpad_softc *sc, int index) +{ +printf("%s: index %d\n", __func__, index); + tegra210_xusbpad_uphy_enable_sata(sc); + + KASSERT(index == 0); + SETCLR4(sc, XUSB_PADCTL_USB3_PAD_MUX_REG, + XUSB_PADCTL_USB3_PAD_MUX_FORCE_SATA_PAD_IDDQ_DISABLE(index), 0); +} + + #define XUSBPAD_LANE(n, i, r, m, f, ef) \ { \ .name = (n), \ @@ -426,8 +624,8 @@ static const struct tegra210_xusbpad_lan XUSBPAD_LANE("pcie-6", 6, 0x28, __BITS(25,24), tegra210_xusbpad_pcie_func, tegra210_xusbpad_lane_enable_pcie), - XUSBPAD_LANE("sata-0", 0, 0x28, __BITS(31,30), tegra210_xusbpad_pcie_func, - NULL), + XUSBPAD_LANE("sata-0", 0, XUSB_PADCTL_USB3_PAD_MUX_REG, __BITS(31,30), + tegra210_xusbpad_pcie_func, tegra210_xusbpad_lane_enable_sata), }; #define XUSBPAD_PORT(n, i, r, m, im) \ @@ -479,6 +677,7 @@ tegra210_xusbpad_find_func(const struct static const struct tegra210_xusbpad_lane * tegra210_xusbpad_find_lane(const char *name) { +printf("%s: name '%s'\n", __func__, name); for (int n = 0; n < __arraycount(tegra210_xusbpad_lanes); n++) if (strcmp(tegra210_xusbpad_lanes[n].name, name) == 0) return &tegra210_xusbpad_lanes[n]; Index: sys/arch/arm/nvidia/tegra_ahcisata.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/nvidia/tegra_ahcisata.c,v retrieving revision 1.11 diff -u -p -r1.11 tegra_ahcisata.c --- sys/arch/arm/nvidia/tegra_ahcisata.c 19 Sep 2017 20:46:12 -0000 1.11 +++ sys/arch/arm/nvidia/tegra_ahcisata.c 12 Dec 2018 09:56:11 -0000 @@ -65,16 +65,38 @@ struct tegra_ahcisata_softc { struct fdtbus_reset *sc_rst_sata_cold; struct tegra_gpio_pin *sc_pin_power; + + int sc_nsupplies; + const char * const *sc_supplies; }; -static const char * const tegra_ahcisata_supplies[] = { +static const char * const tegra124_ahcisata_supplies[] = { "hvdd-supply", "vddio-supply", "avdd-supply", + "target-5v-supply", "target-12v-supply" }; +//struct tegra_ahcisata_data { +// const char *const *tad_supplynames; +// size_t tad_nsupplies; +//} +// +//static const struct of_compat_data tegra_ahci_compat_data[] = { +// { +// .compatible = "nvidia,tegra124-ahci", +// .data = &tegra124_ahcisata_data +// }, +// { +// .compatible = "nvidia,tegra210-ahci", +// .data = &tegra210_ahcisata_data +// }, +// {} +//}; + + static void tegra_ahcisata_init(struct tegra_ahcisata_softc *); static int tegra_ahcisata_init_clocks(struct tegra_ahcisata_softc *); @@ -84,7 +106,11 @@ CFATTACH_DECL_NEW(tegra_ahcisata, sizeof static int tegra_ahcisata_match(device_t parent, cfdata_t cf, void *aux) { - const char * const compatible[] = { "nvidia,tegra124-ahci", NULL }; + const char * const compatible[] = { + "nvidia,tegra124-ahci", + "nvidia,tegra210-ahci", + NULL + }; struct fdt_attach_args * const faa = aux; return of_match_compatible(faa->faa_phandle, compatible); @@ -120,6 +146,7 @@ tegra_ahcisata_attach(device_t parent, d aprint_error(": couldn't get clock sata-oob\n"); return; } +#if 0 sc->sc_clk_cml1 = fdtbus_clock_get(phandle, "cml1"); if (sc->sc_clk_cml1 == NULL) { aprint_error(": couldn't get clock cml1\n"); @@ -130,6 +157,7 @@ tegra_ahcisata_attach(device_t parent, d aprint_error(": couldn't get clock pll_e\n"); return; } +#endif sc->sc_rst_sata = fdtbus_reset_get(phandle, "sata"); if (sc->sc_rst_sata == NULL) { aprint_error(": couldn't get reset sata\n"); @@ -168,8 +196,17 @@ tegra_ahcisata_attach(device_t parent, d aprint_naive("\n"); aprint_normal(": SATA\n"); - for (n = 0; n < __arraycount(tegra_ahcisata_supplies); n++) { - const char *supply = tegra_ahcisata_supplies[n]; + sc->sc_nsupplies = 0; + sc->sc_supplies = NULL; + + const char * const compat_t124[] = { "nvidia,tegra124-ahci" , NULL }; + if (of_match_compatible(faa->faa_phandle, compat_t124)) { + sc->sc_nsupplies = __arraycount(tegra124_ahcisata_supplies); + sc->sc_supplies = tegra124_ahcisata_supplies; + } + + for (n = 0; n < sc->sc_nsupplies; n++) { + const char *supply = sc->sc_supplies[n]; reg = fdtbus_regulator_acquire(phandle, supply); if (reg == NULL) { aprint_error_dev(self, "couldn't acquire %s\n", supply); @@ -181,13 +218,36 @@ tegra_ahcisata_attach(device_t parent, d fdtbus_regulator_release(reg); } + + + + + + + + + + + + if (tegra_ahcisata_init_clocks(sc) != 0) return; tegra_xusbpad_sata_enable(); + /* Enable PHYs */ + struct fdtbus_phy *phy; + for (n = 0; (phy = fdtbus_phy_get_index(faa->faa_phandle, n)) != NULL; n++) + if (fdtbus_phy_enable(phy, true) != 0) + aprint_error_dev(self, "failed to enable PHY #%d\n", n); + tegra_ahcisata_init(sc); + + + + + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { aprint_error_dev(self, "failed to decode interrupt\n"); return; @@ -202,6 +262,7 @@ tegra_ahcisata_attach(device_t parent, d } aprint_normal_dev(self, "interrupting on %s\n", intrstr); + ahci_attach(&sc->sc); } @@ -230,6 +291,11 @@ tegra_ahcisata_init(struct tegra_ahcisat tegra_reg_set_clear(bst, bsh, TEGRA_SATA_AUX_MISC_CNTL_1_REG, 0, TEGRA_SATA_AUX_MISC_CNTL_1_SDS_SUPPORT); +// /* Program the following SATA IPFS register to enable the SATA */ +// val = readl(tegra->sata_regs + SATA_CONFIGURATION_0); +// val |= SATA_CONFIGURATION_0_EN_FPCI; +// writel(val, tegra->sata_regs + SATA_CONFIGURATION_0); + /* Enable IFPS device block */ tegra_reg_set_clear(bst, bsh, TEGRA_SATA_CONFIGURATION_REG, TEGRA_SATA_CONFIGURATION_EN_FPCI, 0); @@ -270,9 +336,24 @@ tegra_ahcisata_init(struct tegra_ahcisat TEGRA_T_SATA0_CFG1_IO_SPACE, 0); + + +// /* +/// * Program the following SATA IPFS registers to allow SW accesses to +// * SATA's MMIO register range. +// */ +// val = readl(tegra->sata_regs + SATA_FPCI_BAR5); +// val &= ~(SATA_FPCI_BAR5_START_MASK | SATA_FPCI_BAR5_ACCESS_TYPE); +// val |= SATA_FPCI_BAR5_START | SATA_FPCI_BAR5_ACCESS_TYPE; +// writel(val, tegra->sata_regs + SATA_FPCI_BAR5); + + + /* MMIO setup */ bus_space_write_4(bst, bsh, TEGRA_SATA_FPCI_BAR5_REG, __SHIFTIN(0x10000, TEGRA_SATA_FPCI_BAR_START)); + + bus_space_write_4(bst, bsh, TEGRA_T_SATA0_CFG9_REG, __SHIFTIN(0x8000, TEGRA_T_SATA0_CFG9_BASE_ADDRESS)); @@ -306,6 +387,9 @@ tegra_ahcisata_init_clocks(struct tegra_ return error; } + + // Linux does this before "Assert resets" + /* Ungate SAX partition in the PMC */ tegra_pmc_power(PMC_PARTID_SAX, true); delay(20); @@ -325,11 +409,13 @@ tegra_ahcisata_init_clocks(struct tegra_ aprint_error_dev(self, "couldn't enable sata-oob: %d\n", error); return error; } +#if 0 error = clk_enable(sc->sc_clk_cml1); if (error) { aprint_error_dev(self, "couldn't enable cml1: %d\n", error); return error; } +#endif /* De-assert resets */ fdtbus_reset_deassert(sc->sc_rst_sata); Index: sys/arch/arm/nvidia/tegra_var.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/nvidia/tegra_var.h,v retrieving revision 1.44 diff -u -p -r1.44 tegra_var.h --- sys/arch/arm/nvidia/tegra_var.h 18 Oct 2018 09:01:53 -0000 1.44 +++ sys/arch/arm/nvidia/tegra_var.h 12 Dec 2018 09:56:11 -0000 @@ -55,6 +55,8 @@ void tegra_pmc_hdmi_enable(void); void tegra210_car_xusbio_enable_hw_control(void); void tegra210_car_xusbio_enable_hw_seq(void); +void tegra210_car_sata_enable_hw_control(void); +void tegra210_car_sata_enable_hw_seq(void); uint32_t tegra_fuse_read(u_int); @@ -85,6 +87,10 @@ static void inline tegra_reg_set_clear(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t o, uint32_t set_mask, uint32_t clr_mask) { +// KASSERTMSG((set_mask & clr_mask) == 0 && (set_mask | clr_mask) != 0, +// "set_mask %x clr_mask %x -> %x/%x @ %p", set_mask, clr_mask, +// set_mask & clr_mask, set_mask | clr_mask, +// __builtin_return_address(0)); const uint32_t old = bus_space_read_4(bst, bsh, o); const uint32_t new = set_mask | (old & ~clr_mask); if (old != new) {