Page MenuHomeFreeBSD

D24339.diff
No OneTemporary

D24339.diff

Index: sys/dev/ofw/ofw_fdt.c
===================================================================
--- sys/dev/ofw/ofw_fdt.c
+++ sys/dev/ofw/ofw_fdt.c
@@ -79,6 +79,8 @@
static ssize_t ofw_fdt_instance_to_path(ofw_t, ihandle_t, char *, size_t);
static ssize_t ofw_fdt_package_to_path(ofw_t, phandle_t, char *, size_t);
static int ofw_fdt_interpret(ofw_t, const char *, int, cell_t *);
+static int ofw_fdt_model(ofw_t, char *, size_t);
+static int ofw_fdt_compatible(ofw_t, char *, size_t);
static ofw_method_t ofw_fdt_methods[] = {
OFWMETHOD(ofw_init, ofw_fdt_init),
@@ -95,6 +97,8 @@
OFWMETHOD(ofw_instance_to_path, ofw_fdt_instance_to_path),
OFWMETHOD(ofw_package_to_path, ofw_fdt_package_to_path),
OFWMETHOD(ofw_interpret, ofw_fdt_interpret),
+ OFWMETHOD(ofw_model, ofw_fdt_model),
+ OFWMETHOD(ofw_compatible, ofw_fdt_compatible),
{ 0, 0 }
};
@@ -105,6 +109,11 @@
};
OFW_DEF(ofw_fdt);
+#define FDT_MODEL_LEN 80
+static char model[FDT_MODEL_LEN];
+#define FDT_COMPAT_LEN 80
+static char compatible[FDT_COMPAT_LEN];
+
static void *fdtp = NULL;
static int
@@ -125,6 +134,15 @@
SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_fdt), OID_AUTO, "dtb",
CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
sysctl_handle_dtb, "", "Device Tree Blob");
+
+ if (*model != '\0')
+ SYSCTL_ADD_STRING(NULL, SYSCTL_STATIC_CHILDREN(_hw_fdt),
+ OID_AUTO, "model", CTLFLAG_RD,
+ model, FDT_MODEL_LEN, "Model as given by manufacturer");
+ if (*compatible != '\0')
+ SYSCTL_ADD_STRING(NULL, SYSCTL_STATIC_CHILDREN(_hw_fdt),
+ OID_AUTO, "compatible", CTLFLAG_RD,
+ compatible, FDT_COMPAT_LEN, "Compatibility string as given by manufacturer");
}
SYSINIT(dtb_oid, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_register_fdt_oid, NULL);
@@ -132,12 +150,27 @@
ofw_fdt_init(ofw_t ofw, void *data)
{
int err;
+ phandle_t root;
/* Check FDT blob integrity */
if ((err = fdt_check_header(data)) != 0)
return (err);
fdtp = data;
+
+ bzero(model, FDT_MODEL_LEN);
+ if ((root = ofw_fdt_finddevice(NULL, "/")) != -1) {
+ if (ofw_fdt_getproplen(NULL, root, "model") > 0)
+ ofw_fdt_getprop(NULL, root, "model", model,
+ FDT_MODEL_LEN);
+ }
+
+ bzero(compatible, FDT_COMPAT_LEN);
+ if ((root = ofw_fdt_finddevice(NULL, "/")) != -1) {
+ if (ofw_fdt_getproplen(NULL, root, "compatible") > 0)
+ ofw_fdt_getprop(NULL, root, "compatible", compatible,
+ FDT_COMPAT_LEN);
+ }
return (0);
}
@@ -274,7 +307,6 @@
return (-1);
prop = fdt_getprop(fdtp, offset, propname, &len);
-
if (prop == NULL && strcmp(propname, "name") == 0) {
/* Emulate the 'name' property */
name = fdt_get_name(fdtp, offset, &len);
@@ -296,7 +328,6 @@
if (prop == NULL)
return (-1);
-
bcopy(prop, buf, min(len, buflen));
return (len);
@@ -407,25 +438,35 @@
return (-1);
}
+/* Find the model string from the fdt */
+static int
+ofw_fdt_model(ofw_t ofw, char *buf, size_t buflen)
+{
+
+ if (buf != NULL)
+ strlcpy (buf, model, buflen);
+ return (0);
+}
+
+/* Find the compatible string from the fdt */
+static int
+ofw_fdt_compatible(ofw_t ofw, char *buf, size_t buflen)
+{
+
+ if (buf != NULL)
+ strlcpy(buf, compatible, buflen);
+ return (0);
+}
+
#if defined(FDT_MARVELL)
static int
ofw_fdt_fixup(ofw_t ofw)
{
-#define FDT_MODEL_LEN 80
- char model[FDT_MODEL_LEN];
phandle_t root;
- ssize_t len;
int i;
- if ((root = ofw_fdt_finddevice(ofw, "/")) == -1)
- return (ENODEV);
-
- if ((len = ofw_fdt_getproplen(ofw, root, "model")) <= 0)
- return (0);
-
- bzero(model, FDT_MODEL_LEN);
- if (ofw_fdt_getprop(ofw, root, "model", model, FDT_MODEL_LEN) <= 0)
- return (0);
+ if (*model == '\0')
+ return (ENOENT);
/*
* Search fixup table and call handler if appropriate.
Index: sys/dev/ofw/ofw_if.m
===================================================================
--- sys/dev/ofw/ofw_if.m
+++ sys/dev/ofw/ofw_if.m
@@ -247,6 +247,30 @@
cell_t *_returns;
};
+/**
+ * @brief return model name
+ *
+ * @param _model Buffer for model
+ * @param _size Size of buffer
+ */
+METHOD int model {
+ ofw_t _ofw;
+ char *_model;
+ size_t _size;
+};
+
+/**
+ * @brief return compatible string
+ *
+ * @param _compatible Buffer for compatible
+ * @param _size Size of buffer
+ */
+METHOD int compatible {
+ ofw_t _ofw;
+ char *_compatible;
+ size_t _size;
+};
+
# Device I/O Functions (optional)
/**
Index: sys/dev/ofw/openfirm.h
===================================================================
--- sys/dev/ofw/openfirm.h
+++ sys/dev/ofw/openfirm.h
@@ -174,6 +174,8 @@
/* User interface functions */
int OF_interpret(const char *cmd, int nreturns, ...);
+int OF_model(char *buf, size_t len);
+int OF_compatible(char *buf, size_t len);
/*
* Decode the Nth register property of the given device node and create a bus
Index: sys/dev/ofw/openfirm.c
===================================================================
--- sys/dev/ofw/openfirm.c
+++ sys/dev/ofw/openfirm.c
@@ -846,3 +846,26 @@
for (;;) /* just in case */
;
}
+
+/* Return model from fdt. */
+int
+OF_model(char *buf, size_t len)
+{
+
+ if (ofw_def_impl == NULL)
+ return (0);
+
+ return(OFW_MODEL(ofw_obj, buf, len));
+}
+
+/* Return compatible from fdt. */
+int
+OF_compatible(char *buf, size_t len)
+{
+
+ if (ofw_def_impl == NULL)
+ return (0);
+
+ return(OFW_COMPATIBLE(ofw_obj, buf, len));
+}
+
Index: sys/dev/uart/uart_dev_mu.c
===================================================================
--- sys/dev/uart/uart_dev_mu.c
+++ sys/dev/uart/uart_dev_mu.c
@@ -140,7 +140,11 @@
static void uart_mu_putc(struct uart_bas *bas, int);
static int uart_mu_rxready(struct uart_bas *bas);
static int uart_mu_getc(struct uart_bas *bas, struct mtx *);
+static int cpu_clock(void);
+#define RPI2_AND_3_CORE_CLOCK 250000000
+#define RPI4_CORE_CLOCK 500000000
+
static struct uart_ops uart_mu_ops = {
.probe = uart_mu_probe,
.init = uart_mu_init,
@@ -157,12 +161,6 @@
return (0);
}
-/*
- * According to the docs, the cpu clock is locked to 250Mhz when
- * the micro-uart is used
- */
-#define CPU_CLOCK 250000000
-
static void
uart_mu_param(struct uart_bas *bas, int baudrate, int databits, int stopbits,
int parity)
@@ -193,10 +191,7 @@
/* See 2.2.1 BCM2835-ARM-Peripherals baudrate */
if (baudrate != 0) {
- baud = CPU_CLOCK / (8 * baudrate);
- /* XXX
- * baud = cpu_clock() / (8 * baudrate);
- */
+ baud = cpu_clock() / (8 * baudrate);
__uart_setreg(bas, AUX_MU_BAUD_REG, ((uint32_t)(baud & 0xFFFF)));
}
@@ -518,4 +513,30 @@
__uart_setreg(bas, AUX_MU_CNTL_REG, CNTL_RXENAB|CNTL_TXENAB);
__uart_setreg(bas, AUX_MU_IER_REG, psc->aux_ier);
uart_unlock(sc->sc_hwmtx);
+}
+
+/*
+ * From www.raspberrypi.org/documentation/configuration/uart.md
+ *
+ * "The baud rate of the mini UART is linked to the core frequency of
+ * the VPU on the VC4 GPU. This means that, as the VPU frequency governor
+ * varies the core frequency, the baud rate of the mini UART also changes"
+ *
+ * Since this is rather unusable for a uart the core frequency is locked
+ * if this uart is enabled in the config. Unfortantely it is locked
+ * to 250Mhz on Rpi2 and Rpi3 but 500Mhz on Rpi4 so this driver needs
+ * to determine which is needed. This is one approach, another approach
+ * might be to query bcm2835_cpufreq.c directly.
+ */
+
+
+static int
+cpu_clock(void)
+{
+ char model[40];
+
+ OF_model(model, sizeof(model));
+ if (strncmp(model, "Raspberry Pi 4", 14) == 0)
+ return (RPI4_CORE_CLOCK);
+ return (RPI2_AND_3_CORE_CLOCK);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 28, 3:05 AM (5 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26272455
Default Alt Text
D24339.diff (7 KB)

Event Timeline