Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm64/rockchip/clk/rk_clk_composite.c
Show All 29 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/bus.h> | #include <sys/bus.h> | ||||
#include <dev/extres/clk/clk.h> | #include <dev/extres/clk/clk.h> | ||||
#include <dev/extres/syscon/syscon.h> | |||||
#include <arm64/rockchip/clk/rk_clk_composite.h> | #include <arm64/rockchip/clk/rk_clk_composite.h> | ||||
#include "clkdev_if.h" | #include "clkdev_if.h" | ||||
#include "syscon_if.h" | |||||
struct rk_clk_composite_sc { | struct rk_clk_composite_sc { | ||||
uint32_t muxdiv_offset; | uint32_t muxdiv_offset; | ||||
uint32_t mux_shift; | uint32_t mux_shift; | ||||
uint32_t mux_width; | uint32_t mux_width; | ||||
uint32_t mux_mask; | uint32_t mux_mask; | ||||
uint32_t div_shift; | uint32_t div_shift; | ||||
uint32_t div_width; | uint32_t div_width; | ||||
uint32_t div_mask; | uint32_t div_mask; | ||||
uint32_t gate_offset; | uint32_t gate_offset; | ||||
uint32_t gate_shift; | uint32_t gate_shift; | ||||
uint32_t flags; | uint32_t flags; | ||||
struct syscon *grf; | |||||
}; | }; | ||||
#define WRITE4(_clk, off, val) \ | #define WRITE4(_clk, off, val) \ | ||||
CLKDEV_WRITE_4(clknode_get_device(_clk), off, val) | rk_clk_composite_write_4(_clk, off, val) | ||||
#define READ4(_clk, off, val) \ | #define READ4(_clk, off, val) \ | ||||
CLKDEV_READ_4(clknode_get_device(_clk), off, val) | rk_clk_composite_read_4(_clk, off, val) | ||||
#define DEVICE_LOCK(_clk) \ | #define DEVICE_LOCK(_clk) \ | ||||
CLKDEV_DEVICE_LOCK(clknode_get_device(_clk)) | CLKDEV_DEVICE_LOCK(clknode_get_device(_clk)) | ||||
#define DEVICE_UNLOCK(_clk) \ | #define DEVICE_UNLOCK(_clk) \ | ||||
CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk)) | CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk)) | ||||
#define RK_CLK_COMPOSITE_MASK_SHIFT 16 | #define RK_CLK_COMPOSITE_MASK_SHIFT 16 | ||||
#if 0 | #if 0 | ||||
#define dprintf(format, arg...) \ | #define dprintf(format, arg...) \ | ||||
printf("%s:(%s)" format, __func__, clknode_get_name(clk), arg) | printf("%s:(%s)" format, __func__, clknode_get_name(clk), arg) | ||||
#else | #else | ||||
#define dprintf(format, arg...) | #define dprintf(format, arg...) | ||||
#endif | #endif | ||||
static void | |||||
rk_clk_composite_read_4(struct clknode *clk, bus_addr_t addr, uint32_t *val) | |||||
{ | |||||
struct rk_clk_composite_sc *sc; | |||||
sc = clknode_get_softc(clk); | |||||
if (sc->grf) | |||||
*val = SYSCON_READ_4(sc->grf, addr); | |||||
else | |||||
CLKDEV_READ_4(clknode_get_device(clk), addr, val); | |||||
} | |||||
static void | |||||
rk_clk_composite_write_4(struct clknode *clk, bus_addr_t addr, uint32_t val) | |||||
{ | |||||
struct rk_clk_composite_sc *sc; | |||||
sc = clknode_get_softc(clk); | |||||
if (sc->grf) | |||||
SYSCON_WRITE_4(sc->grf, addr, val | (0xffff << 16)); | |||||
else | |||||
CLKDEV_WRITE_4(clknode_get_device(clk), addr, val); | |||||
} | |||||
static struct syscon * | |||||
rk_clk_composite_get_grf(struct clknode *clk) | |||||
{ | |||||
device_t dev; | |||||
phandle_t node; | |||||
struct syscon *grf; | |||||
grf = NULL; | |||||
dev = clknode_get_device(clk); | |||||
node = ofw_bus_get_node(dev); | |||||
if (OF_hasprop(node, "rockchip,grf") && | |||||
syscon_get_by_ofw_property(dev, node, | |||||
"rockchip,grf", &grf) != 0) { | |||||
return (NULL); | |||||
} | |||||
return (grf); | |||||
} | |||||
static int | static int | ||||
rk_clk_composite_init(struct clknode *clk, device_t dev) | rk_clk_composite_init(struct clknode *clk, device_t dev) | ||||
{ | { | ||||
struct rk_clk_composite_sc *sc; | struct rk_clk_composite_sc *sc; | ||||
uint32_t val, idx; | uint32_t val, idx; | ||||
sc = clknode_get_softc(clk); | sc = clknode_get_softc(clk); | ||||
if ((sc->flags & RK_CLK_COMPOSITE_GRF) != 0) { | |||||
sc->grf = rk_clk_composite_get_grf(clk); | |||||
if (sc->grf == NULL) | |||||
panic("clock %s has GRF flag set but no syscon is available", | |||||
clknode_get_name(clk)); | |||||
} | |||||
idx = 0; | idx = 0; | ||||
if ((sc->flags & RK_CLK_COMPOSITE_HAVE_MUX) != 0) { | if ((sc->flags & RK_CLK_COMPOSITE_HAVE_MUX) != 0) { | ||||
DEVICE_LOCK(clk); | DEVICE_LOCK(clk); | ||||
READ4(clk, sc->muxdiv_offset, &val); | READ4(clk, sc->muxdiv_offset, &val); | ||||
DEVICE_UNLOCK(clk); | DEVICE_UNLOCK(clk); | ||||
idx = (val & sc->mux_mask) >> sc->mux_shift; | idx = (val & sc->mux_mask) >> sc->mux_shift; | ||||
▲ Show 20 Lines • Show All 226 Lines • Show Last 20 Lines |