FreeBSD Bugzilla – Attachment 188991 Details for
Bug 224481
Add H3 to aw_sid driver for Allwinner SoC
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
SID driver patch
aw_sid.diff (text/plain), 5.96 KB, created by
Eugene Sevastyanov
on 2017-12-20 13:28:40 UTC
(
hide
)
Description:
SID driver patch
Filename:
MIME Type:
Creator:
Eugene Sevastyanov
Created:
2017-12-20 13:28:40 UTC
Size:
5.96 KB
patch
obsolete
>--- /freebsd_orig/sys/arm/allwinner/aw_sid.c 2017-12-15 12:47:24.868899000 +0400 >+++ /freebsd_branch/sys/arm/allwinner/aw_sid.c 2017-12-20 15:35:03.260100000 +0400 >@@ -48,32 +48,64 @@ > > #include <arm/allwinner/aw_sid.h> > >-#define SID_SRAM 0x200 >-#define SID_THERMAL_CALIB0 (SID_SRAM + 0x34) >-#define SID_THERMAL_CALIB1 (SID_SRAM + 0x38) >- >-#define A10_ROOT_KEY_OFF 0x0 >-#define A83T_ROOT_KEY_OFF SID_SRAM >- >-#define ROOT_KEY_SIZE 4 >- >-enum sid_type { >- A10_SID = 1, >- A20_SID, >- A83T_SID, >+#define SID_KEYS_SIZE 4 >+ >+/* Registers and special values for doing register-based SID readout on H3 */ >+#define SUN8I_SID_PRCTL 0x40 >+#define SUN8I_SID_RDKEY 0x60 >+ >+#define SUN8I_SID_OFFSET_MASK 0x1FF >+#define SUN8I_SID_OFFSET_SHIFT 16 >+#define SUN8I_SID_OP_LOCK (0xAC << 8) >+#define SUN8I_SID_READ (0x01 << 1) >+ >+struct sunxi_sid_cfg { >+ uint32_t sid_offset; /* Offset e-fuse area of SoC from a base address */ >+ uint32_t size; /* Size e-fuse area of SoC (byte) */ >+ uint32_t thermal; /* Offset of thermal sensor calibration data in e-fuse area */ >+ bool need_register_readout; >+}; >+ >+static const struct sunxi_sid_cfg sun4i_a10_cfg = { >+ .size = 0x10, >+}; >+ >+static const struct sunxi_sid_cfg sun7i_a20_cfg = { >+ .size = 0x200, >+}; >+ >+static const struct sunxi_sid_cfg sun8i_h3_cfg = { >+ .sid_offset = 0x200, >+ .size = 0x100, >+ .thermal = 0x34, >+ .need_register_readout = true, >+}; >+ >+static const struct sunxi_sid_cfg sun50i_a64_cfg = { >+ .sid_offset = 0x200, >+ .size = 0x100, >+}; >+ >+static const struct sunxi_sid_cfg sun8i_a83t_cfg = { >+ .sid_offset = 0x200, >+ .size = 0x100, >+ .thermal = 0x34, > }; > > static struct ofw_compat_data compat_data[] = { >- { "allwinner,sun4i-a10-sid", A10_SID}, >- { "allwinner,sun7i-a20-sid", A20_SID}, >- { "allwinner,sun8i-a83t-sid", A83T_SID}, >- { NULL, 0 } >+ { "allwinner,sun4i-a10-sid", (uintptr_t)&sun4i_a10_cfg }, >+ { "allwinner,sun7i-a20-sid", (uintptr_t)&sun7i_a20_cfg }, >+ { "allwinner,sun8i-h3-sid", (uintptr_t)&sun8i_h3_cfg }, >+ { "allwinner,sun50i-a64-sid", (uintptr_t)&sun50i_a64_cfg }, >+ { "allwinner,sun8i-a83t-sid", (uintptr_t)&sun8i_a83t_cfg }, >+ { NULL, 0 } > }; > > struct aw_sid_softc { > struct resource *res; >- int type; >- bus_size_t root_key_off; >+ uint32_t size; /* Size e-fuse area of SoC (byte) */ >+ bus_size_t reg_sid; >+ bus_size_t reg_thermal; > }; > > static struct aw_sid_softc *aw_sid_sc; >@@ -90,6 +122,29 @@ > #define RD4(sc, reg) bus_read_4((sc)->res, (reg)) > #define WR4(sc, reg, val) bus_write_4((sc)->res, (reg), (val)) > >+static int >+sun8i_sid_register_readout(struct aw_sid_softc *sc, const uint32_t word) >+{ >+ uint32_t reg_val; >+ int timeout; >+ >+ /* Set word, lock access, and set read command */ >+ reg_val = (word & SUN8I_SID_OFFSET_MASK) << SUN8I_SID_OFFSET_SHIFT; >+ reg_val |= SUN8I_SID_OP_LOCK | SUN8I_SID_READ; >+ WR4(sc, SUN8I_SID_PRCTL, reg_val); >+ >+ for (timeout = 2500; timeout; timeout--) { >+ if (!(RD4(sc, SUN8I_SID_PRCTL) & SUN8I_SID_READ)) >+ break; >+ DELAY(100); >+ } >+ if (RD4(sc, SUN8I_SID_PRCTL) & SUN8I_SID_READ) >+ return (ETIMEDOUT); >+ >+ WR4(sc, SUN8I_SID_PRCTL, 0); >+ return (0); >+} >+ > static int aw_sid_sysctl(SYSCTL_HANDLER_ARGS); > > static int >@@ -109,25 +164,42 @@ > aw_sid_attach(device_t dev) > { > struct aw_sid_softc *sc; >+ int i, size; >+ const struct sunxi_sid_cfg *cfg; > > sc = device_get_softc(dev); > > if (bus_alloc_resources(dev, aw_sid_spec, &sc->res) != 0) { >- device_printf(dev, "cannot allocate resources for device\n"); >- return (ENXIO); >+ device_printf(dev, "cannot allocate resources for device\n"); >+ return (ENXIO); > } > > aw_sid_sc = sc; > >- sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data; >- switch (sc->type) { >- case A83T_SID: >- sc->root_key_off = A83T_ROOT_KEY_OFF; >- break; >- default: >- sc->root_key_off = A10_ROOT_KEY_OFF; >- break; >+ cfg = (struct sunxi_sid_cfg *)ofw_bus_search_compatible(dev, compat_data)->ocd_data; >+ if (cfg == NULL) >+ return (ENXIO); >+ >+ sc->reg_sid = cfg->sid_offset; >+ size = cfg->size; >+ >+ if (cfg->need_register_readout) { >+ /* >+ * H3's SID controller have a bug that the value at 0x200 >+ * offset is not the correct value when the hardware is reseted. >+ * However, after doing a register-based read operation, the >+ * value become right. >+ * Read a quarter of the memory SID here, but ignore its value >+ * (as it's more fast to read by direct MMIO value than >+ * with registers) >+ */ >+ for (i = 0; i < (size >> 2); i++) >+ if (sun8i_sid_register_readout(sc, i)) >+ return (ENXIO); > } >+ >+ sc->reg_thermal = cfg->sid_offset + cfg->thermal; >+ sc->size = size; > > SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), > SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), >@@ -145,12 +217,13 @@ > > sc = aw_sid_sc; > if (sc == NULL) >- return (ENXIO); >- if (sc->type != A83T_SID) >- return (ENXIO); >+ return (ENXIO); >+ >+ if (sc->reg_thermal == sc->reg_sid) >+ return (ENXIO); > >- *calib0 = RD4(sc, SID_THERMAL_CALIB0); >- *calib1 = RD4(sc, SID_THERMAL_CALIB1); >+ *calib0 = RD4(sc, sc->reg_thermal); >+ *calib1 = RD4(sc, sc->reg_thermal + 4); > > return (0); > } >@@ -160,14 +233,14 @@ > { > struct aw_sid_softc *sc; > int i; >- u_int tmp; >+ uint32_t tmp; > > sc = aw_sid_sc; > if (sc == NULL) > return (ENXIO); > >- for (i = 0; i < ROOT_KEY_SIZE ; i++) { >- tmp = RD4(aw_sid_sc, aw_sid_sc->root_key_off + (i * 4)); >+ for (i = 0; i < SID_KEYS_SIZE; i++) { >+ tmp = RD4(sc, sc->reg_sid + (i * 4)); > be32enc(&out[i * 4], tmp); > } > >@@ -186,8 +259,8 @@ > > if (aw_sid_get_rootkey(rootkey) != 0) > return (ENOENT); >- snprintf(out, sizeof(out), >- "%16D", rootkey, ""); >+ >+ snprintf(out, sizeof(out), "%16D", rootkey, ""); > > return sysctl_handle_string(oidp, out, sizeof(out), req); > } >@@ -208,6 +281,5 @@ > > static devclass_t aw_sid_devclass; > >-EARLY_DRIVER_MODULE(aw_sid, simplebus, aw_sid_driver, aw_sid_devclass, 0, 0, >- BUS_PASS_RESOURCE + BUS_PASS_ORDER_FIRST); >+EARLY_DRIVER_MODULE(aw_sid, simplebus, aw_sid_driver, aw_sid_devclass, 0, 0, BUS_PASS_RESOURCE + BUS_PASS_ORDER_FIRST); > MODULE_VERSION(aw_sid, 1);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 224481
: 188991