Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177273200
D24351.1794048936.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
16 KB
Referenced Files
None
Subscribers
None
D24351.1794048936.diff
View Options
Index: sys/arm64/qoriq/clk/qoriq_clk_pll.h
===================================================================
--- /dev/null
+++ sys/arm64/qoriq/clk/qoriq_clk_pll.h
@@ -0,0 +1,50 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Alstom Group.
+ * Copyright (c) 2020 Semihalf.
+ *
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ */
+
+#ifndef _QORIQ_CLK_PLL_H_
+#define _QORIQ_CLK_PLL_H_
+
+#include <dev/extres/clk/clk.h>
+
+#define QORIQ_CLK_PLL_HAS_KILL_BIT 0x01
+
+struct qoriq_clk_pll_def {
+ struct clknode_init_def clkdef;
+
+ bus_addr_t offset;
+ uint32_t mask;
+ uint8_t shift;
+ const uint8_t *dividers;
+ uint8_t flags;
+};
+
+int qoriq_clk_pll_register(struct clkdom *clkdom,
+ const struct qoriq_clk_pll_def *clkdef);
+
+#endif /* _QORIQ_CLK_PLL_H_ */
+
Index: sys/arm64/qoriq/clk/qoriq_clk_pll.c
===================================================================
--- /dev/null
+++ sys/arm64/qoriq/clk/qoriq_clk_pll.c
@@ -0,0 +1,152 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Alstom Group.
+ * Copyright (c) 2020 Semihalf.
+ *
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/clk/clk_fixed.h>
+
+#include <arm64/qoriq/clk/qoriq_clkgen.h>
+
+#include "clkdev_if.h"
+
+struct qoriq_clk_pll_softc {
+ bus_addr_t offset;
+
+ uint32_t mask;
+ uint32_t shift;
+
+ uint32_t flags;
+};
+
+#define WR4(_clk, offset, val) \
+ CLKDEV_WRITE_4(clknode_get_device(_clk), offset, val)
+#define RD4(_clk, offset, val) \
+ CLKDEV_READ_4(clknode_get_device(_clk), offset, val)
+#define DEVICE_LOCK(_clk) \
+ CLKDEV_DEVICE_LOCK(clknode_get_device(_clk))
+#define DEVICE_UNLOCK(_clk) \
+ CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk))
+
+#define QORIQ_PLL_KILL_BIT (1 << 31)
+
+static int
+qoriq_clk_pll_init(struct clknode *clk, device_t dev)
+{
+
+ clknode_init_parent_idx(clk, 0);
+
+ return (0);
+}
+
+static int
+qoriq_clk_pll_recalc_freq(struct clknode *clk, uint64_t *freq)
+{
+ struct qoriq_clk_pll_softc *sc;
+ uint32_t mul;
+
+ sc = clknode_get_softc(clk);
+
+ RD4(clk, sc->offset, &mul);
+
+ if (sc->flags & QORIQ_CLK_PLL_HAS_KILL_BIT && mul & QORIQ_PLL_KILL_BIT)
+ return (0);
+
+ mul &= sc->mask;
+ mul >>= sc->shift;
+
+ *freq = *freq * mul;
+
+ return (0);
+}
+
+static clknode_method_t qoriq_clk_pll_clknode_methods[] = {
+ CLKNODEMETHOD(clknode_init, qoriq_clk_pll_init),
+ CLKNODEMETHOD(clknode_recalc_freq, qoriq_clk_pll_recalc_freq),
+
+ CLKNODEMETHOD_END
+};
+
+DEFINE_CLASS_1(qoriq_clk_pll_clknode, qoriq_clk_pll_clknode_class,
+ qoriq_clk_pll_clknode_methods, sizeof(struct qoriq_clk_pll_softc),
+ clknode_class);
+
+int
+qoriq_clk_pll_register(struct clkdom *clkdom,
+ const struct qoriq_clk_pll_def *clkdef)
+{
+ char namebuf[QORIQ_CLK_NAME_MAX_LEN];
+ struct qoriq_clk_pll_softc *sc;
+ struct clk_fixed_def def;
+ const char *parent_name;
+ struct clknode *clk;
+ int error;
+ int i;
+
+ clk = clknode_create(clkdom, &qoriq_clk_pll_clknode_class,
+ &clkdef->clkdef);
+ if (clk == NULL)
+ return (1);
+
+ sc = clknode_get_softc(clk);
+ sc->mask = clkdef->mask;
+ sc->shift = clkdef->shift;
+ sc->flags = clkdef->flags;
+ sc->offset = clkdef->offset;
+
+ clknode_register(clkdom, clk);
+
+ parent_name = clkdef->clkdef.name;
+
+ def.clkdef.parent_names = &parent_name;
+ def.clkdef.parent_cnt = 1;
+ def.clkdef.name = namebuf;
+ def.mult = 1;
+ def.freq = 0;
+
+ i = 0;
+ while (clkdef->dividers[i] != 0) {
+ def.div = clkdef->dividers[i];
+ def.clkdef.id = clkdef->clkdef.id + i;
+ snprintf(namebuf, QORIQ_CLK_NAME_MAX_LEN, "%s-%d",
+ parent_name, clkdef->dividers[i] - 1);
+
+ error = clknode_fixed_register(clkdom, &def);
+ if (error != 0)
+ return (error);
+
+ i++;
+ }
+
+ return (0);
+}
Index: sys/arm64/qoriq/clk/qoriq_clkgen.h
===================================================================
--- /dev/null
+++ sys/arm64/qoriq/clk/qoriq_clkgen.h
@@ -0,0 +1,87 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Alstom Group.
+ * Copyright (c) 2020 Semihalf.
+ *
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ */
+
+#ifndef _QORIQ_CLKGEN_H_
+#define _QORIQ_CLKGEN_H_
+
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/clk/clk_mux.h>
+
+#include <arm64/qoriq/clk/qoriq_clk_pll.h>
+
+#define QORIQ_CLK_NAME_MAX_LEN 24
+
+#define QORIQ_LITTLE_ENDIAN 0x01
+
+#define QORIQ_SYSCLK "cg-sysclk"
+#define QORIQ_PLTPLL "cg-pltfrm"
+#define QORIQ_CGAPLL1 "cg-cgapll1"
+#define QORIQ_CGAPLL2 "cg-cgapll2"
+#define QORIQ_CMUX "cg-cmux"
+#define QORIQ_HWACCEL "cg-hwaccel"
+#define QORIQ_FMAN "cg-fman"
+
+#define PLL_BASE ""
+#define PLL_DIV1 "-0"
+#define PLL_DIV2 "-1"
+#define PLL_DIV3 "-2"
+#define PLL_DIV4 "-3"
+#define PLL_DIV5 "-4"
+#define PLL_DIV6 "-5"
+#define PLL_DIV7 "-6"
+#define PLL_DIV8 "-7"
+
+#define NODE_NUM0 "-0"
+#define NODE_NUM1 "-1"
+#define NODE_NUM2 "-2"
+#define NODE_NUM3 "-3"
+
+#define QORIQ_CLK_NAME(_base, _extend) (_base _extend)
+
+typedef int (*qoriq_init_func_t)(device_t);
+
+struct qoriq_clkgen_softc {
+ device_t dev;
+ struct resource *res;
+ struct clkdom *clkdom;
+ struct mtx mtx;
+ const struct qoriq_clk_pll_def *pltfrm_pll_def;
+ const struct qoriq_clk_pll_def **cga_pll;
+ int cga_pll_num;
+ struct clk_mux_def **mux;
+ int mux_num;
+ qoriq_init_func_t init_func;
+ uint32_t flags;
+};
+
+MALLOC_DECLARE(M_QORIQ_CLKGEN);
+DECLARE_CLASS(qoriq_clkgen_driver);
+
+int qoriq_clkgen_attach(device_t);
+
+#endif /* _QORIQ_CLKGEN_H_ */
Index: sys/arm64/qoriq/clk/qoriq_clkgen.c
===================================================================
--- /dev/null
+++ sys/arm64/qoriq/clk/qoriq_clkgen.c
@@ -0,0 +1,270 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Alstom Group.
+ * Copyright (c) 2020 Semihalf.
+ *
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/rman.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <machine/bus.h>
+
+#include <dev/fdt/simplebus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/extres/clk/clk_fixed.h>
+
+#include <arm64/qoriq/clk/qoriq_clkgen.h>
+
+#include "clkdev_if.h"
+
+MALLOC_DEFINE(M_QORIQ_CLKGEN, "qoriq_clkgen", "qoriq_clkgen");
+
+static struct resource_spec qoriq_clkgen_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+static const char *clk_names[] = {
+ "sysclk",
+ "cmux",
+ "hwaccel",
+ "fman",
+ "pltfrm"
+};
+
+static int
+qoriq_clkgen_ofw_mapper(struct clkdom *clkdom, uint32_t ncells,
+ phandle_t *cells, struct clknode **clk)
+{
+ char namebuf[QORIQ_CLK_NAME_MAX_LEN];
+
+ if (ncells != 2)
+ return (EINVAL);
+
+ if (cells[0] > 4)
+ return (EINVAL);
+
+ /* Use clock node names for lookup. */
+ snprintf(namebuf, QORIQ_CLK_NAME_MAX_LEN, "cg-%s-%d",
+ clk_names[cells[0]], cells[1]);
+ *clk = clknode_find_by_name(namebuf);
+
+ if (clk == NULL)
+ return (EINVAL);
+
+ return (0);
+}
+
+static int
+qoriq_clkgen_write_4(device_t dev, bus_addr_t addr, uint32_t val)
+{
+ struct qoriq_clkgen_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ if (sc->flags & QORIQ_LITTLE_ENDIAN)
+ bus_write_4(sc->res, addr, htole32(val));
+ else
+ bus_write_4(sc->res, addr, htobe32(val));
+ return (0);
+}
+
+static int
+qoriq_clkgen_read_4(device_t dev, bus_addr_t addr, uint32_t *val)
+{
+ struct qoriq_clkgen_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ if (sc->flags & QORIQ_LITTLE_ENDIAN)
+ *val = le32toh(bus_read_4(sc->res, addr));
+ else
+ *val = be32toh(bus_read_4(sc->res, addr));
+ return (0);
+}
+
+static int
+qoriq_clkgen_modify_4(device_t dev, bus_addr_t addr, uint32_t clr,
+ uint32_t set)
+{
+ uint32_t reg;
+
+ qoriq_clkgen_read_4(dev, addr, ®);
+ reg &= ~clr;
+ reg |= set;
+ qoriq_clkgen_write_4(dev, addr, reg);
+
+ return (0);
+}
+
+static void
+qoriq_clkgen_device_lock(device_t dev)
+{
+ struct qoriq_clkgen_softc *sc;
+
+ sc = device_get_softc(dev);
+ mtx_lock(&sc->mtx);
+}
+
+static void
+qoriq_clkgen_device_unlock(device_t dev)
+{
+ struct qoriq_clkgen_softc *sc;
+
+ sc = device_get_softc(dev);
+ mtx_unlock(&sc->mtx);
+}
+
+static device_method_t qoriq_clkgen_methods[] = {
+ DEVMETHOD(clkdev_write_4, qoriq_clkgen_write_4),
+ DEVMETHOD(clkdev_read_4, qoriq_clkgen_read_4),
+ DEVMETHOD(clkdev_modify_4, qoriq_clkgen_modify_4),
+ DEVMETHOD(clkdev_device_lock, qoriq_clkgen_device_lock),
+ DEVMETHOD(clkdev_device_unlock, qoriq_clkgen_device_unlock),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_0(qoriq_clkgen, qoriq_clkgen_driver, qoriq_clkgen_methods,
+ sizeof(struct qoriq_clkgen_softc));
+
+static int
+qoriq_clkgen_create_sysclk(device_t dev)
+{
+ struct qoriq_clkgen_softc *sc;
+ struct clk_fixed_def def;
+ const char *clkname;
+ phandle_t node;
+ clk_t sysclk;
+ int error;
+
+ sc = device_get_softc(dev);
+ node = ofw_bus_get_node(dev);
+
+ /* Create node referring to sysclk oscillator in current domain. */
+ memset(&def, 0, sizeof(def));
+ def.clkdef.name = "cg-sysclk-0";
+ def.clkdef.id = 0;
+ def.clkdef.parent_cnt = 1;
+ def.mult = 1;
+ def.div = 1;
+
+ error = clk_get_by_ofw_name(dev, node, "sysclk", &sysclk);
+ if (error != 0) {
+ error = clk_get_by_ofw_index(dev, node, 0, &sysclk);
+ if (error != 0)
+ return (error);
+ }
+
+ clkname = clk_get_name(sysclk);
+ def.clkdef.parent_names = &clkname;
+
+ error = clknode_fixed_register(sc->clkdom, &def);
+
+ return (error);
+}
+
+int
+qoriq_clkgen_attach(device_t dev)
+{
+ struct qoriq_clkgen_softc *sc;
+ int i, error;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ if (bus_alloc_resources(dev, qoriq_clkgen_spec, &sc->res) != 0) {
+ device_printf(dev, "Cannot allocate resources.\n");
+ return (ENXIO);
+ }
+
+ mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
+
+ sc->clkdom = clkdom_create(dev);
+ if (sc->clkdom == NULL)
+ panic("Cannot create clock domain.\n");
+
+ error = qoriq_clkgen_create_sysclk(dev);
+ if (error != 0) {
+ device_printf(dev, "Cannot create sysclk.\n");
+ return (error);
+ }
+
+ error = qoriq_clk_pll_register(sc->clkdom, sc->pltfrm_pll_def);
+ if (error != 0) {
+ device_printf(dev, "Cannot create platform PLL.\n");
+ return (error);
+ }
+
+ for (i = 0; i < sc->cga_pll_num; i++) {
+ error = qoriq_clk_pll_register(sc->clkdom, sc->cga_pll[i]);
+ if (error != 0) {
+ device_printf(dev, "Cannot create CGA PLLs\n.");
+ return (error);
+ }
+ }
+
+ /*
+ * Both CMUX and HWACCEL multiplexer nodes can be represented
+ * by using built in clk_mux nodes.
+ */
+ for (i = 0; i < sc->mux_num; i++) {
+ error = clknode_mux_register(sc->clkdom, sc->mux[i]);
+ if (error != 0) {
+ device_printf(dev, "Cannot create MUX nodes.\n");
+ return (error);
+ }
+ }
+
+ if (sc->init_func != NULL) {
+ error = sc->init_func(dev);
+ if (error) {
+ device_printf(dev, "Clock init function failed.\n");
+ return (error);
+ }
+ }
+
+ clkdom_set_ofw_mapper(sc->clkdom, qoriq_clkgen_ofw_mapper);
+
+ if (clkdom_finit(sc->clkdom) != 0)
+ panic("Cannot finalize clock domain initialization.\n");
+
+ if (bootverbose)
+ clkdom_dump(sc->clkdom);
+
+ return (0);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 7, 10:55 AM (4 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41548264
Default Alt Text
D24351.1794048936.diff (16 KB)
Attached To
Mode
D24351: Add QorIQ platform clockgen driver.
Attached
Detach File
Event Timeline