Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F164135440
D42472.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D42472.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D42472: cpufreq_dt: Add parse function for operating-points-v2-ti-cpu
Attached
Detach File
Event Timeline
Log In to Comment