Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/sdhci/sdhci_fsl_fdt.c
Show First 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | struct sdhci_fsl_fdt_softc { | ||||
uint16_t sdclk_bits; | uint16_t sdclk_bits; | ||||
uint32_t (* read)(struct sdhci_fsl_fdt_softc *, bus_size_t); | uint32_t (* read)(struct sdhci_fsl_fdt_softc *, bus_size_t); | ||||
void (* write)(struct sdhci_fsl_fdt_softc *, bus_size_t, uint32_t); | void (* write)(struct sdhci_fsl_fdt_softc *, bus_size_t, uint32_t); | ||||
}; | }; | ||||
struct sdhci_fsl_fdt_soc_data { | struct sdhci_fsl_fdt_soc_data { | ||||
int quirks; | int quirks; | ||||
int baseclk_div; | |||||
}; | }; | ||||
static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_ls1046a_soc_data = { | static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_ls1046a_soc_data = { | ||||
.quirks = SDHCI_QUIRK_DONT_SET_HISPD_BIT | SDHCI_QUIRK_BROKEN_AUTO_STOP | .quirks = SDHCI_QUIRK_DONT_SET_HISPD_BIT | SDHCI_QUIRK_BROKEN_AUTO_STOP, | ||||
.baseclk_div = 2, | |||||
}; | }; | ||||
static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_gen_data = { | static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_gen_data = { | ||||
.quirks = 0, | .quirks = 0, | ||||
.baseclk_div = 1, | |||||
}; | }; | ||||
static const struct ofw_compat_data sdhci_fsl_fdt_compat_data[] = { | static const struct ofw_compat_data sdhci_fsl_fdt_compat_data[] = { | ||||
{"fsl,ls1046a-esdhc", (uintptr_t)&sdhci_fsl_fdt_ls1046a_soc_data}, | {"fsl,ls1046a-esdhc", (uintptr_t)&sdhci_fsl_fdt_ls1046a_soc_data}, | ||||
{"fsl,esdhc", (uintptr_t)&sdhci_fsl_fdt_gen_data}, | {"fsl,esdhc", (uintptr_t)&sdhci_fsl_fdt_gen_data}, | ||||
{NULL, 0} | {NULL, 0} | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 379 Lines • ▼ Show 20 Lines | sdhci_fsl_fdt_attach(device_t dev) | ||||
ret = clk_get_freq(clk, &clk_hz); | ret = clk_get_freq(clk, &clk_hz); | ||||
if (ret != 0) { | if (ret != 0) { | ||||
device_printf(dev, | device_printf(dev, | ||||
"Could not get parent clock frequency\n"); | "Could not get parent clock frequency\n"); | ||||
goto err_free_irq; | goto err_free_irq; | ||||
} | } | ||||
sc->baseclk_hz = clk_hz / 2; | sc->baseclk_hz = clk_hz / sc->soc_data->baseclk_div; | ||||
/* Figure out eSDHC block endianness before we touch any HW regs. */ | /* Figure out eSDHC block endianness before we touch any HW regs. */ | ||||
if (OF_hasprop(node, "little-endian")) { | if (OF_hasprop(node, "little-endian")) { | ||||
sc->read = read_le; | sc->read = read_le; | ||||
sc->write = write_le; | sc->write = write_le; | ||||
buf_order = SDHCI_FSL_PROT_CTRL_BYTE_NATIVE; | buf_order = SDHCI_FSL_PROT_CTRL_BYTE_NATIVE; | ||||
} else { | } else { | ||||
sc->read = read_be; | sc->read = read_be; | ||||
Show All 9 Lines | sdhci_fsl_fdt_attach(device_t dev) | ||||
* the byte order again, resulting in a native byte order. | * the byte order again, resulting in a native byte order. | ||||
* The read/write callbacks accommodate for this behavior. | * The read/write callbacks accommodate for this behavior. | ||||
*/ | */ | ||||
val = RD4(sc, SDHCI_FSL_PROT_CTRL); | val = RD4(sc, SDHCI_FSL_PROT_CTRL); | ||||
val &= ~SDHCI_FSL_PROT_CTRL_BYTE_MASK; | val &= ~SDHCI_FSL_PROT_CTRL_BYTE_MASK; | ||||
WR4(sc, SDHCI_FSL_PROT_CTRL, val | buf_order); | WR4(sc, SDHCI_FSL_PROT_CTRL, val | buf_order); | ||||
/* | /* | ||||
* Gate the SD clock and set its source to peripheral clock / 2. | * Gate the SD clock and set its source to | ||||
* The frequency in baseclk_hz is set to match this. | * peripheral clock / baseclk_div. The frequency in baseclk_hz is set | ||||
* to match this. | |||||
*/ | */ | ||||
val = RD4(sc, SDHCI_CLOCK_CONTROL); | val = RD4(sc, SDHCI_CLOCK_CONTROL); | ||||
WR4(sc, SDHCI_CLOCK_CONTROL, val & ~SDHCI_FSL_CLK_SDCLKEN); | WR4(sc, SDHCI_CLOCK_CONTROL, val & ~SDHCI_FSL_CLK_SDCLKEN); | ||||
val = RD4(sc, SDHCI_FSL_ESDHC_CTRL); | val = RD4(sc, SDHCI_FSL_ESDHC_CTRL); | ||||
WR4(sc, SDHCI_FSL_ESDHC_CTRL, val | SDHCI_FSL_ESDHC_CTRL_CLK_DIV2); | WR4(sc, SDHCI_FSL_ESDHC_CTRL, val | SDHCI_FSL_ESDHC_CTRL_CLK_DIV2); | ||||
sc->slot.max_clk = sc->baseclk_hz; | sc->slot.max_clk = sc->baseclk_hz; | ||||
sc->gpio = sdhci_fdt_gpio_setup(dev, &sc->slot); | sc->gpio = sdhci_fdt_gpio_setup(dev, &sc->slot); | ||||
▲ Show 20 Lines • Show All 131 Lines • Show Last 20 Lines |