Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153422455
D20156.id59337.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.id59337.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,12 @@
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
+#ifdef EXT_RESOURCES
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/syscon/syscon.h>
+#include <dev/extres/phy/phy.h>
+#endif
+
#include <dev/mmc/bridge.h>
#include <dev/sdhci/sdhci.h>
@@ -61,16 +67,35 @@
#include "opt_mmccam.h"
+#ifdef EXT_RESOURCES
+#include "syscon_if.h"
+#include "phydev_if.h"
+#endif
+
#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
+#ifdef EXT_RESOURCES
+#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))
+#endif
+
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 +115,33 @@
bool wp_inverted; /* WP pin is inverted */
bool no_18v; /* No 1.8V support */
+
+#ifdef EXT_RESOURCES
+ clk_t clk_xin;
+ clk_t clk_ahb;
+ phy_t phy;
+#endif
};
+#ifdef EXT_RESOURCES
+static void
+sdhci_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);
+}
+#endif
+
static uint8_t
sdhci_fdt_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off)
{
@@ -212,6 +262,9 @@
sc->sdma_boundary = SDHCI_BLKSZ_SDMA_BNDRY_4K;
device_set_desc(dev, "Qualcomm FDT SDHCI controller");
break;
+ case SDHCI_FDT_RK3399:
+ 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");
@@ -243,6 +296,12 @@
struct sdhci_fdt_softc *sc = device_get_softc(dev);
struct sdhci_slot *slot;
int err, slots, rid, i;
+#ifdef EXT_RESOURCES
+ struct syscon *grf = NULL;
+ phandle_t node;
+ uint64_t freq;
+ int error, type;
+#endif
sc->dev = dev;
@@ -255,6 +314,59 @@
return (ENOMEM);
}
+#ifdef EXT_RESOURCES
+ type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
+ if (type == 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);
+ }
+ /* Enable PHY */
+ error = phy_get_by_ofw_name(dev, 0, "phy_arasan", &sc->phy);
+ if (error != 0) {
+ device_printf(dev, "Could not get phy\n");
+ return (ENXIO);
+ }
+ error = phy_enable(sc->phy);
+ if (error != 0) {
+ device_printf(dev, "Could not enable phy\n");
+ return (ENXIO);
+ }
+ /* Get syscon */
+ node = ofw_bus_get_node(dev);
+ 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);
+ }
+ /* Initialize SDHCI */
+ sdhci_init_rk3399(grf, node, freq);
+ }
+#endif
+
/* Scan all slots. */
slots = sc->num_slots; /* number of slots determined in probe(). */
sc->num_slots = 0;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 22, 2:14 AM (19 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31946677
Default Alt Text
D20156.id59337.diff (4 KB)
Attached To
Mode
D20156: Add support for RK3399 emmc
Attached
Detach File
Event Timeline
Log In to Comment