diff --git a/sys/arch/arm/nvidia/tegra_ahcisata.c b/sys/arch/arm/nvidia/tegra_ahcisata.c index df98132ec5b8..5987d59c7849 100644 --- a/sys/arch/arm/nvidia/tegra_ahcisata.c +++ b/sys/arch/arm/nvidia/tegra_ahcisata.c @@ -65,16 +65,37 @@ struct tegra_ahcisata_softc { struct fdtbus_reset *sc_rst_sata_cold; struct tegra_gpio_pin *sc_pin_power; + int sc_nsupplies; + char *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 +105,11 @@ CFATTACH_DECL_NEW(tegra_ahcisata, sizeof(struct tegra_ahcisata_softc), 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); @@ -168,8 +193,16 @@ tegra_ahcisata_attach(device_t parent, device_t self, void *aux) 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; + + if (of_match_compatible(faa->faa_phandle, "nvidia,tegra124-ahci") { + sc->sc_nsupplies = _arraycount(tegra_ahcisata_supplies) + sc->sc_supplies = tegra_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,6 +214,18 @@ tegra_ahcisata_attach(device_t parent, device_t self, void *aux) fdtbus_regulator_release(reg); } + + + + + + + + + + + + if (tegra_ahcisata_init_clocks(sc) != 0) return; @@ -188,6 +233,17 @@ tegra_ahcisata_attach(device_t parent, device_t self, void *aux) tegra_ahcisata_init(sc); + + + + + + + + + + + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { aprint_error_dev(self, "failed to decode interrupt\n"); return; @@ -230,6 +286,11 @@ tegra_ahcisata_init(struct tegra_ahcisata_softc *sc) 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 +331,24 @@ tegra_ahcisata_init(struct tegra_ahcisata_softc *sc) 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 +382,9 @@ tegra_ahcisata_init_clocks(struct tegra_ahcisata_softc *sc) return error; } + + // Linux does this before "Assert resets" + /* Ungate SAX partition in the PMC */ tegra_pmc_power(PMC_PARTID_SAX, true); delay(20);