Changeset View
Changeset View
Standalone View
Standalone View
sys/arm/ti/ti_prcm.c
Show All 34 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 <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/malloc.h> | #include <sys/mutex.h> | ||||
#include <sys/rman.h> | #include <sys/rman.h> | ||||
#include <sys/timeet.h> | |||||
#include <sys/timetc.h> | |||||
#include <sys/watchdog.h> | |||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#include <machine/cpu.h> | |||||
#include <machine/intr.h> | |||||
#include <arm/ti/ti_cpuid.h> | #include <arm/ti/ti_cpuid.h> | ||||
#include <arm/ti/ti_prcm.h> | #include <arm/ti/ti_prcm.h> | ||||
#include <arm/ti/tivar.h> | #include <arm/ti/tivar.h> | ||||
#include <arm/ti/clk/clock_common.h> | |||||
#include <dev/fdt/simplebus.h> | #include <dev/fdt/simplebus.h> | ||||
#include <dev/ofw/openfirm.h> | #include <dev/ofw/openfirm.h> | ||||
#include <dev/ofw/ofw_bus.h> | #include <dev/ofw/ofw_bus.h> | ||||
#include <dev/ofw/ofw_bus_subr.h> | #include <dev/ofw/ofw_bus_subr.h> | ||||
#include <dev/extres/clk/clk.h> | |||||
#include <dev/extres/clk/clk_link.h> | |||||
#include <dev/extres/syscon/syscon.h> | |||||
#include <dev/extres/syscon/syscon_generic.h> | |||||
#include "syscon_if.h" | |||||
#include "clkdev_if.h" | #include "clkdev_if.h" | ||||
#if 0 | #if 0 | ||||
#define DPRINTF(dev, msg...) device_printf(dev, msg) | #define DPRINTF(dev, msg...) device_printf(dev, msg) | ||||
#else | #else | ||||
#define DPRINTF(dev, msg...) | #define DPRINTF(dev, msg...) | ||||
#endif | #endif | ||||
struct ti_prcm_softc { | static device_t ti_prcm_dev; | ||||
struct simplebus_softc sc_simplebus; | |||||
device_t dev; | |||||
struct resource * mem_res; | |||||
bus_space_tag_t bst; | |||||
bus_space_handle_t bsh; | |||||
int attach_done; | |||||
struct mtx mtx; | |||||
}; | |||||
static struct ti_prcm_softc *ti_prcm_sc = NULL; | |||||
static void omap4_prcm_reset(void); | static void omap4_prcm_reset(void); | ||||
static void am335x_prcm_reset(void); | static void am335x_prcm_reset(void); | ||||
#define TI_AM3_PRCM 18 | #define TI_AM3_PRCM 18 | ||||
#define TI_AM4_PRCM 17 | #define TI_AM4_PRCM 17 | ||||
#define TI_OMAP2_PRCM 16 | #define TI_OMAP2_PRCM 16 | ||||
#define TI_OMAP3_PRM 15 | #define TI_OMAP3_PRM 15 | ||||
#define TI_OMAP3_CM 14 | #define TI_OMAP3_CM 14 | ||||
#define TI_OMAP4_CM1 13 | #define TI_OMAP4_CM1 13 | ||||
#define TI_OMAP4_PRM 12 | #define TI_OMAP4_PRM 12 | ||||
#define TI_OMAP4_CM2 11 | #define TI_OMAP4_CM2 11 | ||||
#define TI_OMAP4_SCRM 10 | #define TI_OMAP4_SCRM 10 | ||||
#define TI_OMAP5_PRM 9 | #define TI_OMAP5_PRM 9 | ||||
#define TI_OMAP5_CM_CORE_AON 8 | #define TI_OMAP5_CM_CORE_AON 8 | ||||
#define TI_OMAP5_SCRM 7 | #define TI_OMAP5_SCRM 7 | ||||
#define TI_OMAP5_CM_CORE 6 | #define TI_OMAP5_CM_CORE 6 | ||||
#define TI_DRA7_PRM 5 | #define TI_DRA7_PRM 5 | ||||
#define TI_DRA7_CM_CORE_AON 4 | #define TI_DRA7_CM_CORE_AON 4 | ||||
#define TI_DRA7_CM_CORE 3 | #define TI_DRA7_CM_CORE 3 | ||||
#define TI_DM814_PRCM 2 | #define TI_DM814_PRCM 2 | ||||
#define TI_DM816_PRCM 1 | #define TI_DM816_PRCM 1 | ||||
#define TI_PRCM_END 0 | #define TI_PRCM_END 0 | ||||
static struct ofw_compat_data compat_data[] = { | static struct ofw_compat_data compat_data[] = { | ||||
{ "ti,am3-prcm", TI_AM3_PRCM }, | { "ti,am3-prcm", TI_AM3_PRCM }, | ||||
{ "ti,am4-prcm", TI_AM4_PRCM }, | { "ti,am4-prcm", TI_AM4_PRCM }, | ||||
{ "ti,omap2-prcm", TI_OMAP2_PRCM }, | { "ti,omap2-prcm", TI_OMAP2_PRCM }, | ||||
{ "ti,omap3-prm", TI_OMAP3_PRM }, | { "ti,omap3-prm", TI_OMAP3_PRM }, | ||||
{ "ti,omap3-cm", TI_OMAP3_CM }, | { "ti,omap3-cm", TI_OMAP3_CM }, | ||||
{ "ti,omap4-cm1", TI_OMAP4_CM1 }, | { "ti,omap4-cm1", TI_OMAP4_CM1 }, | ||||
{ "ti,omap4-prm", TI_OMAP4_PRM }, | { "ti,omap4-prm", TI_OMAP4_PRM }, | ||||
{ "ti,omap4-cm2", TI_OMAP4_CM2 }, | { "ti,omap4-cm2", TI_OMAP4_CM2 }, | ||||
{ "ti,omap4-scrm", TI_OMAP4_SCRM }, | { "ti,omap4-scrm", TI_OMAP4_SCRM }, | ||||
{ "ti,omap5-prm", TI_OMAP5_PRM }, | { "ti,omap5-prm", TI_OMAP5_PRM }, | ||||
{ "ti,omap5-cm-core-aon", TI_OMAP5_CM_CORE_AON }, | { "ti,omap5-cm-core-aon", TI_OMAP5_CM_CORE_AON }, | ||||
{ "ti,omap5-scrm", TI_OMAP5_SCRM }, | { "ti,omap5-scrm", TI_OMAP5_SCRM }, | ||||
{ "ti,omap5-cm-core", TI_OMAP5_CM_CORE }, | { "ti,omap5-cm-core", TI_OMAP5_CM_CORE }, | ||||
{ "ti,dra7-prm", TI_DRA7_PRM }, | { "ti,dra7-prm", TI_DRA7_PRM }, | ||||
{ "ti,dra7-cm-core-aon", TI_DRA7_CM_CORE_AON }, | { "ti,dra7-cm-core-aon", TI_DRA7_CM_CORE_AON }, | ||||
{ "ti,dra7-cm-core", TI_DRA7_CM_CORE }, | { "ti,dra7-cm-core", TI_DRA7_CM_CORE }, | ||||
{ "ti,dm814-prcm", TI_DM814_PRCM }, | { "ti,dm814-prcm", TI_DM814_PRCM }, | ||||
{ "ti,dm816-prcm", TI_DM816_PRCM }, | { "ti,dm816-prcm", TI_DM816_PRCM }, | ||||
{ NULL, TI_PRCM_END} | { NULL, TI_PRCM_END} | ||||
}; | }; | ||||
static struct clk_link_def scm_clocks[] = { | |||||
LINK("sys_clkin_ck@40"), | |||||
LINK("adc_tsc_fck"), | |||||
LINK("dcan0_fck"), | |||||
LINK("dcan1_fck"), | |||||
LINK("mcasp0_fck"), | |||||
LINK("mcasp1_fck"), | |||||
LINK("smartreflex0_fck"), | |||||
LINK("smartreflex1_fck"), | |||||
LINK("sha0_fck"), | |||||
LINK("aes0_fck"), | |||||
LINK("rng_fck"), | |||||
LINK("ehrpwm0_tbclk@44e10664"), | |||||
LINK("ehrpwm1_tbclk@44e10664"), | |||||
LINK("ehrpwm2_tbclk@44e10664"), | |||||
}; | |||||
static struct clk_link_def per_cm_0[] = { | |||||
/* reg = <0x38 0x2c>, <0x6c 0x28>, <0xac 0xc>, | |||||
<0xc0 0x1c>, <0xec 0xc>, <0x10c 0x8>, <0x130 0x4>; */ | |||||
/* <0x38 0x2c> */ | |||||
LINK("l4ls-clkctrl@38_0"), | |||||
LINK("l4ls-clkctrl@38_4"), | |||||
LINK("l4ls-clkctrl@38_8"), | |||||
LINK("l4ls-clkctrl@38_c"), | |||||
LINK("l4ls-clkctrl@38_10"), | |||||
LINK("l4ls-clkctrl@38_14"), | |||||
LINK("l4ls-clkctrl@38_18"), | |||||
LINK("l4ls-clkctrl@38_1c"), | |||||
LINK("l4ls-clkctrl@38_20"), | |||||
LINK("l4ls-clkctrl@38_24"), | |||||
LINK("l4ls-clkctrl@38_28"), | |||||
/* <0x6c 0x28> */ | |||||
LINK("l4ls-clkctrl@38_34"), | |||||
LINK("l4ls-clkctrl@38_38"), | |||||
LINK("l4ls-clkctrl@38_3c"), | |||||
LINK("l4ls-clkctrl@38_40"), | |||||
LINK("l4ls-clkctrl@38_44"), | |||||
LINK("l4ls-clkctrl@38_48"), | |||||
LINK("l4ls-clkctrl@38_4c"), | |||||
LINK("l4ls-clkctrl@38_50"), | |||||
LINK("l4ls-clkctrl@38_54"), | |||||
LINK("l4ls-clkctrl@38_58"), | |||||
/* <0xac 0xc> */ | |||||
LINK("l4ls-clkctrl@38_74"), | |||||
LINK("l4ls-clkctrl@38_75"), | |||||
LINK("l4ls-clkctrl@38_78"), | |||||
LINK("l4ls-clkctrl@38_79"), | |||||
LINK("l4ls-clkctrl@38_7c"), | |||||
LINK("l4ls-clkctrl@38_7d"), | |||||
/* <0xc0 0x1c> */ | |||||
LINK("l4ls-clkctrl@38_88"), | |||||
LINK("l4ls-clkctrl@38_8c"), | |||||
LINK("l4ls-clkctrl@38_90"), | |||||
LINK("l4ls-clkctrl@38_94"), | |||||
LINK("l4ls-clkctrl@38_98"), | |||||
LINK("l4ls-clkctrl@38_9c"), | |||||
LINK("l4ls-clkctrl@38_a0"), | |||||
/* <0xec 0xc> */ | |||||
LINK("l4ls-clkctrl@38_b4"), | |||||
LINK("l4ls-clkctrl@38_b8"), | |||||
LINK("l4ls-clkctrl@38_bc"), | |||||
/* <0xd4 0x8> */ | |||||
LINK("l4ls-clkctrl@38_d4"), | |||||
LINK("l4ls-clkctrl@38_d8"), | |||||
/* <0x130 0x4> */ | |||||
LINK("l4ls-clkctrl@38_f8"), | |||||
/* reg = <0x1c 0x4>, <0x30 0x8>, <0x68 0x4>, <0xf8 0x4> */ | |||||
/* <0x1c 0x4> */ | |||||
LINK("l3s-clkctrl@1c_0"), | |||||
/* <0x30 0x8> */ | |||||
LINK("l3s-clkctrl@1c_14"), | |||||
LINK("l3s-clkctrl@1c_18"), | |||||
/* <0x68 0x4> */ | |||||
LINK("l3s-clkctrl@1c_4c"), | |||||
/* <0xf8 0x4> */ | |||||
LINK("l3s-clkctrl@1c_dc"), | |||||
/* reg = <0x24 0xc>, <0x94 0x10>, <0xbc 0x4>, <0xdc 0x8>, <0xfc 0x8>; */ | |||||
/* <0x24 0xc> */ | |||||
LINK("l3-clkctrl@24_0"), | |||||
LINK("l3-clkctrl@24_4"), | |||||
LINK("l3-clkctrl@24_8"), | |||||
/* <0x94 0x10> */ | |||||
LINK("l3-clkctrl@24_70"), | |||||
LINK("l3-clkctrl@24_74"), | |||||
LINK("l3-clkctrl@24_78"), | |||||
LINK("l3-clkctrl@24_7c"), | |||||
/* <0xbc 0x4> */ | |||||
LINK("l3-clkctrl@24_98"), | |||||
/* <0xdc 0x8> */ | |||||
LINK("l3-clkctrl@24_b8"), | |||||
LINK("l3-clkctrl@24_bc"), | |||||
/* <0xfc 0x8> */ | |||||
LINK("l3-clkctrl@24_d8"), | |||||
LINK("l3-clkctrl@24_dc"), | |||||
/* reg = <0x120 0x4>; */ | |||||
LINK("l4hs-clkctrl@120_0"), | |||||
/* reg = <0xe8 0x4>; */ | |||||
LINK("pruss-ocp-clkctrl@e8_0"), | |||||
/* reg = <0x0 0x18>; */ | |||||
LINK("cpsw-125mhz-clkctrl@0_0"), | |||||
LINK("cpsw-125mhz-clkctrl@0_4"), | |||||
LINK("cpsw-125mhz-clkctrl@0_8"), | |||||
LINK("cpsw-125mhz-clkctrl@0_c"), | |||||
LINK("cpsw-125mhz-clkctrl@0_10"), | |||||
LINK("cpsw-125mhz-clkctrl@0_14"), | |||||
/* reg = <0x18 0x4>; */ | |||||
LINK("lcdc-clkctrl@18_0"), | |||||
/* reg = <0x14c 0x4>; */ | |||||
LINK("clk-24mhz-clkctrl@14c_0"), | |||||
/* reg = <0x0 0x10>, <0xb4 0x24>; */ | |||||
/* <0x0 0x10> */ | |||||
LINK("l4-wkup-clkctrl@0_0"), | |||||
LINK("l4-wkup-clkctrl@0_4"), | |||||
LINK("l4-wkup-clkctrl@0_8"), | |||||
LINK("l4-wkup-clkctrl@0_9"), | |||||
LINK("l4-wkup-clkctrl@0_c"), | |||||
/* <0xb4 0x24> */ | |||||
LINK("l4-wkup-clkctrl@0_b4"), | |||||
LINK("l4-wkup-clkctrl@0_b8"), | |||||
LINK("l4-wkup-clkctrl@0_bc"), | |||||
LINK("l4-wkup-clkctrl@0_c0"), | |||||
LINK("l4-wkup-clkctrl@0_c4"), | |||||
LINK("l4-wkup-clkctrl@0_c8"), | |||||
LINK("l4-wkup-clkctrl@0_cc"), | |||||
LINK("l4-wkup-clkctrl@0_d0"), | |||||
LINK("l4-wkup-clkctrl@0_d4"), | |||||
/* reg = <0x14 0x4>; */ | |||||
LINK("l3-aon-clkctrl@14_0"), | |||||
/* reg = <0xb0 0x4>; */ | |||||
LINK("l4-wkup-aon-clkctrl@b0_0"), | |||||
/* reg = <0x0 0x8>; */ | |||||
LINK("mpu-clkctrl@0_0"), | |||||
LINK("mpu-clkctrl@0_4"), | |||||
/* reg = <0x0 0x4>; */ | |||||
LINK("l4-rtc-clkctrl@0_0"), | |||||
/* reg = <0x0 0x8>; */ | |||||
LINK("gfx-l3-clkctrl@0_0"), | |||||
LINK("gfx-l3-clkctrl@0_4"), | |||||
/* reg = <0x0 0x24>; */ | |||||
LINK("l4-cefuse-clkctrl@0_0"), | |||||
LINK("l4-cefuse-clkctrl@0_4"), | |||||
LINK("l4-cefuse-clkctrl@0_8"), | |||||
LINK("l4-cefuse-clkctrl@0_c"), | |||||
LINK("l4-cefuse-clkctrl@0_10"), | |||||
LINK("l4-cefuse-clkctrl@0_14"), | |||||
LINK("l4-cefuse-clkctrl@0_18"), | |||||
LINK("l4-cefuse-clkctrl@0_1c"), | |||||
LINK("l4-cefuse-clkctrl@0_20"), | |||||
}; | |||||
static int | static int | ||||
ti_prcm_probe(device_t dev) | ti_prcm_probe(device_t dev) | ||||
{ | { | ||||
int i, err; | |||||
struct clkdom *clkdom; | |||||
if (!ofw_bus_status_okay(dev)) | if (!ofw_bus_status_okay(dev)) | ||||
return (ENXIO); | return (ENXIO); | ||||
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) { | if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) | ||||
return (ENXIO); | return (ENXIO); | ||||
} | |||||
device_set_desc(dev, "TI Power and Clock Management"); | device_set_desc(dev, "TI Power and Clock Management"); | ||||
return(BUS_PROBE_DEFAULT); | |||||
} | |||||
static int | clkdom = clkdom_create(dev); | ||||
ti_prcm_attach(device_t dev) | if (clkdom == NULL) | ||||
{ | panic("Cannot create clkdom\n"); | ||||
struct ti_prcm_softc *sc; | |||||
phandle_t node, child; | |||||
int rid; | |||||
sc = device_get_softc(dev); | /* | ||||
sc->dev = dev; | * pre-create clocks to get handles to parents | ||||
* before they actually exists | |||||
node = ofw_bus_get_node(sc->dev); | */ | ||||
simplebus_init(sc->dev, node); | for (i = 0; i < nitems(scm_clocks); i++) { | ||||
err = clknode_link_register(clkdom, | |||||
if (simplebus_fill_ranges(node, &sc->sc_simplebus) < 0) { | &scm_clocks[i]); | ||||
device_printf(sc->dev, "could not get ranges\n"); | if (err != 0) | ||||
return (ENXIO); | device_printf(dev, "Cant create clock link %s\n", | ||||
scm_clocks[i].clkdef.name); | |||||
} | } | ||||
if (sc->sc_simplebus.nranges == 0) { | for (i = 0; i < nitems(per_cm_0); i++) { | ||||
device_printf(sc->dev, "nranges == 0\n"); | err = clknode_link_register(clkdom, | ||||
return (ENXIO); | &per_cm_0[i]); | ||||
if (err != 0) | |||||
device_printf(dev, "Cant create clock link %s\n", | |||||
per_cm_0[i].clkdef.name); | |||||
} | } | ||||
sc->mem_res = bus_alloc_resource(sc->dev, SYS_RES_MEMORY, &rid, | if (clkdom_finit(clkdom) != 0) | ||||
sc->sc_simplebus.ranges[0].host, | panic("cannot finalize clkdom initialization\n"); | ||||
(sc->sc_simplebus.ranges[0].host + | |||||
sc->sc_simplebus.ranges[0].size - 1), | |||||
sc->sc_simplebus.ranges[0].size, | |||||
RF_ACTIVE | RF_SHAREABLE); | |||||
if (sc->mem_res == NULL) { | /* Setup reset handler */ | ||||
return (ENXIO); | ti_prcm_dev = dev; | ||||
} | |||||
sc->bst = rman_get_bustag(sc->mem_res); | |||||
sc->bsh = rman_get_bushandle(sc->mem_res); | |||||
mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF); | |||||
/* Fixme: for xxx_prcm_reset functions. | |||||
* Get rid of global variables? | |||||
*/ | |||||
ti_prcm_sc = sc; | |||||
switch(ti_chip()) { | switch(ti_chip()) { | ||||
#ifdef SOC_OMAP4 | #ifdef SOC_OMAP4 | ||||
case CHIP_OMAP_4: | case CHIP_OMAP_4: | ||||
ti_cpu_reset = omap4_prcm_reset; | ti_cpu_reset = omap4_prcm_reset; | ||||
break; | break; | ||||
#endif | #endif | ||||
#ifdef SOC_TI_AM335X | #ifdef SOC_TI_AM335X | ||||
case CHIP_AM335X: | case CHIP_AM335X: | ||||
ti_cpu_reset = am335x_prcm_reset; | ti_cpu_reset = am335x_prcm_reset; | ||||
break; | break; | ||||
#endif | #endif | ||||
} | } | ||||
bus_generic_probe(sc->dev); | return (BUS_PROBE_DEFAULT); | ||||
for (child = OF_child(node); child != 0; child = OF_peer(child)) { | |||||
simplebus_add_device(dev, child, 0, NULL, -1, NULL); | |||||
} | } | ||||
return (bus_generic_attach(sc->dev)); | |||||
} | |||||
int | int | ||||
ti_prcm_write_4(device_t dev, bus_addr_t addr, uint32_t val) | ti_prcm_write_4(device_t dev, bus_addr_t addr, uint32_t val) | ||||
{ | { | ||||
struct ti_prcm_softc *sc; | struct syscon_generic_softc *sc; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
DPRINTF(sc->dev, "offset=%lx write %x\n", addr, val); | DPRINTF(sc->dev, "ti_prcm_write_4: offset=%lx write %x\n", addr, val); | ||||
bus_space_write_4(sc->bst, sc->bsh, addr, val); | return (SYSCON_UNLOCKED_WRITE_4(sc->syscon, addr, val)); | ||||
return (0); | |||||
} | } | ||||
int | int | ||||
ti_prcm_read_4(device_t dev, bus_addr_t addr, uint32_t *val) | ti_prcm_read_4(device_t dev, bus_addr_t addr, uint32_t *val) | ||||
{ | { | ||||
struct ti_prcm_softc *sc; | struct syscon_generic_softc *sc; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
*val = SYSCON_UNLOCKED_READ_4(sc->syscon, addr); | |||||
*val = bus_space_read_4(sc->bst, sc->bsh, addr); | |||||
DPRINTF(sc->dev, "offset=%lx Read %x\n", addr, *val); | DPRINTF(sc->dev, "offset=%lx Read %x\n", addr, *val); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
ti_prcm_modify_4(device_t dev, bus_addr_t addr, uint32_t clr, uint32_t set) | ti_prcm_modify_4(device_t dev, bus_addr_t addr, uint32_t clr, uint32_t set) | ||||
{ | { | ||||
struct ti_prcm_softc *sc; | struct syscon_generic_softc *sc; | ||||
uint32_t reg; | |||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
DPRINTF(sc->dev, "ti_prcm_modify_4: addr %x clear_mask %x set_mask %x\n", | |||||
reg = bus_space_read_4(sc->bst, sc->bsh, addr); | addr, clr, set); | ||||
reg &= ~clr; | return (SYSCON_UNLOCKED_MODIFY_4(sc->syscon, addr, clr, | ||||
reg |= set; | set)); | ||||
bus_space_write_4(sc->bst, sc->bsh, addr, reg); | |||||
DPRINTF(sc->dev, "offset=%lx reg: %x (clr %x set %x)\n", addr, reg, clr, set); | |||||
return (0); | |||||
} | } | ||||
void | void | ||||
ti_prcm_device_lock(device_t dev) | ti_prcm_device_lock(device_t dev) | ||||
{ | { | ||||
struct ti_prcm_softc *sc; | struct syscon_generic_softc *sc; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
mtx_lock(&sc->mtx); | DPRINTF(sc->dev, "ti_prcm_device_lock\n"); | ||||
SYSCON_DEVICE_LOCK(sc->syscon->pdev); | |||||
} | } | ||||
void | void | ||||
ti_prcm_device_unlock(device_t dev) | ti_prcm_device_unlock(device_t dev) | ||||
{ | { | ||||
struct ti_prcm_softc *sc; | struct syscon_generic_softc *sc; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
mtx_unlock(&sc->mtx); | DPRINTF(sc->dev, "ti_prcm_device_unlock\n"); | ||||
SYSCON_DEVICE_UNLOCK(sc->syscon->pdev); | |||||
} | } | ||||
static int | |||||
ti_prcm_get_handle(device_t dev, struct syscon **syscon) | |||||
{ | |||||
struct syscon_generic_softc *sc; | |||||
sc = device_get_softc(dev); | |||||
*syscon = sc->syscon; | |||||
if (*syscon == NULL) | |||||
return (ENODEV); | |||||
return (0); | |||||
} | |||||
static device_method_t ti_prcm_methods[] = { | static device_method_t ti_prcm_methods[] = { | ||||
/* Device interface */ | |||||
DEVMETHOD(device_probe, ti_prcm_probe), | DEVMETHOD(device_probe, ti_prcm_probe), | ||||
DEVMETHOD(device_attach, ti_prcm_attach), | |||||
/* Syscon */ | |||||
DEVMETHOD(syscon_get_handle, ti_prcm_get_handle), | |||||
/* clkdev interface */ | /* clkdev interface */ | ||||
DEVMETHOD(clkdev_write_4, ti_prcm_write_4), | DEVMETHOD(clkdev_write_4, ti_prcm_write_4), | ||||
DEVMETHOD(clkdev_read_4, ti_prcm_read_4), | DEVMETHOD(clkdev_read_4, ti_prcm_read_4), | ||||
DEVMETHOD(clkdev_modify_4, ti_prcm_modify_4), | DEVMETHOD(clkdev_modify_4, ti_prcm_modify_4), | ||||
DEVMETHOD(clkdev_device_lock, ti_prcm_device_lock), | DEVMETHOD(clkdev_device_lock, ti_prcm_device_lock), | ||||
DEVMETHOD(clkdev_device_unlock, ti_prcm_device_unlock), | DEVMETHOD(clkdev_device_unlock, ti_prcm_device_unlock), | ||||
DEVMETHOD_END | DEVMETHOD_END | ||||
}; | }; | ||||
DEFINE_CLASS_1(ti_prcm, ti_prcm_driver, ti_prcm_methods, | DEFINE_CLASS_1(ti_prcm, ti_prcm_driver, ti_prcm_methods, | ||||
sizeof(struct ti_prcm_softc), simplebus_driver); | sizeof(struct syscon_generic_softc), syscon_generic_driver); | ||||
static devclass_t ti_prcm_devclass; | static devclass_t ti_prcm_devclass; | ||||
EARLY_DRIVER_MODULE(ti_prcm, ofwbus, ti_prcm_driver, | |||||
ti_prcm_devclass, 0, 0, BUS_PASS_BUS); | |||||
EARLY_DRIVER_MODULE(ti_prcm, simplebus, ti_prcm_driver, | EARLY_DRIVER_MODULE(ti_prcm, simplebus, ti_prcm_driver, | ||||
ti_prcm_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); | ti_prcm_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); | ||||
MODULE_VERSION(ti_prcm, 1); | MODULE_VERSION(ti_prcm, 1); | ||||
MODULE_DEPEND(ti_prcm, ti_scm, 1, 1, 1); | MODULE_DEPEND(ti_prcm, syscon_generic_dev, 1, 1, 1); | ||||
/* From sys/arm/ti/am335x/am335x_prcm.c | /* From sys/arm/ti/am335x/am335x_prcm.c | ||||
* Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org> | * Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org> | ||||
*/ | */ | ||||
#define PRM_DEVICE_OFFSET 0xF00 | #define PRM_DEVICE_OFFSET 0xF00 | ||||
#define AM335x_PRM_RSTCTRL (PRM_DEVICE_OFFSET + 0x00) | #define AM335x_PRM_RSTCTRL (PRM_DEVICE_OFFSET + 0x00) | ||||
static void | static void | ||||
am335x_prcm_reset(void) | am335x_prcm_reset(void) | ||||
{ | { | ||||
ti_prcm_write_4(ti_prcm_sc->dev, AM335x_PRM_RSTCTRL, (1<<1)); | ti_prcm_device_lock(ti_prcm_dev); | ||||
ti_prcm_write_4(ti_prcm_dev, AM335x_PRM_RSTCTRL, (1<<1)); | |||||
ti_prcm_device_unlock(ti_prcm_dev); | |||||
} | } | ||||
/* FIXME: Is this correct - or should the license part be ontop? */ | /* FIXME: Is this correct - or should the license part be ontop? */ | ||||
/* From sys/arm/ti/omap4/omap4_prcm_clks.c */ | /* From sys/arm/ti/omap4/omap4_prcm_clks.c */ | ||||
/*- | /*- | ||||
* SPDX-License-Identifier: BSD-3-Clause | * SPDX-License-Identifier: BSD-3-Clause | ||||
* | * | ||||
Show All 27 Lines | |||||
#define PRM_RSTCTRL 0x1b00 | #define PRM_RSTCTRL 0x1b00 | ||||
#define PRM_RSTCTRL_RESET 0x2 | #define PRM_RSTCTRL_RESET 0x2 | ||||
static void | static void | ||||
omap4_prcm_reset(void) | omap4_prcm_reset(void) | ||||
{ | { | ||||
uint32_t reg; | uint32_t reg; | ||||
ti_prcm_read_4(ti_prcm_sc->dev, PRM_RSTCTRL, ®); | ti_prcm_device_lock(ti_prcm_dev); | ||||
ti_prcm_read_4(ti_prcm_dev, PRM_RSTCTRL, ®); | |||||
reg = reg | PRM_RSTCTRL_RESET; | reg = reg | PRM_RSTCTRL_RESET; | ||||
ti_prcm_write_4(ti_prcm_sc->dev, PRM_RSTCTRL, reg); | ti_prcm_write_4(ti_prcm_dev, PRM_RSTCTRL, reg); | ||||
ti_prcm_read_4(ti_prcm_sc->dev, PRM_RSTCTRL, ®); | ti_prcm_read_4(ti_prcm_dev, PRM_RSTCTRL, ®); | ||||
ti_prcm_device_unlock(ti_prcm_dev); | |||||
} | } |