Page MenuHomeFreeBSD

D24339.id70531.diff
No OneTemporary

D24339.id70531.diff

Index: sys/dev/ofw/ofw_fdt.c
===================================================================
--- sys/dev/ofw/ofw_fdt.c
+++ sys/dev/ofw/ofw_fdt.c
@@ -78,6 +78,8 @@
static phandle_t ofw_fdt_finddevice(ofw_t, const char *);
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_model(ofw_t, char *, size_t);
+static phandle_t ofw_fdt_find_model(ofw_t ofw, phandle_t);
static int ofw_fdt_interpret(ofw_t, const char *, int, cell_t *);
static ofw_method_t ofw_fdt_methods[] = {
@@ -95,6 +97,7 @@
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),
{ 0, 0 }
};
@@ -105,6 +108,9 @@
};
OFW_DEF(ofw_fdt);
+#define FDT_MODEL_LEN 80
+static char model[FDT_MODEL_LEN];
+
static void *fdtp = NULL;
static int
@@ -128,6 +134,16 @@
}
SYSINIT(dtb_oid, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_register_fdt_oid, NULL);
+static void
+sysctl_register_model_oid(void *arg)
+{
+ /* XXX hw.model is already taken */
+ SYSCTL_ADD_STRING(NULL, SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "manufacturer",
+ CTLFLAG_RD | CTLFLAG_MPSAFE, model,
+ 0, "Model as given by manufacturer");
+}
+SYSINIT(model_oid, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_register_model_oid, NULL);
+
static int
ofw_fdt_init(ofw_t ofw, void *data)
{
@@ -274,7 +290,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 +311,6 @@
if (prop == NULL)
return (-1);
-
bcopy(prop, buf, min(len, buflen));
return (len);
@@ -407,25 +421,44 @@
return (-1);
}
-#if defined(FDT_MARVELL)
+/* Return the fdt model name. */
static int
-ofw_fdt_fixup(ofw_t ofw)
+ofw_fdt_model(ofw_t ofw, char *buf, size_t len)
{
-#define FDT_MODEL_LEN 80
- char model[FDT_MODEL_LEN];
- phandle_t root;
+
+ ofw_fdt_find_model(ofw, 0);
+ strncpy (buf, model, len);
+ return (-1);
+}
+
+/* Find the model string from the fdt */
+static phandle_t
+ofw_fdt_find_model(ofw_t ofw, phandle_t root)
+{
ssize_t len;
- int i;
+ bzero(model, FDT_MODEL_LEN);
if ((root = ofw_fdt_finddevice(ofw, "/")) == -1)
- return (ENODEV);
-
+ return (-1);
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);
+ return (root);
+}
+
+#if defined(FDT_MARVELL)
+static int
+ofw_fdt_fixup(ofw_t ofw)
+{
+ phandle_t root;
+ int i;
+
+ root = ofw_fdt_find_model(ofw_t ofw, root);
+ if (root < 0)
+ return (ENODEV);
+ 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,18 @@
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;
+};
+
# Device I/O Functions (optional)
/**
Index: sys/dev/ofw/openfirm.c
===================================================================
--- sys/dev/ofw/openfirm.c
+++ sys/dev/ofw/openfirm.c
@@ -292,6 +292,17 @@
return (OFW_TEST(ofw_obj, name));
}
+/* 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));
+}
+
int
OF_interpret(const char *cmd, int nreturns, ...)
{
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,31 @@
__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
Wed, Mar 11, 9:39 AM (22 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29525362
Default Alt Text
D24339.id70531.diff (5 KB)

Event Timeline