ARM: Enhance common Nvidia Tegra drivers by support for Tegra210 SoC.

MFC after:	4 weeks
This commit is contained in:
Michal Meloun 2018-01-04 12:50:12 +01:00 committed by Michal Meloun
parent 9bc6c7219a
commit b9cbd68d1c
17 changed files with 4009 additions and 566 deletions

View File

@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-apbmisc", 1},
{"nvidia,tegra210-apbmisc", 1},
{NULL, 0}
};

View File

@ -57,54 +57,14 @@ __FBSDID("$FreeBSD$");
#include <arm/nvidia/tegra_efuse.h>
#include <arm/nvidia/tegra_pmc.h>
#define AHCI_WR4(_sc, _r, _v) bus_write_4((_sc)->ctlr.r_mem, (_r), (_v))
#define AHCI_RD4(_sc, _r) bus_read_4((_sc)->ctlr.r_mem, (_r))
#define SATA_WR4(_sc, _r, _v) bus_write_4((_sc)->sata_mem, (_r), (_v))
#define SATA_RD4(_sc, _r) bus_read_4((_sc)->sata_mem, (_r))
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-ahci", 1},
{NULL, 0}
};
struct tegra_ahci_sc {
struct ahci_controller ctlr; /* Must be first */
device_t dev;
struct resource *sata_mem;
clk_t clk_sata;
clk_t clk_sata_oob;
clk_t clk_pll_e;
clk_t clk_cml;
hwreset_t hwreset_sata;
hwreset_t hwreset_sata_oob;
hwreset_t hwreset_sata_cold;
regulator_t supply_hvdd;
regulator_t supply_vddio;
regulator_t supply_avdd;
regulator_t supply_target_5v;
regulator_t supply_target_12v;
phy_t phy;
};
struct sata_pad_calibration {
uint32_t gen1_tx_amp;
uint32_t gen1_tx_peak;
uint32_t gen2_tx_amp;
uint32_t gen2_tx_peak;
};
static const struct sata_pad_calibration tegra124_pad_calibration[] = {
{0x18, 0x04, 0x18, 0x0a},
{0x0e, 0x04, 0x14, 0x0a},
{0x0e, 0x07, 0x1a, 0x0e},
{0x14, 0x0e, 0x1a, 0x0e},
};
#define SATA_CONFIGURATION 0x180
#define SATA_CONFIGURATION_EN_FPCI (1 << 0)
#define SATA_CONFIGURATION_CLK_OVERRIDE (1U << 31)
#define SATA_CONFIGURATION_EN_FPCI (1 << 0)
#define SATA_FPCI_BAR5 0x94
#define SATA_FPCI_BAR5_START_SHIFT 4
#define SATA_FPCI_BAR_START(x) (((x) & 0xFFFFFFF) << 4)
#define SATA_FPCI_BAR_ACCESS_TYPE (1 << 0)
#define SATA_INTR_MASK 0x188
#define SATA_INTR_MASK_IP_INT_MASK (1 << 16)
@ -120,8 +80,46 @@ static const struct sata_pad_calibration tegra124_pad_calibration[] = {
#define T_SATA0_CFG_9 0x24
#define T_SATA0_CFG_9_BASE_ADDRESS_SHIFT 13
#define T_SATA0_CFG_35 0x94
#define T_SATA0_CFG_35_IDP_INDEX_MASK (0x7ff << 2)
#define T_SATA0_CFG_35_IDP_INDEX (0x2a << 2)
#define T_SATA0_AHCI_IDP1 0x98
#define T_SATA0_AHCI_IDP1_DATA 0x400040
#define T_SATA0_CFG_PHY_1 0x12c
#define T_SATA0_CFG_PHY_1_PADS_IDDQ_EN (1 << 23)
#define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN (1 << 22)
#define T_SATA0_NVOOB 0x114
#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK (0x3 << 26)
#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH (0x3 << 26)
#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK (0x3 << 24)
#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE (0x1 << 24)
#define T_SATA0_NVOOB_COMMA_CNT_MASK (0xff << 16)
#define T_SATA0_NVOOB_COMMA_CNT (0x07 << 16)
#define T_SATA0_CFG_PHY 0x120
#define T_SATA0_CFG_PHY_MASK_SQUELCH (1 << 24)
#define T_SATA0_CFG_PHY_USE_7BIT_ALIGN_DET_FOR_SPD (1 << 11)
#define T_SATA0_CFG2NVOOB_2 0x134
#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK (0x1ff << 18)
#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW (0xc << 18)
#define T_SATA0_AHCI_HBA_CAP_BKDR 0x300
#define T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ (1 << 30)
#define T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM (1 << 17)
#define T_SATA0_AHCI_HBA_CAP_BKDR_SALP (1 << 26)
#define T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP (1 << 14)
#define T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP (1 << 13)
#define T_SATA0_BKDOOR_CC 0x4a4
#define T_SATA0_BKDOOR_CC_CLASS_CODE_MASK (0xffff << 16)
#define T_SATA0_BKDOOR_CC_CLASS_CODE (0x0106 << 16)
#define T_SATA0_BKDOOR_CC_PROG_IF_MASK (0xff << 8)
#define T_SATA0_BKDOOR_CC_PROG_IF (0x01 << 8)
#define T_SATA0_CFG_SATA 0x54c
#define T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN (1 << 12)
@ -146,6 +144,11 @@ static const struct sata_pad_calibration tegra124_pad_calibration[] = {
#define T_SATA0_CHX_PHY_CTRL11 0x6d0
#define T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ (0x2800 << 16)
#define T_SATA0_CHX_PHY_CTRL17 0x6e8
#define T_SATA0_CHX_PHY_CTRL18 0x6ec
#define T_SATA0_CHX_PHY_CTRL20 0x6f4
#define T_SATA0_CHX_PHY_CTRL21 0x6f8
#define FUSE_SATA_CALIB 0x124
#define FUSE_SATA_CALIB_MASK 0x3
@ -197,42 +200,109 @@ static const struct sata_pad_calibration tegra124_pad_calibration[] = {
#define T_AHCI_PORT_BKDR_COLD_PRSN_DET (1 << 1)
#define T_AHCI_PORT_BKDR_EXT_SATA_SUPP (1 << 0)
/* AUX registers */
#define SATA_AUX_MISC_CNTL_1 0x008
#define SATA_AUX_MISC_CNTL_1_DEVSLP_OVERRIDE (1 << 17)
#define SATA_AUX_MISC_CNTL_1_SDS_SUPPORT (1 << 13)
#define SATA_AUX_MISC_CNTL_1_DESO_SUPPORT (1 << 15)
#define AHCI_WR4(_sc, _r, _v) bus_write_4((_sc)->ctlr.r_mem, (_r), (_v))
#define AHCI_RD4(_sc, _r) bus_read_4((_sc)->ctlr.r_mem, (_r))
#define SATA_WR4(_sc, _r, _v) bus_write_4((_sc)->sata_mem, (_r), (_v))
#define SATA_RD4(_sc, _r) bus_read_4((_sc)->sata_mem, (_r))
struct sata_pad_calibration {
uint32_t gen1_tx_amp;
uint32_t gen1_tx_peak;
uint32_t gen2_tx_amp;
uint32_t gen2_tx_peak;
};
static const struct sata_pad_calibration tegra124_pad_calibration[] = {
{0x18, 0x04, 0x18, 0x0a},
{0x0e, 0x04, 0x14, 0x0a},
{0x0e, 0x07, 0x1a, 0x0e},
{0x14, 0x0e, 0x1a, 0x0e},
};
struct ahci_soc;
struct tegra_ahci_sc {
struct ahci_controller ctlr; /* Must be first */
device_t dev;
struct ahci_soc *soc;
struct resource *sata_mem;
struct resource *aux_mem;
clk_t clk_sata;
clk_t clk_sata_oob;
clk_t clk_pll_e;
clk_t clk_cml;
hwreset_t hwreset_sata;
hwreset_t hwreset_sata_oob;
hwreset_t hwreset_sata_cold;
regulator_t regulators[16]; /* Safe maximum */
phy_t phy;
};
struct ahci_soc {
char **regulator_names;
int (*init)(struct tegra_ahci_sc *sc);
};
/* Tegra 124 config. */
static char *tegra124_reg_names[] = {
"hvdd-supply",
"vddio-supply",
"avdd-supply",
"target-5v-supply",
"target-12v-supply",
NULL
};
static int tegra124_ahci_init(struct tegra_ahci_sc *sc);
static struct ahci_soc tegra124_soc = {
.regulator_names = tegra124_reg_names,
.init = tegra124_ahci_init,
};
/* Tegra 210 config. */
static char *tegra210_reg_names[] = {
NULL
};
static struct ahci_soc tegra210_soc = {
.regulator_names = tegra210_reg_names,
};
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-ahci", (uintptr_t)&tegra124_soc},
{"nvidia,tegra210-ahci", (uintptr_t)&tegra210_soc},
{NULL, 0}
};
static int
get_fdt_resources(struct tegra_ahci_sc *sc, phandle_t node)
{
int rv;
int i, rv;
rv = regulator_get_by_ofw_property(sc->dev, 0, "hvdd-supply",
&sc->supply_hvdd );
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'hvdd' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "vddio-supply",
&sc->supply_vddio);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'vddio' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "avdd-supply",
&sc->supply_avdd);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'avdd' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "target-5v-supply",
&sc->supply_target_5v);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'target-5v' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "target-12v-supply",
&sc->supply_target_12v);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'target-12v' regulator\n");
return (ENXIO);
/* Regulators. */
for (i = 0; sc->soc->regulator_names[i] != NULL; i++) {
if (i >= nitems(sc->regulators)) {
device_printf(sc->dev,
"Too many regulators present in DT.\n");
return (EOVERFLOW);
}
rv = regulator_get_by_ofw_property(sc->dev, 0,
sc->soc->regulator_names[i], sc->regulators + i);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get '%s' regulator\n",
sc->soc->regulator_names[i]);
return (ENXIO);
}
}
/* Resets. */
rv = hwreset_get_by_ofw_name(sc->dev, 0, "sata", &sc->hwreset_sata );
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'sata' reset\n");
@ -251,12 +321,17 @@ get_fdt_resources(struct tegra_ahci_sc *sc, phandle_t node)
return (ENXIO);
}
/* Phy */
rv = phy_get_by_ofw_name(sc->dev, 0, "sata-0", &sc->phy);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'sata' phy\n");
return (ENXIO);
rv = phy_get_by_ofw_idx(sc->dev, 0, 0, &sc->phy);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'sata' phy\n");
return (ENXIO);
}
}
/* Clocks. */
rv = clk_get_by_ofw_name(sc->dev, 0, "sata", &sc->clk_sata);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'sata' clock\n");
@ -267,50 +342,33 @@ get_fdt_resources(struct tegra_ahci_sc *sc, phandle_t node)
device_printf(sc->dev, "Cannot get 'sata oob' clock\n");
return (ENXIO);
}
/* These are optional */
rv = clk_get_by_ofw_name(sc->dev, 0, "cml1", &sc->clk_cml);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'cml1' clock\n");
return (ENXIO);
}
if (rv != 0)
sc->clk_cml = NULL;
rv = clk_get_by_ofw_name(sc->dev, 0, "pll_e", &sc->clk_pll_e);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'pll_e' clock\n");
return (ENXIO);
}
if (rv != 0)
sc->clk_pll_e = NULL;
return (0);
}
static int
enable_fdt_resources(struct tegra_ahci_sc *sc)
{
int rv;
int i, rv;
rv = regulator_enable(sc->supply_hvdd);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable 'hvdd' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_vddio);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable 'vddio' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_avdd);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable 'avdd' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_target_5v);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'target-5v' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_target_12v);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'sc->target-12v' regulator\n");
return (rv);
/* Enable regulators. */
for (i = 0; i < nitems(sc->regulators); i++) {
if (sc->regulators[i] == NULL)
continue;
rv = regulator_enable(sc->regulators[i]);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable '%s' regulator\n",
sc->soc->regulator_names[i]);
return (rv);
}
}
/* Stop clocks */
@ -346,15 +404,19 @@ enable_fdt_resources(struct tegra_ahci_sc *sc)
device_printf(sc->dev, "Cannot enable 'sata oob' clock\n");
return (rv);
}
rv = clk_enable(sc->clk_cml);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable 'cml' clock\n");
return (rv);
if (sc->clk_cml != NULL) {
rv = clk_enable(sc->clk_cml);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable 'cml' clock\n");
return (rv);
}
}
rv = clk_enable(sc->clk_pll_e);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable 'pll e' clock\n");
return (rv);
if (sc->clk_pll_e != NULL) {
rv = clk_enable(sc->clk_pll_e);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable 'pll e' clock\n");
return (rv);
}
}
rv = hwreset_deassert(sc->hwreset_sata_cold);
@ -378,15 +440,11 @@ enable_fdt_resources(struct tegra_ahci_sc *sc)
}
static int
tegra_ahci_ctrl_init(struct tegra_ahci_sc *sc)
tegra124_ahci_init(struct tegra_ahci_sc *sc)
{
uint32_t val;
const struct sata_pad_calibration *calib;
val = SATA_RD4(sc, SATA_CONFIGURATION);
val |= SATA_CONFIGURATION_EN_FPCI;
SATA_WR4(sc, SATA_CONFIGURATION, val);
/* Pad calibration. */
val = tegra_fuse_read_4(FUSE_SATA_CALIB);
calib = tegra124_pad_calibration + (val & FUSE_SATA_CALIB_MASK);
@ -418,17 +476,118 @@ tegra_ahci_ctrl_init(struct tegra_ahci_sc *sc)
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_INDEX, 0);
/* Set device ID. */
return (0);
}
static int
tegra_ahci_ctrl_init(struct tegra_ahci_sc *sc)
{
uint32_t val;
int rv;
/* Enable SATA MMIO. */
val = SATA_RD4(sc, SATA_FPCI_BAR5);
val &= ~SATA_FPCI_BAR_START(~0);
val |= SATA_FPCI_BAR_START(0x10000);
val |= SATA_FPCI_BAR_ACCESS_TYPE;
SATA_WR4(sc, SATA_FPCI_BAR5, val);
/* Enable FPCI access */
val = SATA_RD4(sc, SATA_CONFIGURATION);
val |= SATA_CONFIGURATION_EN_FPCI;
SATA_WR4(sc, SATA_CONFIGURATION, val);
/* Recommended electrical settings for phy */
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL17, 0x55010000);
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL18, 0x55010000);
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL20, 0x1);
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL21, 0x1);
/* SQUELCH and Gen3 */
val = SATA_RD4(sc, SCFG_OFFSET + T_SATA0_CFG_PHY);
val |= T_SATA0_CFG_PHY_MASK_SQUELCH;
val &= ~T_SATA0_CFG_PHY_USE_7BIT_ALIGN_DET_FOR_SPD;
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_CFG_PHY, val);
val = SATA_RD4(sc, SCFG_OFFSET + T_SATA0_NVOOB);
val &= ~T_SATA0_NVOOB_COMMA_CNT_MASK;
val &= ~T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK;
val &= ~T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK;
val |= T_SATA0_NVOOB_COMMA_CNT;
val |= T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH;
val |= T_SATA0_NVOOB_SQUELCH_FILTER_MODE;
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_NVOOB, val);
/* Setup COMWAKE_IDLE_CNT */
val = SATA_RD4(sc, SCFG_OFFSET + T_SATA0_CFG2NVOOB_2);
val &= ~T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK;
val |= T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW;
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_CFG2NVOOB_2, val);
if (sc->soc->init != NULL) {
rv = sc->soc->init(sc);
if (rv != 0) {
device_printf(sc->dev,
"SOC specific intialization failed: %d\n", rv);
return (rv);
}
}
/* Enable backdoor programming. */
val = SATA_RD4(sc, SCFG_OFFSET + T_SATA0_CFG_SATA);
val |= T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_CFG_SATA, val);
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_BKDOOR_CC, 0x01060100);
/* Set device class and interface */
val = SATA_RD4(sc, SCFG_OFFSET + T_SATA0_BKDOOR_CC);
val &= ~T_SATA0_BKDOOR_CC_CLASS_CODE_MASK;
val &= ~T_SATA0_BKDOOR_CC_PROG_IF_MASK;
val |= T_SATA0_BKDOOR_CC_CLASS_CODE;
val |= T_SATA0_BKDOOR_CC_PROG_IF;
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_BKDOOR_CC, val);
/* Enable LPM capabilities */
val = SATA_RD4(sc, SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR);
val |= T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP;
val |= T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP;
val |= T_SATA0_AHCI_HBA_CAP_BKDR_SALP;
val |= T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM;
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR, val);
/* Disable backdoor programming. */
val = SATA_RD4(sc, SCFG_OFFSET + T_SATA0_CFG_SATA);
val &= ~T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_CFG_SATA, val);
/* SATA Second Level Clock Gating */
val = SATA_RD4(sc, SCFG_OFFSET + T_SATA0_CFG_35);
val &= ~T_SATA0_CFG_35_IDP_INDEX_MASK;
val |= T_SATA0_CFG_35_IDP_INDEX;
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_CFG_35, val);
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_AHCI_IDP1, 0x400040);
val = SATA_RD4(sc, SCFG_OFFSET + T_SATA0_CFG_PHY_1);
val |= T_SATA0_CFG_PHY_1_PADS_IDDQ_EN;
val |= T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN;
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_CFG_PHY_1, val);
/*
* Indicate Sata only has the capability to enter DevSleep
* from slumber link.
*/
if (sc->aux_mem != NULL) {
val = bus_read_4(sc->aux_mem, SATA_AUX_MISC_CNTL_1);
val |= SATA_AUX_MISC_CNTL_1_DESO_SUPPORT;
bus_write_4(sc->aux_mem, SATA_AUX_MISC_CNTL_1, val);
}
/* Enable IPFS Clock Gating */
val = SATA_RD4(sc, SCFG_OFFSET + SATA_CONFIGURATION);
val &= ~SATA_CONFIGURATION_CLK_OVERRIDE;
SATA_WR4(sc, SCFG_OFFSET + SATA_CONFIGURATION, val);
/* Enable IO & memory access, bus master mode */
val = SATA_RD4(sc, SCFG_OFFSET + T_SATA0_CFG_1);
val |= T_SATA0_CFG_1_IO_SPACE;
@ -437,10 +596,8 @@ tegra_ahci_ctrl_init(struct tegra_ahci_sc *sc)
val |= T_SATA0_CFG_1_SERR;
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_CFG_1, val);
/* SATA MMIO. */
SATA_WR4(sc, SATA_FPCI_BAR5, 0x10000 << SATA_FPCI_BAR5_START_SHIFT);
/* AHCI bar */
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_CFG_9,
SATA_WR4(sc, SCFG_OFFSET + T_SATA0_CFG_9,
0x08000 << T_SATA0_CFG_9_BASE_ADDRESS_SHIFT);
/* Unmask interrupts. */
@ -513,6 +670,8 @@ tegra_ahci_attach(device_t dev)
sc->dev = dev;
ctlr = &sc->ctlr;
node = ofw_bus_get_node(dev);
sc->soc = (struct ahci_soc *)ofw_bus_search_compatible(dev,
compat_data)->ocd_data;
ctlr->r_rid = 0;
ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
@ -527,6 +686,12 @@ tegra_ahci_attach(device_t dev)
rv = ENXIO;
goto fail;
}
/* Aux is optionall */
rid = 2;
sc->aux_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&rid, RF_ACTIVE);
rv = get_fdt_resources(sc, node);
if (rv != 0) {
device_printf(sc->dev, "Failed to allocate FDT resource(s)\n");

View File

@ -49,23 +49,20 @@ __FBSDID("$FreeBSD$");
#include <arm/nvidia/tegra_efuse.h>
#define RD4(_sc, _r) bus_read_4((_sc)->mem_res, (_sc)->fuse_begin + (_r))
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-efuse", 1},
{NULL, 0}
};
#define FUSES_START 0x100
#define RD4(_sc, _r) bus_read_4((_sc)->mem_res, (FUSES_START + (_r)))
struct efuse_soc;
struct tegra_efuse_softc {
device_t dev;
struct resource *mem_res;
int fuse_begin;
struct efuse_soc *soc;
clk_t clk;
hwreset_t reset;
hwreset_t reset;
};
struct tegra_efuse_softc *dev_sc;
struct tegra_efuse_softc *dev_sc;
struct tegra_sku_info tegra_sku_info;
static char *tegra_rev_name[] = {
[TEGRA_REVISION_UNKNOWN] = "unknown",
@ -76,18 +73,30 @@ static char *tegra_rev_name[] = {
[TEGRA_REVISION_A04] = "A04",
};
/* Tegra30 and later */
#define FUSE_VENDOR_CODE 0x100
#define FUSE_FAB_CODE 0x104
#define FUSE_LOT_CODE_0 0x108
#define FUSE_LOT_CODE_1 0x10c
#define FUSE_WAFER_ID 0x110
#define FUSE_X_COORDINATE 0x114
#define FUSE_Y_COORDINATE 0x118
struct efuse_soc {
void (*init)(struct tegra_efuse_softc *sc,
struct tegra_sku_info *sku);
};
static void tegra124_init(struct tegra_efuse_softc *sc,
struct tegra_sku_info *sku);
struct efuse_soc tegra124_efuse_soc = {
.init = tegra124_init,
};
static void tegra210_init(struct tegra_efuse_softc *sc,
struct tegra_sku_info *sku);
struct efuse_soc tegra210_efuse_soc = {
.init = tegra210_init,
};
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-efuse", (intptr_t)&tegra124_efuse_soc},
{"nvidia,tegra210-efuse", (intptr_t)&tegra210_efuse_soc},
{NULL, 0}
};
/* ---------------------- Tegra 124 specific code & data --------------- */
#define TEGRA124_FUSE_BEGIN 0x100
#define TEGRA124_CPU_PROCESS_CORNERS 2
#define TEGRA124_GPU_PROCESS_CORNERS 2
#define TEGRA124_SOC_PROCESS_CORNERS 2
@ -128,12 +137,13 @@ static uint32_t tegra124_soc_process_speedos[][TEGRA124_SOC_PROCESS_CORNERS] =
{0, UINT_MAX},
};
static void
tegra124_rev_sku_to_speedo_ids(struct tegra_efuse_softc *sc,
struct tegra_sku_info *sku, int *threshold)
{
/* Assign to default */
/* Set default */
sku->cpu_speedo_id = 0;
sku->soc_speedo_id = 0;
sku->gpu_speedo_id = 0;
@ -180,7 +190,7 @@ tegra124_rev_sku_to_speedo_ids(struct tegra_efuse_softc *sc,
}
static void
tegra124_init_speedo(struct tegra_efuse_softc *sc, struct tegra_sku_info *sku)
tegra124_init(struct tegra_efuse_softc *sc, struct tegra_sku_info *sku)
{
int i, threshold;
@ -221,9 +231,175 @@ tegra124_init_speedo(struct tegra_efuse_softc *sc, struct tegra_sku_info *sku)
sku->gpu_process_id = i;
}
/* ----------------- End of Tegra 124 specific code & data --------------- */
/* -------------------- Tegra 201 specific code & data ------------------- */
#define TEGRA210_CPU_PROCESS_CORNERS 2
#define TEGRA210_GPU_PROCESS_CORNERS 2
#define TEGRA210_SOC_PROCESS_CORNERS 3
#define TEGRA210_FUSE_SKU_INFO 0x010
#define TEGRA210_FUSE_CPU_SPEEDO_0 0x014
#define TEGRA210_FUSE_CPU_IDDQ 0x018
#define TEGRA210_FUSE_FT_REV 0x028
#define TEGRA210_FUSE_CPU_SPEEDO_1 0x02c
#define TEGRA210_FUSE_CPU_SPEEDO_2 0x030
#define TEGRA210_FUSE_SOC_SPEEDO_0 0x034
#define TEGRA210_FUSE_SOC_SPEEDO_1 0x038
#define TEGRA210_FUSE_SOC_SPEEDO_2 0x03c
#define TEGRA210_FUSE_SOC_IDDQ 0x040
#define TEGRA210_FUSE_GPU_IDDQ 0x128
#define TEGRA210_FUSE_SPARE 0x270
enum {
TEGRA210_THRESHOLD_INDEX_0,
TEGRA210_THRESHOLD_INDEX_1,
TEGRA210_THRESHOLD_INDEX_COUNT,
};
static uint32_t tegra210_cpu_process_speedos[][TEGRA210_CPU_PROCESS_CORNERS] =
{
{2119, UINT_MAX},
{2119, UINT_MAX},
};
static uint32_t tegra210_gpu_process_speedos[][TEGRA210_GPU_PROCESS_CORNERS] =
{
{UINT_MAX, UINT_MAX},
{UINT_MAX, UINT_MAX},
};
static uint32_t tegra210_soc_process_speedos[][TEGRA210_SOC_PROCESS_CORNERS] =
{
{1950, 2100, UINT_MAX},
{1950, 2100, UINT_MAX},
};
static uint32_t
tegra210_get_speedo_revision(struct tegra_efuse_softc *sc)
{
uint32_t reg;
uint32_t val;
val = 0;
/* Revision i encoded in spare fields */
reg = RD4(sc, TEGRA210_FUSE_SPARE + 2 * 4);
val |= (reg & 1) << 0;
reg = RD4(sc, TEGRA210_FUSE_SPARE + 3 * 4);
val |= (reg & 1) << 1;
reg = RD4(sc, TEGRA210_FUSE_SPARE + 4 * 4);
val |= (reg & 1) << 2;
return (val);
}
static void
tegra210_rev_sku_to_speedo_ids(struct tegra_efuse_softc *sc,
struct tegra_sku_info *sku, int speedo_rev, int *threshold)
{
/* Set defaults */
sku->cpu_speedo_id = 0;
sku->soc_speedo_id = 0;
sku->gpu_speedo_id = 0;
*threshold = TEGRA210_THRESHOLD_INDEX_0;
switch (sku->sku_id) {
case 0x00: /* Eng sku */
case 0x01: /* Eng sku */
case 0x07:
case 0x17:
case 0x27:
/* Use defaults */
if (speedo_rev >= 2)
sku->gpu_speedo_id = 1;
break;
case 0x13:
if (speedo_rev >= 2)
sku->gpu_speedo_id = 1;
sku->cpu_speedo_id = 1;
break;
default:
device_printf(sc->dev, " Unknown SKU ID %d\n", sku->sku_id);
break;
}
}
static void
tegra210_init(struct tegra_efuse_softc *sc, struct tegra_sku_info *sku)
{
int i, threshold, speedo_rev;
uint32_t cpu_speedo[3], soc_speedo[3];
uint32_t cpu_iddq, soc_iddq, gpu_iddq;
cpu_speedo[0] = RD4(sc, TEGRA210_FUSE_CPU_SPEEDO_0);
cpu_speedo[1] = RD4(sc, TEGRA210_FUSE_CPU_SPEEDO_1);
cpu_speedo[2] = RD4(sc, TEGRA210_FUSE_CPU_SPEEDO_2);
soc_speedo[0] = RD4(sc, TEGRA210_FUSE_SOC_SPEEDO_0);
soc_speedo[1] = RD4(sc, TEGRA210_FUSE_SOC_SPEEDO_1);
soc_speedo[2] = RD4(sc, TEGRA210_FUSE_SOC_SPEEDO_2);
sku->cpu_iddq_value = RD4(sc, TEGRA210_FUSE_CPU_IDDQ);
sku->soc_iddq_value = RD4(sc, TEGRA210_FUSE_SOC_IDDQ);
sku->gpu_iddq_value = RD4(sc, TEGRA210_FUSE_GPU_IDDQ);
cpu_iddq = RD4(sc, TEGRA210_FUSE_CPU_IDDQ) * 4;
soc_iddq = RD4(sc, TEGRA210_FUSE_SOC_IDDQ) * 4;
gpu_iddq = RD4(sc, TEGRA210_FUSE_GPU_IDDQ) * 5;
speedo_rev = tegra210_get_speedo_revision(sc);
device_printf(sc->dev, " Speedo revision: %u\n", speedo_rev);
if (speedo_rev >= 3) {
sku->cpu_speedo_value = cpu_speedo[0];
sku->gpu_speedo_value = cpu_speedo[2];
sku->soc_speedo_value = soc_speedo[0];
} else if (speedo_rev == 2) {
sku->cpu_speedo_value =
(-1938 + (1095 * cpu_speedo[0] / 100)) / 10;
sku->gpu_speedo_value =
(-1662 + (1082 * cpu_speedo[2] / 100)) / 10;
sku->soc_speedo_value =
( -705 + (1037 * soc_speedo[0] / 100)) / 10;
} else {
sku->cpu_speedo_value = 2100;
sku->gpu_speedo_value = cpu_speedo[2] - 75;
sku->soc_speedo_value = 1900;
}
tegra210_rev_sku_to_speedo_ids(sc, sku, speedo_rev, &threshold);
for (i = 0; i < TEGRA210_SOC_PROCESS_CORNERS; i++) {
if (sku->soc_speedo_value <
tegra210_soc_process_speedos[threshold][i])
break;
}
sku->soc_process_id = i;
for (i = 0; i < TEGRA210_CPU_PROCESS_CORNERS; i++) {
if (sku->cpu_speedo_value <
tegra210_cpu_process_speedos[threshold][i])
break;
}
sku->cpu_process_id = i;
for (i = 0; i < TEGRA210_GPU_PROCESS_CORNERS; i++) {
if (sku->gpu_speedo_value <
tegra210_gpu_process_speedos[threshold][i])
break;
}
sku->gpu_process_id = i;
}
/* ----------------- End of Tegra 210 specific code & data --------------- */
uint32_t
tegra_fuse_read_4(int addr) {
if (dev_sc == NULL)
@ -274,6 +450,8 @@ tegra_efuse_attach(device_t dev)
sc = device_get_softc(dev);
sc->dev = dev;
node = ofw_bus_get_node(dev);
sc->soc = (struct efuse_soc *)ofw_bus_search_compatible(dev,
compat_data)->ocd_data;
/* Get the memory resource for the register mapping. */
rid = 0;
@ -307,9 +485,7 @@ tegra_efuse_attach(device_t dev)
goto fail;
}
/* Tegra124 specific init. */
sc->fuse_begin = TEGRA124_FUSE_BEGIN;
tegra124_init_speedo(sc, &tegra_sku_info);
sc->soc->init(sc, &tegra_sku_info);
dev_sc = sc;

View File

@ -65,8 +65,10 @@ __FBSDID("$FreeBSD$");
/* Compatible devices. */
#define TEGRA124_EHCI 1
#define TEGRA210_EHCI 2
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-ehci", (uintptr_t)TEGRA124_EHCI},
{"nvidia,tegra210-ehci", (uintptr_t)TEGRA210_EHCI},
{NULL, 0},
};

View File

@ -137,6 +137,7 @@ struct tegra_gpio_softc {
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-gpio", 1},
{"nvidia,tegra210-gpio", 1},
{NULL, 0}
};

View File

@ -205,6 +205,7 @@ __FBSDID("$FreeBSD$");
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-i2c", 1},
{"nvidia,tegra210-i2c", 1},
{NULL, 0}
};
enum tegra_i2c_xfer_type {
@ -678,7 +679,6 @@ tegra_i2c_attach(device_t dev)
sizeof(sc->bus_freq));
if (rv != sizeof(sc->bus_freq)) {
sc->bus_freq = 100000;
goto fail;
}
/* Request maximum frequency for I2C block 136MHz (408MHz / 3). */

View File

@ -38,7 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/rman.h>
#include <machine/fdt.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <machine/resource.h>
@ -78,6 +78,7 @@ static struct resource_spec lic_spec[] = {
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-ictlr", 1},
{"nvidia,tegra210-ictlr", 1},
{NULL, 0}
};

View File

@ -110,6 +110,7 @@ __FBSDID("$FreeBSD$");
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-mc", 1},
{"nvidia,tegra210-mc", 1},
{NULL, 0}
};
@ -132,7 +133,7 @@ static char *smmu_err_tbl[16] = {
"Security carveout", /* 4 */
"reserved", /* 5 */
"Invalid SMMU page", /* 6 */
"reserved", /* 7 */
"reserved", /* 7 */
};
static void
@ -173,8 +174,8 @@ tegra_mc_intr(void *arg)
err = RD4(sc, MC_ERR_STATUS);
addr = RD4(sc, MC_ERR_STATUS);
addr |= (uint64_t)(MC_ERR_ADR_HI(err)) << 32;
printf(" at 0x%012llX [%s %s %s] - %s error.\n",
addr,
printf(" at 0x%012jX [%s %s %s] - %s error.\n",
(uintmax_t)addr,
stat & MC_ERR_SWAP ? "Swap, " : "",
stat & MC_ERR_SECURITY ? "Sec, " : "",
stat & MC_ERR_RW ? "Write" : "Read",

View File

@ -179,28 +179,36 @@ __FBSDID("$FreeBSD$");
#define AFI_PEXBIAS_CTRL 0x168
/* FPCI Address space */
#define FPCI_MAP_IO 0xfdfc000000ULL
#define FPCI_MAP_TYPE0_CONFIG 0xfdfc000000ULL
#define FPCI_MAP_TYPE1_CONFIG 0xfdff000000ULL
#define FPCI_MAP_EXT_TYPE0_CONFIG 0xfe00000000ULL
#define FPCI_MAP_EXT_TYPE1_CONFIG 0xfe10000000ULL
/* Configuration space */
#define RP_VEND_XP 0x00000F00
#define RP_VEND_XP_DL_UP (1 << 30)
#define RP_VEND_XP 0x0F00
#define RP_VEND_XP_DL_UP (1 << 30)
#define RP_PRIV_MISC 0x00000FE0
#define RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xE << 0)
#define RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xF << 0)
#define RP_VEND_CTL2 0x0fa8
#define RP_VEND_CTL2_PCA_ENABLE (1 << 7)
#define RP_PRIV_MISC 0x0FE0
#define RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xE << 0)
#define RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xF << 0)
#define RP_LINK_CONTROL_STATUS 0x0090
#define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000
#define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000
/* PADS space */
#define PADS_REFCLK_CFG0 0x000c8
#define PADS_REFCLK_CFG1 0x000cc
#define RP_LINK_CONTROL_STATUS 0x00000090
#define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000
#define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000
/* Wait 50 ms (per port) for link. */
#define TEGRA_PCIE_LINKUP_TIMEOUT 50000
/* FPCI Address space */
#define FPCI_MAP_IO 0xFDFC000000ULL
#define FPCI_MAP_TYPE0_CONFIG 0xFDFC000000ULL
#define FPCI_MAP_TYPE1_CONFIG 0xFDFF000000ULL
#define FPCI_MAP_EXT_TYPE0_CONFIG 0xFE00000000ULL
#define FPCI_MAP_EXT_TYPE1_CONFIG 0xFE10000000ULL
#define TEGRA_PCIB_MSI_ENABLE
#define DEBUG
@ -224,7 +232,7 @@ __FBSDID("$FreeBSD$");
#define PCI_CFG_FUN(fun) (((fun) & 0x07) << 8)
#define PCI_CFG_BASE_REG(reg) ((reg) & 0xff)
#define PADS_WR4(_sc, _r, _v) bus_write_4((_sc)-pads_mem_res, (_r), (_v))
#define PADS_WR4(_sc, _r, _v) bus_write_4((_sc)->pads_mem_res, (_r), (_v))
#define PADS_RD4(_sc, _r) bus_read_4((_sc)->pads_mem_res, (_r))
#define AFI_WR4(_sc, _r, _v) bus_write_4((_sc)->afi_mem_res, (_r), (_v))
#define AFI_RD4(_sc, _r) bus_read_4((_sc)->afi_mem_res, (_r))
@ -246,10 +254,57 @@ static struct {
{AFI_MSI_AXI_BAR_ST, AFI_MSI_FPCI_BAR_ST, AFI_MSI_BAR_SZ}, /* MSI 9 */
};
struct pcie_soc {
char **regulator_names;
bool cml_clk;
bool pca_enable;
uint32_t pads_refclk_cfg0;
uint32_t pads_refclk_cfg1;
};
/* Tegra 124 config. */
static char *tegra124_reg_names[] = {
"avddio-pex-supply",
"dvddio-pex-supply",
"avdd-pex-pll-supply",
"hvdd-pex-supply",
"hvdd-pex-pll-e-supply",
"vddio-pex-ctl-supply",
"avdd-pll-erefe-supply",
NULL
};
static struct pcie_soc tegra124_soc = {
.regulator_names = tegra124_reg_names,
.cml_clk = true,
.pca_enable = false,
.pads_refclk_cfg0 = 0x44ac44ac,
};
/* Tegra 210 config. */
static char *tegra210_reg_names[] = {
"avdd-pll-uerefe-supply",
"hvddio-pex-supply",
"dvddio-pex-supply",
"dvdd-pex-pll-supply",
"hvdd-pex-pll-e-supply",
"vddio-pex-ctl-supply",
NULL
};
static struct pcie_soc tegra210_soc = {
.regulator_names = tegra210_reg_names,
.cml_clk = true,
.pca_enable = true,
.pads_refclk_cfg0 = 0x90b890b8,
};
/* Compatible devices. */
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-pcie", 1},
{NULL, 0},
{"nvidia,tegra124-pcie", (uintptr_t)&tegra124_soc},
{"nvidia,tegra210-pcie", (uintptr_t)&tegra210_soc},
{NULL, 0},
};
#define TEGRA_FLAG_MSI_USED 0x0001
@ -277,6 +332,7 @@ struct tegra_pcib_port {
struct tegra_pcib_softc {
struct ofw_pci_softc ofw_pci;
device_t dev;
struct pcie_soc *soc;
struct mtx mtx;
struct resource *pads_mem_res;
struct resource *afi_mem_res;
@ -297,13 +353,7 @@ struct tegra_pcib_softc {
hwreset_t hwreset_pex;
hwreset_t hwreset_afi;
hwreset_t hwreset_pcie_x;
regulator_t supply_avddio_pex;
regulator_t supply_dvddio_pex;
regulator_t supply_avdd_pex_pll;
regulator_t supply_hvdd_pex;
regulator_t supply_hvdd_pex_pll_e;
regulator_t supply_vddio_pex_ctl;
regulator_t supply_avdd_pll_erefe;
regulator_t regulators[16]; /* Safe maximum */
vm_offset_t msi_page; /* VA of MSI page */
bus_addr_t cfg_base_addr; /* base address of config */
@ -801,7 +851,7 @@ tegra_pcib_pex_ctrl(struct tegra_pcib_softc *sc, int port)
static int
tegra_pcib_enable_fdt_resources(struct tegra_pcib_softc *sc)
{
int rv;
int i, rv;
rv = hwreset_assert(sc->hwreset_pcie_x);
if (rv != 0) {
@ -821,48 +871,17 @@ tegra_pcib_enable_fdt_resources(struct tegra_pcib_softc *sc)
tegra_powergate_power_off(TEGRA_POWERGATE_PCX);
/* Power supplies. */
rv = regulator_enable(sc->supply_avddio_pex);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'avddio_pex' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_dvddio_pex);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'dvddio_pex' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_avdd_pex_pll);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'avdd-pex-pll' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_hvdd_pex);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'hvdd-pex-supply' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_hvdd_pex_pll_e);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'hvdd-pex-pll-e-supply' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_vddio_pex_ctl);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'vddio-pex-ctl' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_avdd_pll_erefe);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'avdd-pll-erefe-supply' regulator\n");
return (rv);
/* Regulators. */
for (i = 0; i < nitems(sc->regulators); i++) {
if (sc->regulators[i] == NULL)
continue;
rv = regulator_enable(sc->regulators[i]);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable '%s' regulator\n",
sc->soc->regulator_names[i]);
return (rv);
}
}
rv = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCX,
@ -883,16 +902,19 @@ tegra_pcib_enable_fdt_resources(struct tegra_pcib_softc *sc)
device_printf(sc->dev, "Cannot enable 'afi' clock\n");
return (rv);
}
rv = clk_enable(sc->clk_cml);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable 'cml' clock\n");
return (rv);
if (sc->soc->cml_clk) {
rv = clk_enable(sc->clk_cml);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable 'cml' clock\n");
return (rv);
}
}
rv = clk_enable(sc->clk_pll_e);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable 'pll_e' clock\n");
return (rv);
}
return (0);
}
@ -975,57 +997,23 @@ tegra_pcib_parse_fdt_resources(struct tegra_pcib_softc *sc, phandle_t node)
{
phandle_t child;
struct tegra_pcib_port *port;
int rv;
int i, rv;
/* Power supplies. */
rv = regulator_get_by_ofw_property(sc->dev, 0, "avddio-pex-supply",
&sc->supply_avddio_pex);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'avddio-pex' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "dvddio-pex-supply",
&sc->supply_dvddio_pex);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'dvddio-pex' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "avdd-pex-pll-supply",
&sc->supply_avdd_pex_pll);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'avdd-pex-pll' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "hvdd-pex-supply",
&sc->supply_hvdd_pex);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'hvdd-pex' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "hvdd-pex-pll-e-supply",
&sc->supply_hvdd_pex_pll_e);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'hvdd-pex-pll-e' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "vddio-pex-ctl-supply",
&sc->supply_vddio_pex_ctl);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'vddio-pex-ctl' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "avdd-pll-erefe-supply",
&sc->supply_avdd_pll_erefe);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'avdd-pll-erefe' regulator\n");
return (ENXIO);
/* Regulators. */
for (i = 0; sc->soc->regulator_names[i] != NULL; i++) {
if (i >= nitems(sc->regulators)) {
device_printf(sc->dev,
"Too many regulators present in DT.\n");
return (EOVERFLOW);
}
rv = regulator_get_by_ofw_property(sc->dev, 0,
sc->soc->regulator_names[i], sc->regulators + i);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get '%s' regulator\n",
sc->soc->regulator_names[i]);
return (ENXIO);
}
}
/* Resets. */
@ -1061,10 +1049,12 @@ tegra_pcib_parse_fdt_resources(struct tegra_pcib_softc *sc, phandle_t node)
device_printf(sc->dev, "Cannot get 'pll_e' clock\n");
return (ENXIO);
}
rv = clk_get_by_ofw_name(sc->dev, 0, "cml", &sc->clk_cml);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'cml' clock\n");
return (ENXIO);
if (sc->soc->cml_clk) {
rv = clk_get_by_ofw_name(sc->dev, 0, "cml", &sc->clk_cml);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'cml' clock\n");
return (ENXIO);
}
}
/* Ports */
@ -1196,6 +1186,14 @@ tegra_pcib_port_enable(struct tegra_pcib_softc *sc, int port_num)
reg |= AFI_PEX_CTRL_RST_L;
AFI_WR4(sc, port->afi_pex_ctrl, reg);
if (sc->soc->pca_enable) {
reg = tegra_pcib_read_config(sc->dev, 0, port->port_idx, 0,
RP_VEND_CTL2, 4);
reg |= RP_VEND_CTL2_PCA_ENABLE;
tegra_pcib_write_config(sc->dev, 0, port->port_idx, 0,
RP_VEND_CTL2, reg, 4);
}
rv = tegra_pcib_wait_for_link(sc, port);
if (bootverbose)
device_printf(sc->dev, " port %d (%d lane%s): Link is %s\n",
@ -1259,6 +1257,7 @@ tegra_pcib_enable(struct tegra_pcib_softc *sc)
device_printf(sc->dev, "Cannot enable FDT resources\n");
return (rv);
}
/* Enable PLLE control. */
reg = AFI_RD4(sc, AFI_PLLE_CONTROL);
reg &= ~AFI_PLLE_CONTROL_BYPASS_PADS2PLLE_CONTROL;
@ -1310,6 +1309,11 @@ tegra_pcib_enable(struct tegra_pcib_softc *sc)
}
}
/* Configure PCIe reference clock */
PADS_WR4(sc, PADS_REFCLK_CFG0, sc->soc->pads_refclk_cfg0);
if (sc->num_ports > 2)
PADS_WR4(sc, PADS_REFCLK_CFG1, sc->soc->pads_refclk_cfg1);
rv = hwreset_deassert(sc->hwreset_pcie_x);
if (rv != 0) {
device_printf(sc->dev, "Cannot unreset 'pci_x' reset\n");
@ -1449,6 +1453,8 @@ tegra_pcib_attach(device_t dev)
mtx_init(&sc->mtx, "msi_mtx", NULL, MTX_DEF);
node = ofw_bus_get_node(dev);
sc->soc = (struct pcie_soc *)ofw_bus_search_compatible(dev,
compat_data)->ocd_data;
rv = tegra_pcib_parse_fdt_resources(sc, node);
if (rv != 0) {

View File

@ -39,18 +39,18 @@ enum tegra_suspend_mode {
/* PARTIDs for powergate */
enum tegra_powergate_id {
TEGRA_POWERGATE_CRAIL = 0,
TEGRA_POWERGATE_TD = 1,
TEGRA_POWERGATE_TD = 1, /* Tegra124 only */
TEGRA_POWERGATE_VE = 2,
TEGRA_POWERGATE_PCX = 3,
TEGRA_POWERGATE_VDE = 4,
TEGRA_POWERGATE_L2C = 5,
TEGRA_POWERGATE_VDE = 4, /* Tegra124 only */
TEGRA_POWERGATE_L2C = 5, /* Tegra124 only */
TEGRA_POWERGATE_MPE = 6,
TEGRA_POWERGATE_HEG = 7,
TEGRA_POWERGATE_HEG = 7, /* Tegra124 only */
TEGRA_POWERGATE_SAX = 8,
TEGRA_POWERGATE_CE1 = 9,
TEGRA_POWERGATE_CE2 = 10,
TEGRA_POWERGATE_CE3 = 11,
TEGRA_POWERGATE_CELP = 12,
TEGRA_POWERGATE_CELP = 12, /* Tegra124 only */
/* */
TEGRA_POWERGATE_CE0 = 14,
TEGRA_POWERGATE_C0NC = 15,
@ -63,9 +63,13 @@ enum tegra_powergate_id {
TEGRA_POWERGATE_XUSBC = 22,
TEGRA_POWERGATE_VIC = 23,
TEGRA_POWERGATE_IRAM = 24,
TEGRA_POWERGATE_NVDEC = 25, /* Tegra210 only */
TEGRA_POWERGATE_NVJPG = 26, /* Tegra210 only */
TEGRA_POWERGATE_AUD = 27, /* Tegra210 only */
TEGRA_POWERGATE_DFD = 28, /* Tegra210 only */
TEGRA_POWERGATE_VE2 = 29, /* Tegra210 only */
/* */
TEGRA_POWERGATE_3D = 32
};
/* PARTIDs for power rails */

View File

@ -95,6 +95,7 @@ __FBSDID("$FreeBSD$");
/* Compatible devices. */
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-sdhci", 1},
{"nvidia,tegra210-sdhci", 1},
{NULL, 0},
};
@ -242,15 +243,12 @@ tegra_sdhci_probe(device_t dev)
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (ofw_bus_is_compatible(dev, "nvidia,tegra124-sdhci")) {
device_set_desc(dev, "Tegra SDHCI controller");
} else
return (ENXIO);
cd = ofw_bus_search_compatible(dev, compat_data);
if (cd->ocd_data == 0)
return (ENXIO);
node = ofw_bus_get_node(dev);
device_set_desc(dev, "Tegra SDHCI controller");
/* Allow dts to patch quirks, slots, and max-frequency. */
if ((OF_getencprop(node, "quirks", &cid, sizeof(cid))) > 0)
@ -291,25 +289,27 @@ tegra_sdhci_attach(device_t dev)
goto fail;
}
if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
NULL, tegra_sdhci_intr, sc, &sc->intr_cookie)) {
device_printf(dev, "cannot setup interrupt handler\n");
rv = ENXIO;
goto fail;
}
rv = hwreset_get_by_ofw_name(sc->dev, 0, "sdhci", &sc->reset);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'sdhci' reset\n");
goto fail;
}
rv = hwreset_deassert(sc->reset);
rv = hwreset_assert(sc->reset);
if (rv != 0) {
device_printf(dev, "Cannot unreset 'sdhci' reset\n");
device_printf(dev, "Cannot reset 'sdhci' reset\n");
goto fail;
}
gpio_pin_get_by_ofw_property(sc->dev, node, "power-gpios", &sc->gpio_power);
gpio_pin_get_by_ofw_property(sc->dev, node, "power-gpios",
&sc->gpio_power);
if (OF_hasprop(node, "assigned-clocks")) {
rv = clk_set_assigned(sc->dev, node);
if (rv != 0) {
device_printf(dev, "Cannot set assigned clocks\n");
goto fail;
}
}
rv = clk_get_by_ofw_index(dev, 0, 0, &sc->clk);
if (rv != 0) {
@ -330,8 +330,14 @@ tegra_sdhci_attach(device_t dev)
device_printf(dev, "Cannot get clock frequency\n");
goto fail;
}
DELAY(4000);
rv = hwreset_deassert(sc->reset);
if (rv != 0) {
device_printf(dev, "Cannot unreset 'sdhci' reset\n");
goto fail;
}
if (bootverbose)
device_printf(dev, " Base MMC clock: %lld\n", freq);
device_printf(dev, " Base MMC clock: %jd\n", (uintmax_t)freq);
/* Fill slot information. */
sc->max_clk = (int)freq;
@ -369,6 +375,12 @@ tegra_sdhci_attach(device_t dev)
sc->slot.max_clk = sc->max_clk;
sc->slot.caps = sc->caps;
if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
NULL, tegra_sdhci_intr, sc, &sc->intr_cookie)) {
device_printf(dev, "cannot setup interrupt handler\n");
rv = ENXIO;
goto fail;
}
rv = sdhci_init_slot(dev, &sc->slot, 0);
if (rv != 0) {
goto fail;

View File

@ -86,52 +86,55 @@ __FBSDID("$FreeBSD$");
#define TSENSOR_STATUS2_TEMP_MAX(x) (((x) >> 16) & 0xffff)
#define TSENSOR_STATUS2_TEMP_MIN(x) (((x) >> 0) & 0xffff)
/* Global registers */
#define TSENSOR_PDIV 0x1c0
#define TSENSOR_PDIV_T124 0x8888
#define TSENSOR_HOTSPOT_OFF 0x1c4
#define TSENSOR_HOTSPOT_OFF_T124 0x00060600
#define TSENSOR_TEMP1 0x1c8
#define TSENSOR_TEMP2 0x1cc
/* Readbacks */
#define READBACK_VALUE_MASK 0xff00
#define READBACK_VALUE_SHIFT 8
#define READBACK_VALUE(x) (((x) >> 8) & 0xff)
#define READBACK_ADD_HALF (1 << 7)
#define READBACK_NEGATE (1 << 0)
/* Global registers */
#define TSENSOR_PDIV 0x1c0
#define TSENSOR_HOTSPOT_OFF 0x1c4
#define TSENSOR_TEMP1 0x1c8
#define TSENSOR_TEMP2 0x1cc
/* Fuses */
#define FUSE_TSENSOR_CALIB_CP_TS_BASE_SHIFT 0
#define FUSE_TSENSOR_CALIB_CP_TS_BASE_BITS 13
#define FUSE_TSENSOR_CALIB_FT_TS_BASE_SHIFT 13
#define FUSE_TSENSOR_CALIB_FT_TS_BASE_BITS 13
#define FUSE_TSENSOR8_CALIB 0x180
#define FUSE_TSENSOR8_CALIB_CP_TS_BASE(x) (((x) >> 0) & 0x3ff)
#define FUSE_TSENSOR8_CALIB_FT_TS_BASE(x) (((x) >> 10) & 0x7ff)
/* Layout is different for Tegra124 and Tegra210 */
#define FUSE_TSENSOR_COMMON 0x180
#define TEGRA124_FUSE_COMMON_CP_TS_BASE(x) (((x) >> 0) & 0x3ff)
#define TEGRA124_FUSE_COMMON_FT_TS_BASE(x) (((x) >> 10) & 0x7ff)
#define TEGRA124_FUSE_COMMON_SHIFT_FT_SHIFT 21
#define TEGRA124_FUSE_COMMON_SHIFT_FT_BITS 5
#define TEGRA210_FUSE_COMMON_CP_TS_BASE(x) (((x) >> 11) & 0x3ff)
#define TEGRA210_FUSE_COMMON_FT_TS_BASE(x) (((x) >> 21) & 0x7ff)
#define TEGRA210_FUSE_COMMON_SHIFT_CP_SHIFT 0
#define TEGRA210_FUSE_COMMON_SHIFT_CP_BITS 6
#define TEGRA210_FUSE_COMMON_SHIFT_FT_SHIFT 6
#define TEGRA210_FUSE_COMMON_SHIFT_FT_BITS 5
/* Only for Tegra124 */
#define FUSE_SPARE_REALIGNMENT_REG 0x1fc
#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_CP_SHIFT 0
#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_CP_BITS 6
#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_SHIFT 21
#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_BITS 5
#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_CP(x) (((x) >> 0) & 0x3f)
#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT(x) (((x) >> 21) & 0x1f)
#define NOMINAL_CALIB_FT_T124 105
#define NOMINAL_CALIB_CP_T124 25
#define TEGRA124_NOMINAL_CALIB_FT 105
#define TEGRA124_NOMINAL_CALIB_CP 25
#define TEGRA210_NOMINAL_CALIB_FT 105
#define TEGRA210_NOMINAL_CALIB_CP 25
#define WR4(_sc, _r, _v) bus_write_4((_sc)->mem_res, (_r), (_v))
#define RD4(_sc, _r) bus_read_4((_sc)->mem_res, (_r))
static struct sysctl_ctx_list soctherm_sysctl_ctx;
struct soctherm_shared_cal {
uint32_t base_cp;
uint32_t base_ft;
int32_t actual_temp_cp;
int32_t actual_temp_ft;
};
struct tsensor_cfg {
uint32_t tall;
uint32_t tsample;
@ -142,10 +145,16 @@ struct tsensor_cfg {
uint32_t pdiv_ate;
};
struct soctherm_shared_cal {
uint32_t base_cp;
uint32_t base_ft;
int32_t actual_temp_cp;
int32_t actual_temp_ft;
};
struct tsensor {
char *name;
int id;
struct tsensor_cfg *cfg;
bus_addr_t sensor_base;
bus_addr_t calib_fuse;
int fuse_corr_alpha;
@ -155,6 +164,7 @@ struct tsensor {
int16_t therm_b;
};
struct soctherm_soc;
struct soctherm_softc {
device_t dev;
struct resource *mem_res;
@ -163,16 +173,22 @@ struct soctherm_softc {
clk_t tsensor_clk;
clk_t soctherm_clk;
hwreset_t reset;
hwreset_t reset;
int ntsensors;
struct soctherm_soc *soc;
struct soctherm_shared_cal shared_cal;
};
struct soctherm_soc {
void (*shared_cal)(struct soctherm_softc *sc);
uint32_t tsensor_pdiv;
uint32_t tsensor_hotspot_off;
struct tsensor_cfg *tsensor_cfg;
struct tsensor *tsensors;
int ntsensors;
};
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-soctherm", 1},
{NULL, 0},
};
/* Tegra124 config */
static struct tsensor_cfg t124_tsensor_config = {
.tall = 16300,
@ -188,7 +204,6 @@ static struct tsensor t124_tsensors[] = {
{
.name = "cpu0",
.id = TEGRA124_SOCTHERM_SENSOR_CPU,
.cfg = &t124_tsensor_config,
.sensor_base = 0x0c0,
.calib_fuse = 0x098,
.fuse_corr_alpha = 1135400,
@ -197,7 +212,6 @@ static struct tsensor t124_tsensors[] = {
{
.name = "cpu1",
.id = -1,
.cfg = &t124_tsensor_config,
.sensor_base = 0x0e0,
.calib_fuse = 0x084,
.fuse_corr_alpha = 1122220,
@ -206,7 +220,6 @@ static struct tsensor t124_tsensors[] = {
{
.name = "cpu2",
.id = -1,
.cfg = &t124_tsensor_config,
.sensor_base = 0x100,
.calib_fuse = 0x088,
.fuse_corr_alpha = 1127000,
@ -215,7 +228,6 @@ static struct tsensor t124_tsensors[] = {
{
.name = "cpu3",
.id = -1,
.cfg = &t124_tsensor_config,
.sensor_base = 0x120,
.calib_fuse = 0x12c,
.fuse_corr_alpha = 1110900,
@ -224,7 +236,6 @@ static struct tsensor t124_tsensors[] = {
{
.name = "mem0",
.id = TEGRA124_SOCTHERM_SENSOR_MEM,
.cfg = &t124_tsensor_config,
.sensor_base = 0x140,
.calib_fuse = 0x158,
.fuse_corr_alpha = 1122300,
@ -233,7 +244,6 @@ static struct tsensor t124_tsensors[] = {
{
.name = "mem1",
.id = -1,
.cfg = &t124_tsensor_config,
.sensor_base = 0x160,
.calib_fuse = 0x15c,
.fuse_corr_alpha = 1145700,
@ -242,7 +252,6 @@ static struct tsensor t124_tsensors[] = {
{
.name = "gpu",
.id = TEGRA124_SOCTHERM_SENSOR_GPU,
.cfg = &t124_tsensor_config,
.sensor_base = 0x180,
.calib_fuse = 0x154,
.fuse_corr_alpha = 1120100,
@ -251,7 +260,6 @@ static struct tsensor t124_tsensors[] = {
{
.name = "pllX",
.id = TEGRA124_SOCTHERM_SENSOR_PLLX,
.cfg = &t124_tsensor_config,
.sensor_base = 0x1a0,
.calib_fuse = 0x160,
.fuse_corr_alpha = 1106500,
@ -259,6 +267,112 @@ static struct tsensor t124_tsensors[] = {
},
};
static void tegra124_shared_cal(struct soctherm_softc *sc);
static struct soctherm_soc tegra124_soc = {
.shared_cal = tegra124_shared_cal,
.tsensor_pdiv = 0x8888,
.tsensor_hotspot_off = 0x00060600 ,
.tsensor_cfg = &t124_tsensor_config,
.tsensors = t124_tsensors,
.ntsensors = nitems(t124_tsensors),
};
/* Tegra210 config */
static struct tsensor_cfg t210_tsensor_config = {
.tall = 16300,
.tsample = 120,
.tiddq_en = 1,
.ten_count = 1,
.pdiv = 8,
.tsample_ate = 480,
.pdiv_ate = 8
};
static struct tsensor t210_tsensors[] = {
{
.name = "cpu0",
.id = TEGRA124_SOCTHERM_SENSOR_CPU,
.sensor_base = 0x0c0,
.calib_fuse = 0x098,
.fuse_corr_alpha = 1085000,
.fuse_corr_beta = 3244200,
},
{
.name = "cpu1",
.id = -1,
.sensor_base = 0x0e0,
.calib_fuse = 0x084,
.fuse_corr_alpha = 1126200,
.fuse_corr_beta = -67500,
},
{
.name = "cpu2",
.id = -1,
.sensor_base = 0x100,
.calib_fuse = 0x088,
.fuse_corr_alpha = 1098400,
.fuse_corr_beta = 2251100,
},
{
.name = "cpu3",
.id = -1,
.sensor_base = 0x120,
.calib_fuse = 0x12c,
.fuse_corr_alpha = 1108000,
.fuse_corr_beta = 602700,
},
{
.name = "mem0",
.id = TEGRA124_SOCTHERM_SENSOR_MEM,
.sensor_base = 0x140,
.calib_fuse = 0x158,
.fuse_corr_alpha = 1069200,
.fuse_corr_beta = 3549900,
},
{
.name = "mem1",
.id = -1,
.sensor_base = 0x160,
.calib_fuse = 0x15c,
.fuse_corr_alpha = 1173700,
.fuse_corr_beta = -6263600,
},
{
.name = "gpu",
.id = TEGRA124_SOCTHERM_SENSOR_GPU,
.sensor_base = 0x180,
.calib_fuse = 0x154,
.fuse_corr_alpha = 1074300,
.fuse_corr_beta = 2734900,
},
{
.name = "pllX",
.id = TEGRA124_SOCTHERM_SENSOR_PLLX,
.sensor_base = 0x1a0,
.calib_fuse = 0x160,
.fuse_corr_alpha = 1039700,
.fuse_corr_beta = 6829100,
},
};
static void tegra210_shared_cal(struct soctherm_softc *sc);
static struct soctherm_soc tegra210_soc = {
.shared_cal = tegra210_shared_cal,
.tsensor_pdiv = 0x8888,
.tsensor_hotspot_off = 0x000A0500 ,
.tsensor_cfg = &t210_tsensor_config,
.tsensors = t210_tsensors,
.ntsensors = nitems(t210_tsensors),
};
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-soctherm", (uintptr_t)&tegra124_soc},
{"nvidia,tegra210-soctherm", (uintptr_t)&tegra210_soc},
{NULL, 0},
};
/* Extract signed integer bitfield from register */
static int
extract_signed(uint32_t reg, int shift, int bits)
@ -272,35 +386,39 @@ extract_signed(uint32_t reg, int shift, int bits)
return ((int32_t)val);
}
static inline int64_t div64_s64_precise(int64_t a, int64_t b)
static inline
int64_t div64_s64_precise(int64_t a, int64_t b)
{
int64_t r, al;
al = a << 16;
r = (al * 2 + 1) / (2 * b);
return r >> 16;
return (r >> 16);
}
static void
get_shared_cal(struct soctherm_softc *sc, struct soctherm_shared_cal *cal)
tegra124_shared_cal(struct soctherm_softc *sc)
{
uint32_t val;
int calib_cp, calib_ft;
struct soctherm_shared_cal *cal;
val = tegra_fuse_read_4(FUSE_TSENSOR8_CALIB);
cal->base_cp = FUSE_TSENSOR8_CALIB_CP_TS_BASE(val);
cal->base_ft = FUSE_TSENSOR8_CALIB_FT_TS_BASE(val);
cal = &sc->shared_cal;
val = tegra_fuse_read_4(FUSE_TSENSOR_COMMON);
cal->base_cp = TEGRA124_FUSE_COMMON_CP_TS_BASE(val);
cal->base_ft = TEGRA124_FUSE_COMMON_FT_TS_BASE(val);
calib_ft = extract_signed(val,
TEGRA124_FUSE_COMMON_SHIFT_FT_SHIFT,
TEGRA124_FUSE_COMMON_SHIFT_FT_BITS);
val = tegra_fuse_read_4(FUSE_SPARE_REALIGNMENT_REG);
calib_ft = extract_signed(val,
FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_SHIFT,
FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_BITS);
calib_cp = extract_signed(val,
FUSE_SPARE_REALIGNMENT_REG_SHIFT_CP_SHIFT,
FUSE_SPARE_REALIGNMENT_REG_SHIFT_CP_BITS);
cal->actual_temp_cp = 2 * NOMINAL_CALIB_CP_T124 + calib_cp;
cal->actual_temp_ft = 2 * NOMINAL_CALIB_FT_T124 + calib_ft;
cal->actual_temp_cp = 2 * TEGRA124_NOMINAL_CALIB_CP + calib_cp;
cal->actual_temp_ft = 2 * TEGRA124_NOMINAL_CALIB_FT + calib_ft;
#ifdef DEBUG
printf("%s: base_cp: %u, base_ft: %d,"
" actual_temp_cp: %d, actual_temp_ft: %d\n",
@ -310,35 +428,70 @@ get_shared_cal(struct soctherm_softc *sc, struct soctherm_shared_cal *cal)
}
static void
tsensor_calibration(struct tsensor *sensor, struct soctherm_shared_cal *shared)
tegra210_shared_cal(struct soctherm_softc *sc)
{
uint32_t val;
int calib_cp, calib_ft;
struct soctherm_shared_cal *cal;
cal = &sc->shared_cal;
val = tegra_fuse_read_4(FUSE_TSENSOR_COMMON);
cal->base_cp = TEGRA210_FUSE_COMMON_CP_TS_BASE(val);
cal->base_ft = TEGRA210_FUSE_COMMON_FT_TS_BASE(val);
calib_ft = extract_signed(val,
TEGRA210_FUSE_COMMON_SHIFT_FT_SHIFT,
TEGRA210_FUSE_COMMON_SHIFT_FT_BITS);
calib_cp = extract_signed(val,
TEGRA210_FUSE_COMMON_SHIFT_CP_SHIFT,
TEGRA210_FUSE_COMMON_SHIFT_CP_BITS);
cal->actual_temp_cp = 2 * TEGRA210_NOMINAL_CALIB_CP + calib_cp;
cal->actual_temp_ft = 2 * TEGRA210_NOMINAL_CALIB_FT + calib_ft;
#ifdef DEBUG
printf("%s: base_cp: %u, base_ft: %d,"
" actual_temp_cp: %d, actual_temp_ft: %d\n",
__func__, cal->base_cp, cal->base_ft,
cal->actual_temp_cp, cal->actual_temp_ft);
#endif
}
static void
tsensor_calibration(struct soctherm_softc *sc, struct tsensor *sensor)
{
uint32_t val;
int mult, div, calib_cp, calib_ft;
int actual_tsensor_ft, actual_tsensor_cp, delta_sens, delta_temp;
int temp_a, temp_b;
struct tsensor_cfg *cfg;
struct soctherm_shared_cal *cal;
int64_t tmp;
cfg = sc->soc->tsensor_cfg;
cal = &sc->shared_cal;
val = tegra_fuse_read_4(sensor->calib_fuse);
calib_cp = extract_signed(val,
FUSE_TSENSOR_CALIB_CP_TS_BASE_SHIFT,
FUSE_TSENSOR_CALIB_CP_TS_BASE_BITS);
actual_tsensor_cp = shared->base_cp * 64 + calib_cp;
actual_tsensor_cp = cal->base_cp * 64 + calib_cp;
calib_ft = extract_signed(val,
FUSE_TSENSOR_CALIB_FT_TS_BASE_SHIFT,
FUSE_TSENSOR_CALIB_FT_TS_BASE_BITS);
actual_tsensor_ft = shared->base_ft * 32 + calib_ft;
actual_tsensor_ft = cal->base_ft * 32 + calib_ft;
delta_sens = actual_tsensor_ft - actual_tsensor_cp;
delta_temp = shared->actual_temp_ft - shared->actual_temp_cp;
mult = sensor->cfg->pdiv * sensor->cfg->tsample_ate;
div = sensor->cfg->tsample * sensor->cfg->pdiv_ate;
delta_temp = cal->actual_temp_ft - cal->actual_temp_cp;
mult = cfg->pdiv * cfg->tsample_ate;
div = cfg->tsample * cfg->pdiv_ate;
temp_a = div64_s64_precise((int64_t) delta_temp * (1LL << 13) * mult,
(int64_t) delta_sens * div);
tmp = (int64_t)actual_tsensor_ft * shared->actual_temp_cp -
(int64_t)actual_tsensor_cp * shared->actual_temp_ft;
tmp = (int64_t)actual_tsensor_ft * cal->actual_temp_cp -
(int64_t)actual_tsensor_cp * cal->actual_temp_ft;
temp_b = div64_s64_precise(tmp, (int64_t)delta_sens);
temp_a = div64_s64_precise((int64_t)temp_a * sensor->fuse_corr_alpha,
@ -353,31 +506,32 @@ tsensor_calibration(struct tsensor *sensor, struct soctherm_shared_cal *shared)
__func__, sensor->name, val, val & 0x1FFF, (val >> 13) & 0x1FFF,
calib_cp, calib_cp, calib_ft, calib_ft);
printf("therma: 0x%04X(%d), thermb: 0x%04X(%d)\n",
(uint16_t)sensor->therm_a, temp_a,
(uint16_t)sensor->therm_a, sensor->therm_a,
(uint16_t)sensor->therm_b, sensor->therm_b);
#endif
}
static void
soctherm_init_tsensor(struct soctherm_softc *sc, struct tsensor *sensor,
struct soctherm_shared_cal *shared_cal)
soctherm_init_tsensor(struct soctherm_softc *sc, struct tsensor *sensor)
{
struct tsensor_cfg *cfg;
uint32_t val;
tsensor_calibration(sensor, shared_cal);
cfg = sc->soc->tsensor_cfg;
tsensor_calibration(sc, sensor);
val = RD4(sc, sensor->sensor_base + TSENSOR_CONFIG0);
val |= TSENSOR_CONFIG0_STOP;
val |= TSENSOR_CONFIG0_STATUS_CLR;
WR4(sc, sensor->sensor_base + TSENSOR_CONFIG0, val);
val = TSENSOR_CONFIG0_TALL(sensor->cfg->tall);
val = TSENSOR_CONFIG0_TALL(cfg->tall);
val |= TSENSOR_CONFIG0_STOP;
WR4(sc, sensor->sensor_base + TSENSOR_CONFIG0, val);
val = TSENSOR_CONFIG1_TSAMPLE(sensor->cfg->tsample - 1);
val |= TSENSOR_CONFIG1_TIDDQ_EN(sensor->cfg->tiddq_en);
val |= TSENSOR_CONFIG1_TEN_COUNT(sensor->cfg->ten_count);
val = TSENSOR_CONFIG1_TSAMPLE(cfg->tsample - 1);
val |= TSENSOR_CONFIG1_TIDDQ_EN(cfg->tiddq_en);
val |= TSENSOR_CONFIG1_TEN_COUNT(cfg->ten_count);
val |= TSENSOR_CONFIG1_TEMP_ENABLE;
WR4(sc, sensor->sensor_base + TSENSOR_CONFIG1, val);
@ -406,13 +560,13 @@ soctherm_convert_raw(uint32_t val)
{
int32_t t;
t = ((val & READBACK_VALUE_MASK) >> READBACK_VALUE_SHIFT) * 1000;
t = READBACK_VALUE(val) * 1000;
if (val & READBACK_ADD_HALF)
t += 500;
if (val & READBACK_NEGATE)
t *= -1;
return t;
return (t);
}
static int
@ -422,7 +576,7 @@ soctherm_read_temp(struct soctherm_softc *sc, struct tsensor *sensor, int *temp)
uint32_t val;
/* wait for valid sample */
for (timeout = 1000; timeout > 0; timeout--) {
for (timeout = 100; timeout > 0; timeout--) {
val = RD4(sc, sensor->sensor_base + TSENSOR_STATUS1);
if ((val & TSENSOR_STATUS1_TEMP_VALID) != 0)
break;
@ -443,7 +597,7 @@ soctherm_read_temp(struct soctherm_softc *sc, struct tsensor *sensor, int *temp)
RD4(sc, sensor->sensor_base + TSENSOR_STATUS2)
);
#endif
return 0;
return (0);
}
static int
@ -456,14 +610,16 @@ soctherm_get_temp(device_t dev, device_t cdev, uintptr_t id, int *val)
/* The direct sensor map starts at 0x100 */
if (id >= 0x100) {
id -= 0x100;
if (id >= sc->ntsensors)
if (id >= sc->soc->ntsensors)
return (ERANGE);
return(soctherm_read_temp(sc, sc->tsensors + id, val));
return(soctherm_read_temp(sc, sc->soc->tsensors + id, val));
}
/* Linux (DT) compatible thermal zones */
for (i = 0; i < sc->ntsensors; i++) {
if (sc->tsensors->id == id)
return(soctherm_read_temp(sc, sc->tsensors + id, val));
for (i = 0; i < sc->soc->ntsensors; i++) {
if (sc->soc->tsensors->id == id) {
return(soctherm_read_temp(sc, sc->soc->tsensors + id,
val));
}
}
return (ERANGE);
}
@ -483,9 +639,9 @@ soctherm_sysctl_temperature(SYSCTL_HANDLER_ARGS)
sc = arg1;
id = arg2;
if (id >= sc->ntsensors)
if (id >= sc->soc->ntsensors)
return (ERANGE);
rv = soctherm_read_temp(sc, sc->tsensors + id, &val);
rv = soctherm_read_temp(sc, sc->soc->tsensors + id, &val);
if (rv != 0)
return (rv);
@ -510,9 +666,9 @@ soctherm_init_sysctl(struct soctherm_softc *sc)
return (ENXIO);
/* Add sensors */
for (i = sc->ntsensors - 1; i >= 0; i--) {
for (i = sc->soc->ntsensors - 1; i >= 0; i--) {
tmp = SYSCTL_ADD_PROC(&soctherm_sysctl_ctx,
SYSCTL_CHILDREN(oid), OID_AUTO, sc->tsensors[i].name,
SYSCTL_CHILDREN(oid), OID_AUTO, sc->soc->tsensors[i].name,
CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, sc, i,
soctherm_sysctl_temperature, "IK", "SoC Temperature");
if (tmp == NULL)
@ -542,10 +698,11 @@ soctherm_attach(device_t dev)
struct soctherm_softc *sc;
phandle_t node;
int i, rid, rv;
struct soctherm_shared_cal shared_calib;
sc = device_get_softc(dev);
sc->dev = dev;
sc->soc = (struct soctherm_soc *)ofw_bus_search_compatible(dev,
compat_data)->ocd_data;
node = ofw_bus_get_node(sc->dev);
rid = 0;
@ -610,16 +767,13 @@ soctherm_attach(device_t dev)
goto fail;
}
/* Tegra 124 */
sc->tsensors = t124_tsensors;
sc->ntsensors = nitems(t124_tsensors);
get_shared_cal(sc, &shared_calib);
sc->soc->shared_cal(sc);
WR4(sc, TSENSOR_PDIV, TSENSOR_PDIV_T124);
WR4(sc, TSENSOR_HOTSPOT_OFF, TSENSOR_HOTSPOT_OFF_T124);
WR4(sc, TSENSOR_PDIV, sc->soc->tsensor_pdiv);
WR4(sc, TSENSOR_HOTSPOT_OFF, sc->soc->tsensor_hotspot_off);
for (i = 0; i < sc->ntsensors; i++)
soctherm_init_tsensor(sc, sc->tsensors + i, &shared_calib);
for (i = 0; i < sc->soc->ntsensors; i++)
soctherm_init_tsensor(sc, sc->soc->tsensors + i);
rv = soctherm_init_sysctl(sc);
if (rv != 0) {

View File

@ -155,7 +155,8 @@ static struct uart_class tegra_uart_class = {
/* Compatible devices. */
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-uart", (uintptr_t)&tegra_uart_class},
{NULL, (uintptr_t)NULL},
{"nvidia,tegra210-uart", (uintptr_t)&tegra_uart_class},
{NULL, (uintptr_t)NULL},
};
UART_FDT_CLASS(compat_data);
@ -190,7 +191,6 @@ tegra_uart_probe(device_t dev)
if (cd->ocd_data == 0)
return (ENXIO);
sc->ns8250_base.base.sc_class = (struct uart_class *)cd->ocd_data;
rv = hwreset_get_by_ofw_name(dev, 0, "serial", &sc->reset);
if (rv != 0) {
device_printf(dev, "Cannot get 'serial' reset\n");
@ -201,7 +201,6 @@ tegra_uart_probe(device_t dev)
device_printf(dev, "Cannot unreset 'serial' reset\n");
return (ENXIO);
}
node = ofw_bus_get_node(dev);
shift = uart_fdt_get_shift1(node);
rv = clk_get_by_ofw_index(dev, 0, 0, &sc->clk);

View File

@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <machine/bus.h>
#include <machine/fdt.h>
#include <dev/extres/clk/clk.h>
#include <dev/extres/hwreset/hwreset.h>
@ -291,6 +290,7 @@ struct usbphy_softc {
};
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra210-usb-phy", 1},
{"nvidia,tegra30-usb-phy", 1},
{NULL, 0},
};

View File

@ -265,15 +265,11 @@ struct tegra_xusb_fw_hdr {
uint8_t padding[137]; /* Pad to 256 bytes */
};
/* Compatible devices. */
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-xusb", 1},
{NULL, 0}
};
struct xhci_soc;
struct tegra_xhci_softc {
struct xhci_softc xhci_softc;
device_t dev;
struct xhci_soc *soc;
struct mtx mtx;
struct resource *mem_res_fpci;
struct resource *mem_res_ipfs;
@ -288,26 +284,86 @@ struct tegra_xhci_softc {
clk_t clk_xusb_fs_src;
hwreset_t hwreset_xusb_host;
hwreset_t hwreset_xusb_ss;
regulator_t supply_avddio_pex;
regulator_t supply_dvddio_pex;
regulator_t supply_avdd_usb;
regulator_t supply_avdd_pll_utmip;
regulator_t supply_avdd_pll_erefe;
regulator_t supply_avdd_usb_ss_pll;
regulator_t supply_hvdd_usb_ss;
regulator_t supply_hvdd_usb_ss_pll_e;
phy_t phy_usb2_0;
phy_t phy_usb2_1;
phy_t phy_usb2_2;
phy_t phy_usb3_0;
regulator_t regulators[16]; /* Safe maximum */
phy_t phys[8]; /* Safe maximum */
struct intr_config_hook irq_hook;
bool xhci_inited;
char *fw_name;
vm_offset_t fw_vaddr;
vm_size_t fw_size;
};
struct xhci_soc {
char *fw_name;
char **regulator_names;
char **phy_names;
};
/* Tegra 124 config */
static char *tegra124_reg_names[] = {
"avddio-pex-supply",
"dvddio-pex-supply",
"avdd-usb-supply",
"avdd-pll-utmip-supply",
"avdd-pll-erefe-supply",
"avdd-usb-ss-pll-supply",
"hvdd-usb-ss-supply",
"hvdd-usb-ss-pll-e-supply",
NULL
};
static char *tegra124_phy_names[] = {
"usb2-0",
"usb2-1",
"usb2-2",
"usb3-0",
NULL
};
static struct xhci_soc tegra124_soc =
{
.fw_name = "tegra124_xusb_fw",
.regulator_names = tegra124_reg_names,
.phy_names = tegra124_phy_names,
};
/* Tegra 210 config */
static char *tegra210_reg_names[] = {
"dvddio-pex-supply",
"hvddio-pex-supply",
"avdd-usb-supply",
"avdd-pll-utmip-supply",
"avdd-pll-uerefe-supply",
"dvdd-usb-ss-pll-supply",
"hvdd-usb-ss-pll-e-supply",
NULL
};
static char *tegra210_phy_names[] = {
"usb2-0",
"usb2-1",
"usb2-2",
"usb2-3",
"usb3-0",
"usb3-1",
NULL
};
static struct xhci_soc tegra210_soc =
{
.fw_name = "tegra210_xusb_fw",
.regulator_names = tegra210_reg_names,
.phy_names = tegra210_phy_names,
};
/* Compatible devices. */
static struct ofw_compat_data compat_data[] = {
{"nvidia,tegra124-xusb", (uintptr_t)&tegra124_soc},
{"nvidia,tegra210-xusb", (uintptr_t)&tegra210_soc},
{NULL, 0}
};
static uint32_t
CSB_RD4(struct tegra_xhci_softc *sc, uint32_t addr)
{
@ -327,63 +383,23 @@ CSB_WR4(struct tegra_xhci_softc *sc, uint32_t addr, uint32_t val)
static int
get_fdt_resources(struct tegra_xhci_softc *sc, phandle_t node)
{
int rv;
int i, rv;
rv = regulator_get_by_ofw_property(sc->dev, 0, "avddio-pex-supply",
&sc->supply_avddio_pex);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'avddio-pex' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "dvddio-pex-supply",
&sc->supply_dvddio_pex);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'dvddio-pex' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "avdd-usb-supply",
&sc->supply_avdd_usb);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'avdd-usb' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "avdd-pll-utmip-supply",
&sc->supply_avdd_pll_utmip);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'avdd-pll-utmip' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "avdd-pll-erefe-supply",
&sc->supply_avdd_pll_erefe);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'avdd-pll-erefe' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "avdd-usb-ss-pll-supply",
&sc->supply_avdd_usb_ss_pll);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'avdd-usb-ss-pll' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0, "hvdd-usb-ss-supply",
&sc->supply_hvdd_usb_ss);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'hvdd-usb-ss' regulator\n");
return (ENXIO);
}
rv = regulator_get_by_ofw_property(sc->dev, 0,
"hvdd-usb-ss-pll-e-supply", &sc->supply_hvdd_usb_ss_pll_e);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get 'hvdd-usb-ss-pll-e' regulator\n");
return (ENXIO);
/* Regulators. */
for (i = 0; sc->soc->regulator_names[i] != NULL; i++) {
if (i >= nitems(sc->regulators)) {
device_printf(sc->dev,
"Too many regulators present in DT.\n");
return (EOVERFLOW);
}
rv = regulator_get_by_ofw_property(sc->dev, 0,
sc->soc->regulator_names[i], sc->regulators + i);
if (rv != 0) {
device_printf(sc->dev,
"Cannot get '%s' regulator\n",
sc->soc->regulator_names[i]);
return (ENXIO);
}
}
rv = hwreset_get_by_ofw_name(sc->dev, 0, "xusb_host",
@ -399,25 +415,20 @@ get_fdt_resources(struct tegra_xhci_softc *sc, phandle_t node)
return (ENXIO);
}
rv = phy_get_by_ofw_name(sc->dev, 0, "usb2-0", &sc->phy_usb2_0);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'usb2-0' phy\n");
return (ENXIO);
}
rv = phy_get_by_ofw_name(sc->dev, 0, "usb2-1", &sc->phy_usb2_1);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'usb2-1' phy\n");
return (ENXIO);
}
rv = phy_get_by_ofw_name(sc->dev, 0, "usb2-2", &sc->phy_usb2_2);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'usb2-2' phy\n");
return (ENXIO);
}
rv = phy_get_by_ofw_name(sc->dev, 0, "usb3-0", &sc->phy_usb3_0);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'usb3-0' phy\n");
return (ENXIO);
/* Phys. */
for (i = 0; sc->soc->phy_names[i] != NULL; i++) {
if (i >= nitems(sc->phys)) {
device_printf(sc->dev,
"Too many phys present in DT.\n");
return (EOVERFLOW);
}
rv = phy_get_by_ofw_name(sc->dev, 0, sc->soc->phy_names[i],
sc->phys + i);
if (rv != 0 && rv != ENOENT) {
device_printf(sc->dev, "Cannot get '%s' phy.\n",
sc->soc->phy_names[i]);
return (ENXIO);
}
}
rv = clk_get_by_ofw_name(sc->dev, 0, "xusb_host",
@ -450,8 +461,8 @@ get_fdt_resources(struct tegra_xhci_softc *sc, phandle_t node)
device_printf(sc->dev, "Cannot get 'xusb_fs_src' clock\n");
return (ENXIO);
}
rv = clk_get_by_ofw_index_prop(sc->dev, 0, "freebsd,clock-xusb-gate", 0,
&sc->clk_xusb_gate);
/* Clock xusb_gate is missing in mainstream DT */
rv = clk_get_by_name(sc->dev, "xusb_gate", &sc->clk_xusb_gate);
if (rv != 0) {
device_printf(sc->dev, "Cannot get 'xusb_gate' clock\n");
return (ENXIO);
@ -462,7 +473,7 @@ get_fdt_resources(struct tegra_xhci_softc *sc, phandle_t node)
static int
enable_fdt_resources(struct tegra_xhci_softc *sc)
{
int rv;
int i, rv;
rv = hwreset_assert(sc->hwreset_xusb_host);
if (rv != 0) {
@ -475,53 +486,17 @@ enable_fdt_resources(struct tegra_xhci_softc *sc)
return (rv);
}
rv = regulator_enable(sc->supply_avddio_pex);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'avddio_pex' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_dvddio_pex);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'dvddio_pex' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_avdd_usb);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'avdd_usb' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_avdd_pll_utmip);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'avdd_pll_utmip-5v' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_avdd_pll_erefe);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'avdd_pll_erefe' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_avdd_usb_ss_pll);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'avdd_usb_ss_pll' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_hvdd_usb_ss);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'hvdd_usb_ss' regulator\n");
return (rv);
}
rv = regulator_enable(sc->supply_hvdd_usb_ss_pll_e);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable 'hvdd_usb_ss_pll_e' regulator\n");
return (rv);
/* Regulators. */
for (i = 0; i < nitems(sc->regulators); i++) {
if (sc->regulators[i] == NULL)
continue;
rv = regulator_enable(sc->regulators[i]);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable '%s' regulator\n",
sc->soc->regulator_names[i]);
return (rv);
}
}
/* Power off XUSB host and XUSB SS domains. */
@ -583,25 +558,16 @@ enable_fdt_resources(struct tegra_xhci_softc *sc)
return (rv);
}
rv = phy_enable(sc->phy_usb2_0);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable USB2_0 phy\n");
return (rv);
}
rv = phy_enable(sc->phy_usb2_1);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable USB2_1 phy\n");
return (rv);
}
rv = phy_enable(sc->phy_usb2_2);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable USB2_2 phy\n");
return (rv);
}
rv = phy_enable(sc->phy_usb3_0);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable USB3_0 phy\n");
return (rv);
/* Phys. */
for (i = 0; i < nitems(sc->phys); i++) {
if (sc->phys[i] == NULL)
continue;
rv = phy_enable(sc->phys[i]);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable '%s' phy\n",
sc->soc->phy_names[i]);
return (rv);
}
}
return (0);
@ -797,7 +763,7 @@ load_fw(struct tegra_xhci_softc *sc)
return (0);
}
fw = firmware_get(sc->fw_name);
fw = firmware_get(sc->soc->fw_name);
if (fw == NULL) {
device_printf(sc->dev, "Cannot read xusb firmware\n");
return (ENOENT);
@ -997,7 +963,8 @@ tegra_xhci_attach(device_t dev)
sc = device_get_softc(dev);
sc->dev = dev;
sc->fw_name = "tegra124_xusb_fw";
sc->soc = (struct xhci_soc *)ofw_bus_search_compatible(dev,
compat_data)->ocd_data;
node = ofw_bus_get_node(dev);
xsc = &sc->xhci_softc;
LOCK_INIT(sc);

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,10 @@
# $FreeBSD$
# All the dts files for Nvidia ARM systems we support.
DTS= \
tegra124-jetson-tk1-fbsd.dts
.if ${MACHINE_ARCH} == "armv7"
DTS= tegra124-jetson-tk1-fbsd.dts
DTS+= tegra124-jetson-tk1.dts
.elif ${MACHINE_ARCH} == "aarch64"
DTS= nvidia/tegra210-p2371-2180.dts
DTS+= nvidia/tegra210-p3450-0000.dts
.endif
.include <bsd.dtb.mk>