Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F106136008
D30123.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D30123.diff
View Options
diff --git a/sys/dev/sdhci/sdhci_fsl_fdt.c b/sys/dev/sdhci/sdhci_fsl_fdt.c
--- a/sys/dev/sdhci/sdhci_fsl_fdt.c
+++ b/sys/dev/sdhci/sdhci_fsl_fdt.c
@@ -90,6 +90,9 @@
#define SDHCI_FSL_ESDHC_CTRL_SNOOP (1 << 6)
#define SDHCI_FSL_ESDHC_CTRL_CLK_DIV2 (1 << 19)
+#define SDHCI_FSL_CAN_VDD_MASK \
+ (SDHCI_CAN_VDD_180 | SDHCI_CAN_VDD_300 | SDHCI_CAN_VDD_330)
+
struct sdhci_fsl_fdt_softc {
device_t dev;
const struct sdhci_fsl_fdt_soc_data *soc_data;
@@ -295,18 +298,11 @@
val32 = RD4(sc, off);
- switch (off) {
- case SDHCI_CAPABILITIES:
- val32 &= ~(SDHCI_CAN_DO_SUSPEND | SDHCI_CAN_VDD_180);
- break;
- case SDHCI_PRESENT_STATE:
+ if (off == SDHCI_PRESENT_STATE) {
wrk32 = val32;
val32 &= SDHCI_FSL_PRES_COMPAT_MASK;
val32 |= (wrk32 >> 4) & SDHCI_STATE_DAT_MASK;
val32 |= (wrk32 << 1) & SDHCI_STATE_CMD;
- break;
- default:
- break;
}
return (val32);
@@ -546,17 +542,78 @@
return (sdhci_fdt_gpio_get_present(sc->gpio));
}
+static uint32_t
+sdhci_fsl_fdt_vddrange_to_mask(device_t dev, uint32_t *vdd_ranges, int len)
+{
+ uint32_t vdd_min, vdd_max;
+ uint32_t vdd_mask = 0;
+ int i;
+
+ /* Ranges are organized as pairs of values. */
+ if ((len % 2) != 0) {
+ device_printf(dev, "Invalid voltage range\n");
+ return (0);
+ }
+ len = len / 2;
+
+ for (i = 0; i < len; i++) {
+ vdd_min = vdd_ranges[2 * i];
+ vdd_max = vdd_ranges[2 * i + 1];
+
+ if (vdd_min > vdd_max || vdd_min < 1650 || vdd_min > 3600 ||
+ vdd_max < 1650 || vdd_max > 3600) {
+ device_printf(dev, "Voltage range %d - %d is out of bounds\n",
+ vdd_min, vdd_max);
+ return (0);
+ }
+
+ if (vdd_min <= 1800 && vdd_max >= 1800)
+ vdd_mask |= SDHCI_CAN_VDD_180;
+ if (vdd_min <= 3000 && vdd_max >= 3000)
+ vdd_mask |= SDHCI_CAN_VDD_300;
+ if (vdd_min <= 3300 && vdd_max >= 3300)
+ vdd_mask |= SDHCI_CAN_VDD_330;
+ }
+
+ return (vdd_mask);
+}
+
static void
sdhci_fsl_fdt_of_parse(device_t dev)
{
struct sdhci_fsl_fdt_softc *sc;
phandle_t node;
+ pcell_t *voltage_ranges;
+ uint32_t vdd_mask = 0;
+ ssize_t num_ranges;
sc = device_get_softc(dev);
node = ofw_bus_get_node(dev);
/* Call mmc_fdt_parse in order to get mmc related properties. */
mmc_fdt_parse(dev, node, &sc->fdt_helper, &sc->slot.host);
+
+ sc->slot.caps = sdhci_fsl_fdt_read_4(dev, &sc->slot,
+ SDHCI_CAPABILITIES) & ~(SDHCI_CAN_DO_SUSPEND);
+ sc->slot.caps2 = sdhci_fsl_fdt_read_4(dev, &sc->slot,
+ SDHCI_CAPABILITIES2);
+
+ /* Parse the "voltage-ranges" dts property. */
+ num_ranges = OF_getencprop_alloc(node, "voltage-ranges",
+ (void **) &voltage_ranges);
+ if (num_ranges <= 0)
+ return;
+ vdd_mask = sdhci_fsl_fdt_vddrange_to_mask(dev, voltage_ranges,
+ num_ranges / sizeof(uint32_t));
+ OF_prop_free(voltage_ranges);
+
+ /* Overwrite voltage caps only if we got something from dts. */
+ if (vdd_mask != 0 &&
+ (vdd_mask != (sc->slot.caps & SDHCI_FSL_CAN_VDD_MASK))) {
+ sc->slot.caps &= ~(SDHCI_FSL_CAN_VDD_MASK);
+ sc->slot.caps |= vdd_mask;
+ sc->slot.quirks |= SDHCI_QUIRK_MISSING_CAPS;
+ }
}
static int
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 27, 12:04 AM (11 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15609263
Default Alt Text
D30123.diff (2 KB)
Attached To
Mode
D30123: sdhci_fsl_fdt.c: Read supported voltages from dts.
Attached
Detach File
Event Timeline
Log In to Comment