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 13 Dec 2018 10:55:55 -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,20 @@ static const char *mux_hda_p[] = { "PLL_P", "PLL_C2", "PLL_C", "PLL_C4_OUT0", NULL, "PLL_C4_OUT1", "CLK_M", "PLL_C4_OUT2" }; +#if 0 +SATA_OOB_CLK_SRC: 000 = pllP_out0, 001 = pllC4_out0, 010 = pllC_out0, 011 = +pllC4_out1, 101 = pllC4_out2,110 = clk_m +0 = PLLP_OUT0 +1 = PLLC4_OUT0 +2 = PLLC_OUT0 +3 = PLLC4_OUT1 +5 = PLLC4_OUT2 +6 = CLK_M +#endif + +static const char *mux_sata_p[] = + { "PLL_P", NULL, "PLL_C", NULL, NULL, NULL, "CLK_M" }; + static struct tegra_clk tegra210_car_clocks[] = { CLK_FIXED("CLK_M", TEGRA210_REF_FREQ), @@ -536,6 +552,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 +618,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 +664,11 @@ 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), + + CLK_GATE_SIMPLE("MOD_SATA", "DIV_SATA", CAR_CLKSRC_SATA_REG, __BIT(24)) }; struct tegra210_init_parent { @@ -661,6 +694,9 @@ 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 }, + { "MOD_SATA", NULL, 0, 1 } }; struct tegra210_car_rst { @@ -848,6 +884,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 +913,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 +1459,7 @@ tegra210_car_clock_set_rate_div(struct t return EINVAL; } break; + // XXXNH default: if (rate) { raw_div = (parent_rate / rate) * 2; @@ -1681,3 +1721,38 @@ 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); } + +// tegra210_sata_pll_hw_control_enable +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; + + // linux SATA_PLL_CFG0 + 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); +} + +// tegra210_sata_pll_hw_sequence_start +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); +} +