Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F149558541
D20156.id57033.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D20156.id57033.diff
View Options
Index: sys/dev/sdhci/sdhci_fdt.c
===================================================================
--- sys/dev/sdhci/sdhci_fdt.c
+++ sys/dev/sdhci/sdhci_fdt.c
@@ -52,6 +52,9 @@
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/syscon/syscon.h>
+
#include <dev/mmc/bridge.h>
#include <dev/sdhci/sdhci.h>
@@ -61,16 +64,30 @@
#include "opt_mmccam.h"
+#include "syscon_if.h"
+
#define MAX_SLOTS 6
#define SDHCI_FDT_ARMADA38X 1
#define SDHCI_FDT_GENERIC 2
#define SDHCI_FDT_XLNX_ZY7 3
#define SDHCI_FDT_QUALCOMM 4
+#define SDHCI_FDT_RK3399 5
+#define RK3399_GRF_EMMCCORE_CON0 0xf000
+#define RK3399_CORECFG_BASECLKFREQ (1 << 15) | (1 << 8)
+#define RK3399_CORECFG_TIMEOUTCLKUNIT (1 << 7)
+#define RK3399_CORECFG_TUNINGCOUNT (1 << 5) | (1 << 0)
+#define RK3399_GRF_EMMCCORE_CON11 0xf02c
+#define RK3399_CORECFG_CLOCKMULTIPLIER (1 << 7) | (1 << 0)
+
+#define LOWEST_SET_BIT(mask) ((((mask) - 1) & (mask)) ^ (mask))
+#define SHIFTIN(x, mask) ((x) * LOWEST_SET_BIT(mask))
+
static struct ofw_compat_data compat_data[] = {
{ "marvell,armada-380-sdhci", SDHCI_FDT_ARMADA38X },
{ "sdhci_generic", SDHCI_FDT_GENERIC },
{ "qcom,sdhci-msm-v4", SDHCI_FDT_QUALCOMM },
+ { "rockchip,rk3399-sdhci-5.1", SDHCI_FDT_RK3399 },
{ "xlnx,zy7_sdhci", SDHCI_FDT_XLNX_ZY7 },
{ NULL, 0 }
};
@@ -90,8 +107,28 @@
bool wp_inverted; /* WP pin is inverted */
bool no_18v; /* No 1.8V support */
+
+ clk_t clk_xin;
+ clk_t clk_ahb;
};
+static void
+sdhc_init_rk3399(struct syscon *grf, phandle_t node, uint64_t freq)
+{
+ uint32_t mask, val;
+
+ /* Disable clock multiplier */
+ mask = RK3399_CORECFG_CLOCKMULTIPLIER;
+ val = 0;
+ SYSCON_WRITE_4(grf, RK3399_GRF_EMMCCORE_CON11, (mask << 16) | val);
+
+ /* Set base clock frequency */
+ mask = RK3399_CORECFG_BASECLKFREQ;
+ val = SHIFTIN((freq + (1000000 / 2)) / 1000000,
+ RK3399_CORECFG_BASECLKFREQ);
+ SYSCON_WRITE_4(grf, RK3399_GRF_EMMCCORE_CON0, (mask << 16) | val);
+}
+
static uint8_t
sdhci_fdt_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off)
{
@@ -188,8 +225,11 @@
sdhci_fdt_probe(device_t dev)
{
struct sdhci_fdt_softc *sc = device_get_softc(dev);
+ struct syscon *grf = NULL;
phandle_t node;
pcell_t cid;
+ uint64_t freq;
+ int error;
sc->quirks = 0;
sc->num_slots = 1;
@@ -198,6 +238,8 @@
if (!ofw_bus_status_okay(dev))
return (ENXIO);
+ node = ofw_bus_get_node(dev);
+
switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
case SDHCI_FDT_ARMADA38X:
sc->quirks = SDHCI_QUIRK_BROKEN_AUTO_STOP;
@@ -212,6 +254,42 @@
sc->sdma_boundary = SDHCI_BLKSZ_SDMA_BNDRY_4K;
device_set_desc(dev, "Qualcomm FDT SDHCI controller");
break;
+ case SDHCI_FDT_RK3399:
+ /* Get and activate clocks */
+ error = clk_get_by_ofw_name(dev, 0, "clk_xin", &sc->clk_xin);
+ if (error != 0) {
+ device_printf(dev, "cannot get xin clock\n");
+ return (ENXIO);
+ }
+ error = clk_enable(sc->clk_xin);
+ if (error != 0) {
+ device_printf(dev, "cannot enable xin clock\n");
+ return (ENXIO);
+ }
+ error = clk_get_freq(sc->clk_xin, &freq);
+ if (error != 0) {
+ device_printf(dev, "cannot get xin clock frequency\n");
+ return (ENXIO);
+ }
+ error = clk_get_by_ofw_name(dev, 0, "clk_ahb", &sc->clk_ahb);
+ if (error != 0) {
+ device_printf(dev, "cannot get ahb clock\n");
+ return (ENXIO);
+ }
+ error = clk_enable(sc->clk_ahb);
+ if (error != 0) {
+ device_printf(dev, "cannot enable ahb clock\n");
+ return (ENXIO);
+ }
+ if (OF_hasprop(node, "arasan,soc-ctl-syscon") &&
+ syscon_get_by_ofw_property(dev, node,
+ "arasan,soc-ctl-syscon", &grf) != 0) {
+ device_printf(dev, "cannot get grf driver handle\n");
+ return (ENXIO);
+ }
+ sdhc_init_rk3399(grf, node, freq);
+ device_set_desc(dev, "Rockchip RK3399 fdt SDHCI controller");
+ break;
case SDHCI_FDT_XLNX_ZY7:
sc->quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK;
device_set_desc(dev, "Zynq-7000 generic fdt SDHCI controller");
@@ -220,8 +298,6 @@
return (ENXIO);
}
- node = ofw_bus_get_node(dev);
-
/* Allow dts to patch quirks, slots, and max-frequency. */
if ((OF_getencprop(node, "quirks", &cid, sizeof(cid))) > 0)
sc->quirks = cid;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 26, 6:19 AM (15 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30367775
Default Alt Text
D20156.id57033.diff (4 KB)
Attached To
Mode
D20156: Add support for RK3399 emmc
Attached
Detach File
Event Timeline
Log In to Comment