Page MenuHomeFreeBSD

D42472.diff
No OneTemporary

D42472.diff

Index: sys/arm/ti/am335x/files.am335x
===================================================================
--- sys/arm/ti/am335x/files.am335x
+++ sys/arm/ti/am335x/files.am335x
@@ -22,3 +22,7 @@
arm/ti/ti_edma3.c standard
arm/ti/cpsw/if_cpsw.c optional cpsw
+
+dev/cpufreq/cpufreq_dt_if.m optional ti_cpufreq fdt
+dev/cpufreq/cpufreq_dt.c optional ti_cpufreq fdt
+dev/cpufreq/cpufreq_dt_ti_opp.c optional fdt ti_cpufreq
Index: sys/dev/cpufreq/cpufreq_dt_ti_opp.c
===================================================================
--- /dev/null
+++ sys/dev/cpufreq/cpufreq_dt_ti_opp.c
@@ -0,0 +1,215 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Oskar Holmlund <oh@FreeBSD.Org>
+ * Copyright (c) 2018 Emmanuel Vadot <manu@FreeBSD.Org>
+ * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Based on sys/contrib/device-tree/Bindings/cpufreq/ti-cpufreq.txt
+ */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/cpu.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/extres/syscon/syscon.h>
+
+#include <dev/cpufreq/cpufreq_dt.h>
+
+#include "cpufreq_dt_if.h"
+#include "syscon_if.h"
+
+#if 0
+#define DPRINTF(dev, msg...) device_printf(dev, "ti_cpufreq: " msg);
+#else
+#define DPRINTF(dev, msg...)
+#endif
+
+#define AM33XX_EFUSE_OFFSET 0x7FC
+#define AM33XX_EFUSE_MASK 0x1FFF
+#define AM33XX_REV_OFFSET 0x600
+#define AM33XX_REV_MASK 0xF0000000
+#define AM33XX_REV_SHIFT 28
+
+static int
+cpufreq_dt_ti_oppv2_parse(device_t dev, struct cpufreq_dt_softc *sc,
+ phandle_t node)
+{
+ phandle_t opp, opp_table, opp_xref;
+ pcell_t cell[2];
+ uint32_t *volts, lat;
+ int nvolt, i, len, rv;
+ uint32_t efuse, rev;
+ uint32_t opp_sup_hw[2];
+ struct syscon *syscon;
+
+ if (OF_getencprop(node, "operating-points-v2", &opp_xref,
+ sizeof(opp_xref)) == -1) {
+ device_printf(sc->dev, "Cannot get xref to oppv2 table\n");
+ return (ENXIO);
+ }
+
+ opp_table = OF_node_from_xref(opp_xref);
+ if (opp_table == opp_xref)
+ return (ENXIO);
+
+ rv = ofw_bus_node_is_compatible(opp_table,
+ "operating-points-v2-ti-cpu");
+ if (rv == 0)
+ {
+ device_printf(sc->dev,
+ "Not compatible with operating-points-v2-ti-cpu\n");
+ return (ENXIO);
+ }
+
+ rv = syscon_get_by_ofw_property(sc->dev, opp_table, "syscon", &syscon);
+ if (rv != 0) {
+ device_printf(sc->dev, "cannot find syscon\n");
+ return (ENXIO);
+ }
+
+ /* REV see TRM 9.3.1.15 */
+ rev = SYSCON_READ_4(syscon, AM33XX_REV_OFFSET) & AM33XX_REV_MASK;
+ rev >>= AM33XX_REV_SHIFT;
+
+ /* Read EFUSE register see TRM 9.3.1.49 */
+ efuse = SYSCON_READ_4(syscon, AM33XX_EFUSE_OFFSET);
+ efuse &= AM33XX_EFUSE_MASK;
+ if (efuse == 0) {
+ DPRINTF(sc->dev,
+ "Use default - OSD3358 see am335x-osd335x-common.dtsi\n");
+ /* All OSD3358 is 1000MHz ZCZ package */
+ efuse = 0x1C2F;
+ }
+
+ /* invert bits
+ * 0 represents the frequency are supported
+ * 300MHz zcz bin(0x1FEF) = 0b1111111101111
+ * 600MHz zcz bin(0x1FAF) = 0b1111110101111
+ * 720MHz zcz bin(0x1F2F) = 0b1111100101111
+ * 800MHz zcz bin(0x1E2F) = 0b1111000101111
+ * 1000Mhz zcz bin(0x1C2F) = 0b1110000101111
+ *
+ * TODO: if you for some reason use ZCE package
+ * you have to read package_type bits in the efuse_sma register
+ * see 9.3.1.49 for details.
+ */
+ efuse = ~efuse;
+
+ for (opp = OF_child(opp_table); opp > 0; opp = OF_peer(opp))
+ sc->nopp += 1;
+
+ sc->opp = malloc(sizeof(*sc->opp) * sc->nopp, M_DEVBUF, M_WAITOK);
+
+ for (i = 0, opp_table = OF_child(opp_table); opp_table > 0;
+ opp_table = OF_peer(opp_table), i++) {
+ /* Check if this hardware support this opp */
+ if (OF_hasprop(opp_table, "opp-supported-hw")) {
+ len = OF_getencprop(opp_table, "opp-supported-hw",
+ opp_sup_hw, sizeof(opp_sup_hw));
+ if (len != sizeof(opp_sup_hw))
+ continue;
+
+ if ((rev & opp_sup_hw[0]) == 0)
+ continue;
+ if ((efuse & opp_sup_hw[1]) == 0)
+ continue;
+ }
+ /* opp-hz is a required property */
+ if (OF_getencprop(opp_table, "opp-hz", cell,
+ sizeof(cell)) == -1)
+ continue;
+
+ sc->opp[i].freq = cell[0];
+ sc->opp[i].freq <<= 32;
+ sc->opp[i].freq |= cell[1];
+
+ if (OF_getencprop(opp_table, "clock-latency", &lat,
+ sizeof(lat)) == -1)
+ sc->opp[i].clk_latency = CPUFREQ_VAL_UNKNOWN;
+ else
+ sc->opp[i].clk_latency = (int)lat;
+
+ if (OF_hasprop(opp_table, "turbo-mode"))
+ sc->opp[i].turbo_mode = true;
+ if (OF_hasprop(opp_table, "opp-suspend"))
+ sc->opp[i].opp_suspend = true;
+
+ if (CPUFREQ_DT_HAVE_REGULATOR(sc)) {
+ nvolt = OF_getencprop_alloc_multi(opp_table,
+ "opp-microvolt", sizeof(*volts), (void **)&volts);
+ if (nvolt == 1) {
+ sc->opp[i].uvolt_target = volts[0];
+ sc->opp[i].uvolt_min = volts[0];
+ sc->opp[i].uvolt_max = volts[0];
+ } else if (nvolt == 3) {
+ sc->opp[i].uvolt_target = volts[0];
+ sc->opp[i].uvolt_min = volts[1];
+ sc->opp[i].uvolt_max = volts[2];
+ } else {
+ device_printf(sc->dev,
+ "Wrong count of opp-microvolt property\n");
+ OF_prop_free(volts);
+ free(sc->opp, M_DEVBUF);
+ return (ENXIO);
+ }
+ OF_prop_free(volts);
+ } else {
+ /* No regulator required; don't add anything */
+ sc->opp[i].uvolt_target = 0;
+ sc->opp[i].uvolt_min = 0;
+ sc->opp[i].uvolt_max = 0;
+ }
+ if (bootverbose)
+ device_printf(sc->dev, "found: %ju.%03ju Mhz (%u uV)\n",
+ sc->opp[i].freq / 1000000,
+ sc->opp[i].freq % 1000000,
+ sc->opp[i].uvolt_target);
+ }
+ return (0);
+}
+
+static device_method_t cpufreq_dt_ti_methods[] = {
+ /* cpufreq_dt interface */
+ DEVMETHOD(cpufreq_dt_oppv2_parse, cpufreq_dt_ti_oppv2_parse),
+
+ DEVMETHOD_END
+};
+
+extern driver_t cpufreq_dt_driver;
+
+DEFINE_CLASS_1(cpufreq_dt, cpufreq_dt_ti_driver, cpufreq_dt_ti_methods,
+ sizeof(struct cpufreq_dt_softc), cpufreq_dt_driver);
+
+DRIVER_MODULE(cpufreq_dt_ti, cpu, cpufreq_dt_ti_driver, 0, 0);
+MODULE_VERSION(cpufreq_dt_ti, 1);

File Metadata

Mime Type
text/plain
Expires
Thu, Jul 30, 1:36 AM (5 m, 2 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35721590
Default Alt Text
D42472.diff (7 KB)

Event Timeline