Commit 2b1ee306 authored by Olof Johansson's avatar Olof Johansson

Merge tag 'omap-for-v4.13/soc-v4-signed' of...

Merge tag 'omap-for-v4.13/soc-v4-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/soc

SoC changes for omap variants for v4.13 merge window:

- PM clean-up in preparation of adding am335x/am437x PM support

- Fixes for issues found by Coccinelle

- Legacy code removal now that everything boots in device
  tree only mode

- Interconnect changes in preparation of moving clkctrl clocks
  to be managed by clkctrl clock driver

- Interconnect changes to add omap4 crypto acceclerator
  support

* tag 'omap-for-v4.13/soc-v4-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: (27 commits)
  ARM: OMAP4: hwmod_data: add SHAM crypto accelerator
  ARM: OMAP4: hwmod data: add des
  ARM: OMAP4: hwmod data: add aes2
  ARM: OMAP4: hwmod data: add aes1
  ARM: OMAP2+: Remove unused legacy code for n8x0
  ARM: OMAP2+: Remove unused legacy code for watchdog
  ARM: OMAP2+: Remove unused legacy code for interconnects
  ARM: OMAP2+: Remove unused legacy code for PRM
  ARM: OMAP2+: Remove unused legacy code for io.c
  ARM: OMAP2+: Remove unused legacy code for McBSP
  ARM: OMAP2+: SmartReflex: Delete an error message for a failed memory allocation in two functions
  ARM: OMAP2+: Use kcalloc() in sr_set_nvalues()
  ARM: OMAP2+: Improve a size determination in sr_dev_init()
  ARM: OMAP2+: Delete an error message for a failed memory allocation in two functions
  ARM: OMAP2+: Remove unused legacy code for device init
  ARM: OMAP2+: Remove unused legacy code for PMU
  ARM: OMAP2+: Remove unused legacy code for opp
  ARM: OMAP2+: hwmod: populate clkctrl clocks for hwmods if available
  ARM: OMAP4: cminst: add support for clkdm_xlate_address
  ARM: omap2+: clockdomain: add clkdm_xlate_address
  ...
Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents 6198c749 1df5eaa6
...@@ -69,7 +69,6 @@ obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o ...@@ -69,7 +69,6 @@ obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
# OPP table initialization # OPP table initialization
ifeq ($(CONFIG_PM_OPP),y) ifeq ($(CONFIG_PM_OPP),y)
obj-y += opp.o
obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o
obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o
endif endif
...@@ -220,9 +219,6 @@ obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o ...@@ -220,9 +219,6 @@ obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o
obj-$(CONFIG_SOC_OMAP5) += omap_hwmod_54xx_data.o obj-$(CONFIG_SOC_OMAP5) += omap_hwmod_54xx_data.o
obj-$(CONFIG_SOC_DRA7XX) += omap_hwmod_7xx_data.o obj-$(CONFIG_SOC_DRA7XX) += omap_hwmod_7xx_data.o
# EMU peripherals
obj-$(CONFIG_HW_PERF_EVENTS) += pmu.o
# OMAP2420 MSDI controller integration support ("MMC") # OMAP2420 MSDI controller integration support ("MMC")
obj-$(CONFIG_SOC_OMAP2420) += msdi.o obj-$(CONFIG_SOC_OMAP2420) += msdi.o
......
...@@ -53,14 +53,12 @@ static u32 board_caps; ...@@ -53,14 +53,12 @@ static u32 board_caps;
static void board_check_revision(void) static void board_check_revision(void)
{ {
if (of_have_populated_dt()) {
if (of_machine_is_compatible("nokia,n800")) if (of_machine_is_compatible("nokia,n800"))
board_caps = NOKIA_N800; board_caps = NOKIA_N800;
else if (of_machine_is_compatible("nokia,n810")) else if (of_machine_is_compatible("nokia,n810"))
board_caps = NOKIA_N810; board_caps = NOKIA_N810;
else if (of_machine_is_compatible("nokia,n810-wimax")) else if (of_machine_is_compatible("nokia,n810-wimax"))
board_caps = NOKIA_N810_WIMAX; board_caps = NOKIA_N810_WIMAX;
}
if (!board_caps) if (!board_caps)
pr_err("Unknown board\n"); pr_err("Unknown board\n");
......
...@@ -1224,6 +1224,14 @@ int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) ...@@ -1224,6 +1224,14 @@ int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
return 0; return 0;
} }
u32 clkdm_xlate_address(struct clockdomain *clkdm)
{
if (arch_clkdm->clkdm_xlate_address)
return arch_clkdm->clkdm_xlate_address(clkdm);
return 0;
}
/** /**
* clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm * clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm
* @clkdm: struct clockdomain * * @clkdm: struct clockdomain *
......
...@@ -175,6 +175,7 @@ struct clkdm_ops { ...@@ -175,6 +175,7 @@ struct clkdm_ops {
void (*clkdm_deny_idle)(struct clockdomain *clkdm); void (*clkdm_deny_idle)(struct clockdomain *clkdm);
int (*clkdm_clk_enable)(struct clockdomain *clkdm); int (*clkdm_clk_enable)(struct clockdomain *clkdm);
int (*clkdm_clk_disable)(struct clockdomain *clkdm); int (*clkdm_clk_disable)(struct clockdomain *clkdm);
u32 (*clkdm_xlate_address)(struct clockdomain *clkdm);
}; };
int clkdm_register_platform_funcs(struct clkdm_ops *co); int clkdm_register_platform_funcs(struct clkdm_ops *co);
...@@ -213,6 +214,7 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); ...@@ -213,6 +214,7 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh); int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh);
int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh); int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh);
u32 clkdm_xlate_address(struct clockdomain *clkdm);
extern void __init omap242x_clockdomains_init(void); extern void __init omap242x_clockdomains_init(void);
extern void __init omap243x_clockdomains_init(void); extern void __init omap243x_clockdomains_init(void);
......
...@@ -24,8 +24,11 @@ ...@@ -24,8 +24,11 @@
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
#include <linux/clk/ti.h> #include <linux/clk/ti.h>
extern void __iomem *cm_base;
extern void __iomem *cm2_base; #include "prcm-common.h"
extern struct omap_domain_base cm_base;
extern struct omap_domain_base cm2_base;
extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2); extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2);
# endif # endif
......
...@@ -52,12 +52,12 @@ ...@@ -52,12 +52,12 @@
static inline u32 omap2_cm_read_mod_reg(s16 module, u16 idx) static inline u32 omap2_cm_read_mod_reg(s16 module, u16 idx)
{ {
return readl_relaxed(cm_base + module + idx); return readl_relaxed(cm_base.va + module + idx);
} }
static inline void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx) static inline void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx)
{ {
writel_relaxed(val, cm_base + module + idx); writel_relaxed(val, cm_base.va + module + idx);
} }
/* Read-modify-write a register in a CM module. Caller must lock */ /* Read-modify-write a register in a CM module. Caller must lock */
......
...@@ -50,13 +50,13 @@ ...@@ -50,13 +50,13 @@
/* Read a register in a CM instance */ /* Read a register in a CM instance */
static inline u32 am33xx_cm_read_reg(u16 inst, u16 idx) static inline u32 am33xx_cm_read_reg(u16 inst, u16 idx)
{ {
return readl_relaxed(cm_base + inst + idx); return readl_relaxed(cm_base.va + inst + idx);
} }
/* Write into a register in a CM */ /* Write into a register in a CM */
static inline void am33xx_cm_write_reg(u32 val, u16 inst, u16 idx) static inline void am33xx_cm_write_reg(u32 val, u16 inst, u16 idx)
{ {
writel_relaxed(val, cm_base + inst + idx); writel_relaxed(val, cm_base.va + inst + idx);
} }
/* Read-modify-write a register in CM */ /* Read-modify-write a register in CM */
......
...@@ -669,7 +669,8 @@ static struct cm_ll_data omap3xxx_cm_ll_data = { ...@@ -669,7 +669,8 @@ static struct cm_ll_data omap3xxx_cm_ll_data = {
int __init omap3xxx_cm_init(const struct omap_prcm_init_data *data) int __init omap3xxx_cm_init(const struct omap_prcm_init_data *data)
{ {
omap2_clk_legacy_provider_init(TI_CLKM_CM, cm_base + OMAP3430_IVA2_MOD); omap2_clk_legacy_provider_init(TI_CLKM_CM, cm_base.va +
OMAP3430_IVA2_MOD);
return cm_register(&omap3xxx_cm_ll_data); return cm_register(&omap3xxx_cm_ll_data);
} }
......
...@@ -32,10 +32,10 @@ static struct cm_ll_data null_cm_ll_data; ...@@ -32,10 +32,10 @@ static struct cm_ll_data null_cm_ll_data;
static struct cm_ll_data *cm_ll_data = &null_cm_ll_data; static struct cm_ll_data *cm_ll_data = &null_cm_ll_data;
/* cm_base: base virtual address of the CM IP block */ /* cm_base: base virtual address of the CM IP block */
void __iomem *cm_base; struct omap_domain_base cm_base;
/* cm2_base: base virtual address of the CM2 IP block (OMAP44xx only) */ /* cm2_base: base virtual address of the CM2 IP block (OMAP44xx only) */
void __iomem *cm2_base; struct omap_domain_base cm2_base;
#define CM_NO_CLOCKS 0x1 #define CM_NO_CLOCKS 0x1
#define CM_SINGLE_INSTANCE 0x2 #define CM_SINGLE_INSTANCE 0x2
...@@ -49,8 +49,8 @@ void __iomem *cm2_base; ...@@ -49,8 +49,8 @@ void __iomem *cm2_base;
*/ */
void __init omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2) void __init omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2)
{ {
cm_base = cm; cm_base.va = cm;
cm2_base = cm2; cm2_base.va = cm2;
} }
/** /**
...@@ -315,27 +315,34 @@ int __init omap2_cm_base_init(void) ...@@ -315,27 +315,34 @@ int __init omap2_cm_base_init(void)
struct device_node *np; struct device_node *np;
const struct of_device_id *match; const struct of_device_id *match;
struct omap_prcm_init_data *data; struct omap_prcm_init_data *data;
void __iomem *mem; struct resource res;
int ret;
struct omap_domain_base *mem = NULL;
for_each_matching_node_and_match(np, omap_cm_dt_match_table, &match) { for_each_matching_node_and_match(np, omap_cm_dt_match_table, &match) {
data = (struct omap_prcm_init_data *)match->data; data = (struct omap_prcm_init_data *)match->data;
mem = of_iomap(np, 0); ret = of_address_to_resource(np, 0, &res);
if (!mem) if (ret)
return -ENOMEM; return ret;
if (data->index == TI_CLKM_CM) if (data->index == TI_CLKM_CM)
cm_base = mem + data->offset; mem = &cm_base;
if (data->index == TI_CLKM_CM2) if (data->index == TI_CLKM_CM2)
cm2_base = mem + data->offset; mem = &cm2_base;
data->mem = mem; data->mem = ioremap(res.start, resource_size(&res));
if (mem) {
mem->pa = res.start + data->offset;
mem->va = data->mem + data->offset;
}
data->np = np; data->np = np;
if (data->init && (data->flags & CM_SINGLE_INSTANCE || if (data->init && (data->flags & CM_SINGLE_INSTANCE ||
(cm_base && cm2_base))) (cm_base.va && cm2_base.va)))
data->init(data); data->init(data);
} }
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
#define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2 #define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2
#define CLKCTRL_IDLEST_DISABLED 0x3 #define CLKCTRL_IDLEST_DISABLED 0x3
static void __iomem *_cm_bases[OMAP4_MAX_PRCM_PARTITIONS]; static struct omap_domain_base _cm_bases[OMAP4_MAX_PRCM_PARTITIONS];
/** /**
* omap_cm_base_init - Populates the cm partitions * omap_cm_base_init - Populates the cm partitions
...@@ -65,10 +65,11 @@ static void __iomem *_cm_bases[OMAP4_MAX_PRCM_PARTITIONS]; ...@@ -65,10 +65,11 @@ static void __iomem *_cm_bases[OMAP4_MAX_PRCM_PARTITIONS];
*/ */
static void omap_cm_base_init(void) static void omap_cm_base_init(void)
{ {
_cm_bases[OMAP4430_PRM_PARTITION] = prm_base; memcpy(&_cm_bases[OMAP4430_PRM_PARTITION], &prm_base, sizeof(prm_base));
_cm_bases[OMAP4430_CM1_PARTITION] = cm_base; memcpy(&_cm_bases[OMAP4430_CM1_PARTITION], &cm_base, sizeof(cm_base));
_cm_bases[OMAP4430_CM2_PARTITION] = cm2_base; memcpy(&_cm_bases[OMAP4430_CM2_PARTITION], &cm2_base, sizeof(cm2_base));
_cm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base; memcpy(&_cm_bases[OMAP4430_PRCM_MPU_PARTITION], &prcm_mpu_base,
sizeof(prcm_mpu_base));
} }
/* Private functions */ /* Private functions */
...@@ -116,8 +117,8 @@ static u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx) ...@@ -116,8 +117,8 @@ static u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx)
{ {
BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
part == OMAP4430_INVALID_PRCM_PARTITION || part == OMAP4430_INVALID_PRCM_PARTITION ||
!_cm_bases[part]); !_cm_bases[part].va);
return readl_relaxed(_cm_bases[part] + inst + idx); return readl_relaxed(_cm_bases[part].va + inst + idx);
} }
/* Write into a register in a CM instance */ /* Write into a register in a CM instance */
...@@ -125,8 +126,8 @@ static void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx) ...@@ -125,8 +126,8 @@ static void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx)
{ {
BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
part == OMAP4430_INVALID_PRCM_PARTITION || part == OMAP4430_INVALID_PRCM_PARTITION ||
!_cm_bases[part]); !_cm_bases[part].va);
writel_relaxed(val, _cm_bases[part] + inst + idx); writel_relaxed(val, _cm_bases[part].va + inst + idx);
} }
/* Read-modify-write a register in CM1. Caller must lock */ /* Read-modify-write a register in CM1. Caller must lock */
...@@ -475,6 +476,14 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm) ...@@ -475,6 +476,14 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
return 0; return 0;
} }
static u32 omap4_clkdm_xlate_address(struct clockdomain *clkdm)
{
u32 addr = _cm_bases[clkdm->prcm_partition].pa + clkdm->cm_inst +
clkdm->clkdm_offs;
return addr;
}
struct clkdm_ops omap4_clkdm_operations = { struct clkdm_ops omap4_clkdm_operations = {
.clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep, .clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep,
.clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep, .clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep,
...@@ -490,6 +499,7 @@ struct clkdm_ops omap4_clkdm_operations = { ...@@ -490,6 +499,7 @@ struct clkdm_ops omap4_clkdm_operations = {
.clkdm_deny_idle = omap4_clkdm_deny_idle, .clkdm_deny_idle = omap4_clkdm_deny_idle,
.clkdm_clk_enable = omap4_clkdm_clk_enable, .clkdm_clk_enable = omap4_clkdm_clk_enable,
.clkdm_clk_disable = omap4_clkdm_clk_disable, .clkdm_clk_disable = omap4_clkdm_clk_disable,
.clkdm_xlate_address = omap4_clkdm_xlate_address,
}; };
struct clkdm_ops am43xx_clkdm_operations = { struct clkdm_ops am43xx_clkdm_operations = {
...@@ -499,6 +509,7 @@ struct clkdm_ops am43xx_clkdm_operations = { ...@@ -499,6 +509,7 @@ struct clkdm_ops am43xx_clkdm_operations = {
.clkdm_deny_idle = omap4_clkdm_deny_idle, .clkdm_deny_idle = omap4_clkdm_deny_idle,
.clkdm_clk_enable = omap4_clkdm_clk_enable, .clkdm_clk_enable = omap4_clkdm_clk_enable,
.clkdm_clk_disable = omap4_clkdm_clk_disable, .clkdm_clk_disable = omap4_clkdm_clk_disable,
.clkdm_xlate_address = omap4_clkdm_xlate_address,
}; };
static struct cm_ll_data omap4xxx_cm_ll_data = { static struct cm_ll_data omap4xxx_cm_ll_data = {
......
...@@ -36,130 +36,6 @@ ...@@ -36,130 +36,6 @@
#define L3_MODULES_MAX_LEN 12 #define L3_MODULES_MAX_LEN 12
#define L3_MODULES 3 #define L3_MODULES 3
static int __init omap3_l3_init(void)
{
struct omap_hwmod *oh;
struct platform_device *pdev;
char oh_name[L3_MODULES_MAX_LEN];
/*
* To avoid code running on other OMAPs in
* multi-omap builds
*/
if (!(cpu_is_omap34xx()) || of_have_populated_dt())
return -ENODEV;
snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main");
oh = omap_hwmod_lookup(oh_name);
if (!oh)
pr_err("could not look up %s\n", oh_name);
pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0);
WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
return PTR_ERR_OR_ZERO(pdev);
}
omap_postcore_initcall(omap3_l3_init);
static inline void omap_init_sti(void) {}
#if IS_ENABLED(CONFIG_SPI_OMAP24XX)
#include <linux/platform_data/spi-omap2-mcspi.h>
static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused)
{
struct platform_device *pdev;
char *name = "omap2_mcspi";
struct omap2_mcspi_platform_config *pdata;
static int spi_num;
struct omap2_mcspi_dev_attr *mcspi_attrib = oh->dev_attr;
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
pr_err("Memory allocation for McSPI device failed\n");
return -ENOMEM;
}
pdata->num_cs = mcspi_attrib->num_chipselect;
switch (oh->class->rev) {
case OMAP2_MCSPI_REV:
case OMAP3_MCSPI_REV:
pdata->regs_offset = 0;
break;
case OMAP4_MCSPI_REV:
pdata->regs_offset = OMAP4_MCSPI_REG_OFFSET;
break;
default:
pr_err("Invalid McSPI Revision value\n");
kfree(pdata);
return -EINVAL;
}
spi_num++;
pdev = omap_device_build(name, spi_num, oh, pdata, sizeof(*pdata));
WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n",
name, oh->name);
kfree(pdata);
return 0;
}
static void omap_init_mcspi(void)
{
omap_hwmod_for_each_by_class("mcspi", omap_mcspi_init, NULL);
}
#else
static inline void omap_init_mcspi(void) {}
#endif
/**
* omap_init_rng - bind the RNG hwmod to the RNG omap_device
*
* Bind the RNG hwmod to the RNG omap_device. No return value.
*/
static void __init omap_init_rng(void)
{
struct omap_hwmod *oh;
struct platform_device *pdev;
oh = omap_hwmod_lookup("rng");
if (!oh)
return;
pdev = omap_device_build("omap_rng", -1, oh, NULL, 0);
WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n");
}
static void __init omap_init_sham(void)
{
struct omap_hwmod *oh;
struct platform_device *pdev;
oh = omap_hwmod_lookup("sham");
if (!oh)
return;
pdev = omap_device_build("omap-sham", -1, oh, NULL, 0);
WARN(IS_ERR(pdev), "Can't build omap_device for omap-sham\n");
}
static void __init omap_init_aes(void)
{
struct omap_hwmod *oh;
struct platform_device *pdev;
oh = omap_hwmod_lookup("aes");
if (!oh)
return;
pdev = omap_device_build("omap-aes", -1, oh, NULL, 0);
WARN(IS_ERR(pdev), "Can't build omap_device for omap-aes\n");
}
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#if IS_ENABLED(CONFIG_VIDEO_OMAP2_VOUT) #if IS_ENABLED(CONFIG_VIDEO_OMAP2_VOUT)
...@@ -185,54 +61,3 @@ int __init omap_init_vout(void) ...@@ -185,54 +61,3 @@ int __init omap_init_vout(void)
#else #else
int __init omap_init_vout(void) { return 0; } int __init omap_init_vout(void) { return 0; }
#endif #endif
/*-------------------------------------------------------------------------*/
static int __init omap2_init_devices(void)
{
/* Enable dummy states for those platforms without pinctrl support */
if (!of_have_populated_dt())
pinctrl_provide_dummies();
/* If dtb is there, the devices will be created dynamically */
if (!of_have_populated_dt()) {
/*
* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
omap_init_mcspi();
omap_init_sham();
omap_init_aes();
omap_init_rng();
}
omap_init_sti();
return 0;
}
omap_arch_initcall(omap2_init_devices);
static int __init omap_gpmc_init(void)
{
struct omap_hwmod *oh;
struct platform_device *pdev;
char *oh_name = "gpmc";
/*
* if the board boots up with a populated DT, do not
* manually add the device from this initcall
*/
if (of_have_populated_dt())
return -ENODEV;
oh = omap_hwmod_lookup(oh_name);
if (!oh) {
pr_err("Could not look up %s\n", oh_name);
return -ENODEV;
}
pdev = omap_device_build("omap-gpmc", -1, oh, NULL, 0);
WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
return PTR_ERR_OR_ZERO(pdev);
}
omap_postcore_initcall(omap_gpmc_init);
...@@ -153,7 +153,6 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, ...@@ -153,7 +153,6 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
hc_name = kzalloc(sizeof(char) * (HSMMC_NAME_LEN + 1), GFP_KERNEL); hc_name = kzalloc(sizeof(char) * (HSMMC_NAME_LEN + 1), GFP_KERNEL);
if (!hc_name) { if (!hc_name) {
pr_err("Cannot allocate memory for controller slot name\n");
kfree(hc_name); kfree(hc_name);
return -ENOMEM; return -ENOMEM;
} }
...@@ -315,10 +314,8 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo, ...@@ -315,10 +314,8 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
int res; int res;
mmc_data = kzalloc(sizeof(*mmc_data), GFP_KERNEL); mmc_data = kzalloc(sizeof(*mmc_data), GFP_KERNEL);
if (!mmc_data) { if (!mmc_data)
pr_err("Cannot allocate memory for mmc device!\n");
return; return;
}
res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data); res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data);
if (res < 0) if (res < 0)
......
...@@ -493,66 +493,38 @@ void __init omap3_init_early(void) ...@@ -493,66 +493,38 @@ void __init omap3_init_early(void)
omap2_set_globals_tap(OMAP343X_CLASS, OMAP2_L4_IO_ADDRESS(0x4830A000)); omap2_set_globals_tap(OMAP343X_CLASS, OMAP2_L4_IO_ADDRESS(0x4830A000));
omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE), omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE),
OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE)); OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE));
/* XXX: remove these once OMAP3 is DT only */
if (!of_have_populated_dt()) {
omap2_set_globals_control(
OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE));
omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE));
omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE),
NULL);
}
omap2_control_base_init(); omap2_control_base_init();
omap3xxx_check_revision(); omap3xxx_check_revision();
omap3xxx_check_features(); omap3xxx_check_features();
omap2_prcm_base_init(); omap2_prcm_base_init();
/* XXX: remove these once OMAP3 is DT only */
if (!of_have_populated_dt()) {
omap3xxx_prm_init(NULL);
omap3xxx_cm_init(NULL);
}
omap3xxx_voltagedomains_init(); omap3xxx_voltagedomains_init();
omap3xxx_powerdomains_init(); omap3xxx_powerdomains_init();
omap3xxx_clockdomains_init(); omap3xxx_clockdomains_init();
omap3xxx_hwmod_init(); omap3xxx_hwmod_init();
omap_hwmod_init_postsetup(); omap_hwmod_init_postsetup();
if (!of_have_populated_dt()) {
omap3_control_legacy_iomap_init();
if (soc_is_am35xx())
omap_clk_soc_init = am35xx_clk_legacy_init;
else if (cpu_is_omap3630())
omap_clk_soc_init = omap36xx_clk_legacy_init;
else if (omap_rev() == OMAP3430_REV_ES1_0)
omap_clk_soc_init = omap3430es1_clk_legacy_init;
else
omap_clk_soc_init = omap3430_clk_legacy_init;
}
} }
void __init omap3430_init_early(void) void __init omap3430_init_early(void)
{ {
omap3_init_early(); omap3_init_early();
if (of_have_populated_dt())
omap_clk_soc_init = omap3430_dt_clk_init; omap_clk_soc_init = omap3430_dt_clk_init;
} }
void __init omap35xx_init_early(void) void __init omap35xx_init_early(void)
{ {
omap3_init_early(); omap3_init_early();
if (of_have_populated_dt())
omap_clk_soc_init = omap3430_dt_clk_init; omap_clk_soc_init = omap3430_dt_clk_init;
} }
void __init omap3630_init_early(void) void __init omap3630_init_early(void)
{ {
omap3_init_early(); omap3_init_early();
if (of_have_populated_dt())
omap_clk_soc_init = omap3630_dt_clk_init; omap_clk_soc_init = omap3630_dt_clk_init;
} }
void __init am35xx_init_early(void) void __init am35xx_init_early(void)
{ {
omap3_init_early(); omap3_init_early();
if (of_have_populated_dt())
omap_clk_soc_init = am35xx_dt_clk_init; omap_clk_soc_init = am35xx_dt_clk_init;
} }
...@@ -628,7 +600,6 @@ void __init ti816x_init_early(void) ...@@ -628,7 +600,6 @@ void __init ti816x_init_early(void)
ti816x_clockdomains_init(); ti816x_clockdomains_init();
dm816x_hwmod_init(); dm816x_hwmod_init();
omap_hwmod_init_postsetup(); omap_hwmod_init_postsetup();
if (of_have_populated_dt())
omap_clk_soc_init = dm816x_dt_clk_init; omap_clk_soc_init = dm816x_dt_clk_init;
} }
#endif #endif
...@@ -785,7 +756,6 @@ int __init omap_clk_init(void) ...@@ -785,7 +756,6 @@ int __init omap_clk_init(void)
omap2_clk_setup_ll_ops(); omap2_clk_setup_ll_ops();
if (of_have_populated_dt()) {
ret = omap_control_init(); ret = omap_control_init();
if (ret) if (ret)
return ret; return ret;
...@@ -799,7 +769,6 @@ int __init omap_clk_init(void) ...@@ -799,7 +769,6 @@ int __init omap_clk_init(void)
ti_dt_clk_init_retry_clks(); ti_dt_clk_init_retry_clks();
ti_dt_clockdomains_setup(); ti_dt_clockdomains_setup();
}
ret = omap_clk_soc_init(); ret = omap_clk_soc_init();
......
...@@ -53,73 +53,3 @@ void __init omap3_mcbsp_init_pdata_callback( ...@@ -53,73 +53,3 @@ void __init omap3_mcbsp_init_pdata_callback(
pdata->force_ick_on = omap3_mcbsp_force_ick_on; pdata->force_ick_on = omap3_mcbsp_force_ick_on;
} }
static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
{
int id, count = 1;
char *name = "omap-mcbsp";
struct omap_hwmod *oh_device[2];
struct omap_mcbsp_platform_data *pdata = NULL;
struct platform_device *pdev;
sscanf(oh->name, "mcbsp%d", &id);
pdata = kzalloc(sizeof(struct omap_mcbsp_platform_data), GFP_KERNEL);
if (!pdata) {
pr_err("%s: No memory for mcbsp\n", __func__);
return -ENOMEM;
}
pdata->reg_step = 4;
if (oh->class->rev < MCBSP_CONFIG_TYPE2) {
pdata->reg_size = 2;
} else {
pdata->reg_size = 4;
pdata->has_ccr = true;
}
if (oh->class->rev == MCBSP_CONFIG_TYPE2) {
/* The FIFO has 128 locations */
pdata->buffer_size = 0x80;
} else if (oh->class->rev == MCBSP_CONFIG_TYPE3) {
if (id == 2)
/* The FIFO has 1024 + 256 locations */
pdata->buffer_size = 0x500;
else
/* The FIFO has 128 locations */
pdata->buffer_size = 0x80;
} else if (oh->class->rev == MCBSP_CONFIG_TYPE4) {
/* The FIFO has 128 locations for all instances */
pdata->buffer_size = 0x80;
}
if (oh->class->rev >= MCBSP_CONFIG_TYPE3)
pdata->has_wakeup = true;
oh_device[0] = oh;
if (oh->dev_attr) {
oh_device[1] = omap_hwmod_lookup((
(struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone);
pdata->force_ick_on = omap3_mcbsp_force_ick_on;
count++;
}
pdev = omap_device_build_ss(name, id, oh_device, count, pdata,
sizeof(*pdata));
kfree(pdata);
if (IS_ERR(pdev)) {
pr_err("%s: Can't build omap_device for %s:%s.\n", __func__,
name, oh->name);
return PTR_ERR(pdev);
}
return 0;
}
static int __init omap2_mcbsp_init(void)
{
if (!of_have_populated_dt())
omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL);
return 0;
}
omap_arch_initcall(omap2_mcbsp_init);
...@@ -58,6 +58,17 @@ static unsigned int irq_banks = DEFAULT_NR_REG_BANKS; ...@@ -58,6 +58,17 @@ static unsigned int irq_banks = DEFAULT_NR_REG_BANKS;
static unsigned int max_irqs = DEFAULT_IRQS; static unsigned int max_irqs = DEFAULT_IRQS;
static unsigned int omap_secure_apis; static unsigned int omap_secure_apis;
#ifdef CONFIG_CPU_PM
static unsigned int wakeupgen_context[MAX_NR_REG_BANKS];
#endif
struct omap_wakeupgen_ops {
void (*save_context)(void);
void (*restore_context)(void);
};
static struct omap_wakeupgen_ops *wakeupgen_ops;
/* /*
* Static helper functions. * Static helper functions.
*/ */
...@@ -264,6 +275,16 @@ static inline void omap5_irq_save_context(void) ...@@ -264,6 +275,16 @@ static inline void omap5_irq_save_context(void)
} }
static inline void am43xx_irq_save_context(void)
{
u32 i;
for (i = 0; i < irq_banks; i++) {
wakeupgen_context[i] = wakeupgen_readl(i, 0);
wakeupgen_writel(0, i, CPU0_ID);
}
}
/* /*
* Save WakeupGen interrupt context in SAR BANK3. Restore is done by * Save WakeupGen interrupt context in SAR BANK3. Restore is done by
* ROM code. WakeupGen IP is integrated along with GIC to manage the * ROM code. WakeupGen IP is integrated along with GIC to manage the
...@@ -280,11 +301,8 @@ static void irq_save_context(void) ...@@ -280,11 +301,8 @@ static void irq_save_context(void)
if (!sar_base) if (!sar_base)
sar_base = omap4_get_sar_ram_base(); sar_base = omap4_get_sar_ram_base();
if (wakeupgen_ops && wakeupgen_ops->save_context)
if (soc_is_omap54xx()) wakeupgen_ops->save_context();
omap5_irq_save_context();
else
omap4_irq_save_context();
} }
/* /*
...@@ -306,6 +324,20 @@ static void irq_sar_clear(void) ...@@ -306,6 +324,20 @@ static void irq_sar_clear(void)
writel_relaxed(val, sar_base + offset); writel_relaxed(val, sar_base + offset);
} }
static void am43xx_irq_restore_context(void)
{
u32 i;
for (i = 0; i < irq_banks; i++)
wakeupgen_writel(wakeupgen_context[i], i, CPU0_ID);
}
static void irq_restore_context(void)
{
if (wakeupgen_ops && wakeupgen_ops->restore_context)
wakeupgen_ops->restore_context();
}
/* /*
* Save GIC and Wakeupgen interrupt context using secure API * Save GIC and Wakeupgen interrupt context using secure API
* for HS/EMU devices. * for HS/EMU devices.
...@@ -319,6 +351,26 @@ static void irq_save_secure_context(void) ...@@ -319,6 +351,26 @@ static void irq_save_secure_context(void)
if (ret != API_HAL_RET_VALUE_OK) if (ret != API_HAL_RET_VALUE_OK)
pr_err("GIC and Wakeupgen context save failed\n"); pr_err("GIC and Wakeupgen context save failed\n");
} }
/* Define ops for context save and restore for each SoC */
static struct omap_wakeupgen_ops omap4_wakeupgen_ops = {
.save_context = omap4_irq_save_context,
.restore_context = irq_sar_clear,
};
static struct omap_wakeupgen_ops omap5_wakeupgen_ops = {
.save_context = omap5_irq_save_context,
.restore_context = irq_sar_clear,
};
static struct omap_wakeupgen_ops am43xx_wakeupgen_ops = {
.save_context = am43xx_irq_save_context,
.restore_context = am43xx_irq_restore_context,
};
#else
static struct omap_wakeupgen_ops omap4_wakeupgen_ops = {};
static struct omap_wakeupgen_ops omap5_wakeupgen_ops = {};
static struct omap_wakeupgen_ops am43xx_wakeupgen_ops = {};
#endif #endif
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
...@@ -359,7 +411,7 @@ static int irq_notifier(struct notifier_block *self, unsigned long cmd, void *v) ...@@ -359,7 +411,7 @@ static int irq_notifier(struct notifier_block *self, unsigned long cmd, void *v)
break; break;
case CPU_CLUSTER_PM_EXIT: case CPU_CLUSTER_PM_EXIT:
if (omap_type() == OMAP2_DEVICE_TYPE_GP) if (omap_type() == OMAP2_DEVICE_TYPE_GP)
irq_sar_clear(); irq_restore_context();
break; break;
} }
return NOTIFY_OK; return NOTIFY_OK;
...@@ -494,9 +546,13 @@ static int __init wakeupgen_init(struct device_node *node, ...@@ -494,9 +546,13 @@ static int __init wakeupgen_init(struct device_node *node,
irq_banks = OMAP4_NR_BANKS; irq_banks = OMAP4_NR_BANKS;
max_irqs = OMAP4_NR_IRQS; max_irqs = OMAP4_NR_IRQS;
omap_secure_apis = 1; omap_secure_apis = 1;
wakeupgen_ops = &omap4_wakeupgen_ops;
} else if (soc_is_omap54xx()) {
wakeupgen_ops = &omap5_wakeupgen_ops;
} else if (soc_is_am43xx()) { } else if (soc_is_am43xx()) {
irq_banks = AM43XX_NR_REG_BANKS; irq_banks = AM43XX_NR_REG_BANKS;
max_irqs = AM43XX_IRQS; max_irqs = AM43XX_IRQS;
wakeupgen_ops = &am43xx_wakeupgen_ops;
} }
domain = irq_domain_add_hierarchy(parent_domain, 0, max_irqs, domain = irq_domain_add_hierarchy(parent_domain, 0, max_irqs,
......
...@@ -65,7 +65,7 @@ static void _add_clkdev(struct omap_device *od, const char *clk_alias, ...@@ -65,7 +65,7 @@ static void _add_clkdev(struct omap_device *od, const char *clk_alias,
r = clk_get_sys(NULL, clk_name); r = clk_get_sys(NULL, clk_name);
if (IS_ERR(r) && of_have_populated_dt()) { if (IS_ERR(r)) {
struct of_phandle_args clkspec; struct of_phandle_args clkspec;
clkspec.np = of_find_node_by_name(NULL, clk_name); clkspec.np = of_find_node_by_name(NULL, clk_name);
...@@ -953,9 +953,6 @@ static int __init omap_device_late_init(void) ...@@ -953,9 +953,6 @@ static int __init omap_device_late_init(void)
{ {
bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle); bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle);
WARN(!of_have_populated_dt(),
"legacy booting deprecated, please update to boot with .dts\n");
return 0; return 0;
} }
omap_late_initcall_sync(omap_device_late_init); omap_late_initcall_sync(omap_device_late_init);
...@@ -141,6 +141,7 @@ ...@@ -141,6 +141,7 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/bootmem.h>
#include <asm/system_misc.h> #include <asm/system_misc.h>
...@@ -181,6 +182,24 @@ ...@@ -181,6 +182,24 @@
*/ */
#define MOD_CLK_MAX_NAME_LEN 32 #define MOD_CLK_MAX_NAME_LEN 32
/**
* struct clkctrl_provider - clkctrl provider mapping data
* @addr: base address for the provider
* @offset: base offset for the provider
* @clkdm: base clockdomain for provider
* @node: device node associated with the provider
* @link: list link
*/
struct clkctrl_provider {
u32 addr;
u16 offset;
struct clockdomain *clkdm;
struct device_node *node;
struct list_head link;
};
static LIST_HEAD(clkctrl_providers);
/** /**
* struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations
* @enable_module: function to enable a module (via MODULEMODE) * @enable_module: function to enable a module (via MODULEMODE)
...@@ -204,6 +223,8 @@ struct omap_hwmod_soc_ops { ...@@ -204,6 +223,8 @@ struct omap_hwmod_soc_ops {
void (*update_context_lost)(struct omap_hwmod *oh); void (*update_context_lost)(struct omap_hwmod *oh);
int (*get_context_lost)(struct omap_hwmod *oh); int (*get_context_lost)(struct omap_hwmod *oh);
int (*disable_direct_prcm)(struct omap_hwmod *oh); int (*disable_direct_prcm)(struct omap_hwmod *oh);
u32 (*xlate_clkctrl)(struct omap_hwmod *oh,
struct clkctrl_provider *provider);
}; };
/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
...@@ -690,6 +711,103 @@ static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) ...@@ -690,6 +711,103 @@ static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
return clkdm_del_sleepdep(clkdm, init_clkdm); return clkdm_del_sleepdep(clkdm, init_clkdm);
} }
static const struct of_device_id ti_clkctrl_match_table[] __initconst = {
{ .compatible = "ti,clkctrl" },
{ }
};
static int _match_clkdm(struct clockdomain *clkdm, void *user)
{
struct clkctrl_provider *provider = user;
if (clkdm_xlate_address(clkdm) == provider->addr) {
pr_debug("%s: Matched clkdm %s for addr %x (%s)\n", __func__,
clkdm->name, provider->addr,
provider->node->parent->name);
provider->clkdm = clkdm;
return -1;
}
return 0;
}
static int _setup_clkctrl_provider(struct device_node *np)
{
const __be32 *addrp;
struct clkctrl_provider *provider;
provider = memblock_virt_alloc(sizeof(*provider), 0);
if (!provider)
return -ENOMEM;
addrp = of_get_address(np, 0, NULL, NULL);
provider->addr = (u32)of_translate_address(np, addrp);
provider->offset = provider->addr & 0xff;
provider->addr &= ~0xff;
provider->node = np;
clkdm_for_each(_match_clkdm, provider);
if (!provider->clkdm) {
pr_err("%s: nothing matched for node %s (%x)\n",
__func__, np->parent->name, provider->addr);
memblock_free_early(__pa(provider), sizeof(*provider));
return -EINVAL;
}
list_add(&provider->link, &clkctrl_providers);
return 0;
}
static int _init_clkctrl_providers(void)
{
struct device_node *np;
int ret = 0;
for_each_matching_node(np, ti_clkctrl_match_table) {
ret = _setup_clkctrl_provider(np);
if (ret)
break;
}
return ret;
}
static u32 _omap4_xlate_clkctrl(struct omap_hwmod *oh,
struct clkctrl_provider *provider)
{
return oh->prcm.omap4.clkctrl_offs -
provider->offset - provider->clkdm->clkdm_offs;
}
static struct clk *_lookup_clkctrl_clk(struct omap_hwmod *oh)
{
struct clkctrl_provider *provider;
struct clk *clk;
if (!soc_ops.xlate_clkctrl)
return NULL;
list_for_each_entry(provider, &clkctrl_providers, link) {
if (provider->clkdm == oh->clkdm) {
struct of_phandle_args clkspec;
clkspec.np = provider->node;
clkspec.args_count = 2;
clkspec.args[0] = soc_ops.xlate_clkctrl(oh, provider);
clkspec.args[1] = 0;
clk = of_clk_get_from_provider(&clkspec);
return clk;
}
}
return NULL;
}
/** /**
* _init_main_clk - get a struct clk * for the the hwmod's main functional clk * _init_main_clk - get a struct clk * for the the hwmod's main functional clk
* @oh: struct omap_hwmod * * @oh: struct omap_hwmod *
...@@ -701,22 +819,16 @@ static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) ...@@ -701,22 +819,16 @@ static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
static int _init_main_clk(struct omap_hwmod *oh) static int _init_main_clk(struct omap_hwmod *oh)
{ {
int ret = 0; int ret = 0;
char name[MOD_CLK_MAX_NAME_LEN]; struct clk *clk = NULL;
struct clk *clk;
static const char modck[] = "_mod_ck";
if (strlen(oh->name) >= MOD_CLK_MAX_NAME_LEN - strlen(modck))
pr_warn("%s: warning: cropping name for %s\n", __func__,
oh->name);
strlcpy(name, oh->name, MOD_CLK_MAX_NAME_LEN - strlen(modck)); clk = _lookup_clkctrl_clk(oh);
strlcat(name, modck, MOD_CLK_MAX_NAME_LEN);
clk = clk_get(NULL, name); if (!IS_ERR_OR_NULL(clk)) {
if (!IS_ERR(clk)) { pr_debug("%s: mapped main_clk %s for %s\n", __func__,
__clk_get_name(clk), oh->name);
oh->main_clk = __clk_get_name(clk);
oh->_clk = clk; oh->_clk = clk;
soc_ops.disable_direct_prcm(oh); soc_ops.disable_direct_prcm(oh);
oh->main_clk = kstrdup(name, GFP_KERNEL);
} else { } else {
if (!oh->main_clk) if (!oh->main_clk)
return 0; return 0;
...@@ -1482,13 +1594,13 @@ static int _init_clkdm(struct omap_hwmod *oh) ...@@ -1482,13 +1594,13 @@ static int _init_clkdm(struct omap_hwmod *oh)
* _init_clocks - clk_get() all clocks associated with this hwmod. Retrieve as * _init_clocks - clk_get() all clocks associated with this hwmod. Retrieve as
* well the clockdomain. * well the clockdomain.
* @oh: struct omap_hwmod * * @oh: struct omap_hwmod *
* @data: not used; pass NULL * @np: device_node mapped to this hwmod
* *
* Called by omap_hwmod_setup_*() (after omap2_clk_init()). * Called by omap_hwmod_setup_*() (after omap2_clk_init()).
* Resolves all clock names embedded in the hwmod. Returns 0 on * Resolves all clock names embedded in the hwmod. Returns 0 on
* success, or a negative error code on failure. * success, or a negative error code on failure.
*/ */
static int _init_clocks(struct omap_hwmod *oh, void *data) static int _init_clocks(struct omap_hwmod *oh, struct device_node *np)
{ {
int ret = 0; int ret = 0;
...@@ -2334,13 +2446,11 @@ static int __init _init(struct omap_hwmod *oh, void *data) ...@@ -2334,13 +2446,11 @@ static int __init _init(struct omap_hwmod *oh, void *data)
{ {
int r, index; int r, index;
struct device_node *np = NULL; struct device_node *np = NULL;
struct device_node *bus;
if (oh->_state != _HWMOD_STATE_REGISTERED) if (oh->_state != _HWMOD_STATE_REGISTERED)
return 0; return 0;
if (of_have_populated_dt()) {
struct device_node *bus;
bus = of_find_node_by_name(NULL, "ocp"); bus = of_find_node_by_name(NULL, "ocp");
if (!bus) if (!bus)
return -ENODEV; return -ENODEV;
...@@ -2351,7 +2461,6 @@ static int __init _init(struct omap_hwmod *oh, void *data) ...@@ -2351,7 +2461,6 @@ static int __init _init(struct omap_hwmod *oh, void *data)
else if (np && index) else if (np && index)
pr_warn("omap_hwmod: %s using broken dt data from %s\n", pr_warn("omap_hwmod: %s using broken dt data from %s\n",
oh->name, np->name); oh->name, np->name);
}
r = _init_mpu_rt_base(oh, NULL, index, np); r = _init_mpu_rt_base(oh, NULL, index, np);
if (r < 0) { if (r < 0) {
...@@ -2360,7 +2469,7 @@ static int __init _init(struct omap_hwmod *oh, void *data) ...@@ -2360,7 +2469,7 @@ static int __init _init(struct omap_hwmod *oh, void *data)
return 0; return 0;
} }
r = _init_clocks(oh, NULL); r = _init_clocks(oh, np);
if (r < 0) { if (r < 0) {
WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name); WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name);
return -EINVAL; return -EINVAL;
...@@ -3722,6 +3831,7 @@ void __init omap_hwmod_init(void) ...@@ -3722,6 +3831,7 @@ void __init omap_hwmod_init(void)
soc_ops.update_context_lost = _omap4_update_context_lost; soc_ops.update_context_lost = _omap4_update_context_lost;
soc_ops.get_context_lost = _omap4_get_context_lost; soc_ops.get_context_lost = _omap4_get_context_lost;
soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm; soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm;
soc_ops.xlate_clkctrl = _omap4_xlate_clkctrl;
} else if (cpu_is_ti814x() || cpu_is_ti816x() || soc_is_am33xx() || } else if (cpu_is_ti814x() || cpu_is_ti816x() || soc_is_am33xx() ||
soc_is_am43xx()) { soc_is_am43xx()) {
soc_ops.enable_module = _omap4_enable_module; soc_ops.enable_module = _omap4_enable_module;
...@@ -3736,6 +3846,8 @@ void __init omap_hwmod_init(void) ...@@ -3736,6 +3846,8 @@ void __init omap_hwmod_init(void)
WARN(1, "omap_hwmod: unknown SoC type\n"); WARN(1, "omap_hwmod: unknown SoC type\n");
} }
_init_clkctrl_providers();
inited = true; inited = true;
} }
......
...@@ -3204,7 +3204,6 @@ int __init omap3xxx_hwmod_init(void) ...@@ -3204,7 +3204,6 @@ int __init omap3xxx_hwmod_init(void)
* If DT information is missing, enable them only for GP devices. * If DT information is missing, enable them only for GP devices.
*/ */
if (of_have_populated_dt())
bus = of_find_node_by_name(NULL, "ocp"); bus = of_find_node_by_name(NULL, "ocp");
if (h_sham && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "sham")) { if (h_sham && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "sham")) {
......
...@@ -775,6 +775,7 @@ static struct omap_hwmod_dma_info omap44xx_dss_hdmi_sdma_reqs[] = { ...@@ -775,6 +775,7 @@ static struct omap_hwmod_dma_info omap44xx_dss_hdmi_sdma_reqs[] = {
static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = { static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = {
{ .role = "sys_clk", .clk = "dss_sys_clk" }, { .role = "sys_clk", .clk = "dss_sys_clk" },
{ .role = "hdmi_clk", .clk = "dss_48mhz_clk" },
}; };
static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
...@@ -785,7 +786,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { ...@@ -785,7 +786,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
* HDMI audio requires to use no-idle mode. Hence, * HDMI audio requires to use no-idle mode. Hence,
* set idle mode by software. * set idle mode by software.
*/ */
.flags = HWMOD_SWSUP_SIDLE, .flags = HWMOD_SWSUP_SIDLE | HWMOD_OPT_CLKS_NEEDED,
.mpu_irqs = omap44xx_dss_hdmi_irqs, .mpu_irqs = omap44xx_dss_hdmi_irqs,
.xlate_irq = omap4_xlate_irq, .xlate_irq = omap4_xlate_irq,
.sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs,
...@@ -858,11 +859,16 @@ static struct omap_hwmod_class omap44xx_venc_hwmod_class = { ...@@ -858,11 +859,16 @@ static struct omap_hwmod_class omap44xx_venc_hwmod_class = {
}; };
/* dss_venc */ /* dss_venc */
static struct omap_hwmod_opt_clk dss_venc_opt_clks[] = {
{ .role = "tv_clk", .clk = "dss_tv_clk" },
};
static struct omap_hwmod omap44xx_dss_venc_hwmod = { static struct omap_hwmod omap44xx_dss_venc_hwmod = {
.name = "dss_venc", .name = "dss_venc",
.class = &omap44xx_venc_hwmod_class, .class = &omap44xx_venc_hwmod_class,
.clkdm_name = "l3_dss_clkdm", .clkdm_name = "l3_dss_clkdm",
.main_clk = "dss_tv_clk", .main_clk = "dss_tv_clk",
.flags = HWMOD_OPT_CLKS_NEEDED,
.prcm = { .prcm = {
.omap4 = { .omap4 = {
.clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
...@@ -870,6 +876,35 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = { ...@@ -870,6 +876,35 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = {
}, },
}, },
.parent_hwmod = &omap44xx_dss_hwmod, .parent_hwmod = &omap44xx_dss_hwmod,
.opt_clks = dss_venc_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(dss_venc_opt_clks),
};
/* sha0 HIB2 (the 'P' (public) device) */
static struct omap_hwmod_class_sysconfig omap44xx_sha0_sysc = {
.rev_offs = 0x100,
.sysc_offs = 0x110,
.syss_offs = 0x114,
.sysc_flags = SYSS_HAS_RESET_STATUS,
};
static struct omap_hwmod_class omap44xx_sha0_hwmod_class = {
.name = "sham",
.sysc = &omap44xx_sha0_sysc,
};
struct omap_hwmod omap44xx_sha0_hwmod = {
.name = "sham",
.class = &omap44xx_sha0_hwmod_class,
.clkdm_name = "l4_secure_clkdm",
.main_clk = "l3_div_ck",
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4SEC_SHA2MD51_CONTEXT_OFFSET,
.modulemode = MODULEMODE_SWCTRL,
},
},
}; };
/* /*
...@@ -952,6 +987,103 @@ static struct omap_hwmod omap44xx_emif2_hwmod = { ...@@ -952,6 +987,103 @@ static struct omap_hwmod omap44xx_emif2_hwmod = {
}, },
}; };
/*
Crypto modules AES0/1 belong to:
PD_L4_PER power domain
CD_L4_SEC clock domain
On the L3, the AES modules are mapped to
L3_CLK2: Peripherals and multimedia sub clock domain
*/
static struct omap_hwmod_class_sysconfig omap44xx_aes_sysc = {
.rev_offs = 0x80,
.sysc_offs = 0x84,
.syss_offs = 0x88,
.sysc_flags = SYSS_HAS_RESET_STATUS,
};
static struct omap_hwmod_class omap44xx_aes_hwmod_class = {
.name = "aes",
.sysc = &omap44xx_aes_sysc,
};
static struct omap_hwmod omap44xx_aes1_hwmod = {
.name = "aes1",
.class = &omap44xx_aes_hwmod_class,
.clkdm_name = "l4_secure_clkdm",
.main_clk = "l3_div_ck",
.prcm = {
.omap4 = {
.context_offs = OMAP4_RM_L4SEC_AES1_CONTEXT_OFFSET,
.clkctrl_offs = OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET,
.modulemode = MODULEMODE_SWCTRL,
},
},
};
static struct omap_hwmod_ocp_if omap44xx_l3_main_2__aes1 = {
.master = &omap44xx_l4_per_hwmod,
.slave = &omap44xx_aes1_hwmod,
.clk = "l3_div_ck",
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
static struct omap_hwmod omap44xx_aes2_hwmod = {
.name = "aes2",
.class = &omap44xx_aes_hwmod_class,
.clkdm_name = "l4_secure_clkdm",
.main_clk = "l3_div_ck",
.prcm = {
.omap4 = {
.context_offs = OMAP4_RM_L4SEC_AES2_CONTEXT_OFFSET,
.clkctrl_offs = OMAP4_CM_L4SEC_AES2_CLKCTRL_OFFSET,
.modulemode = MODULEMODE_SWCTRL,
},
},
};
static struct omap_hwmod_ocp_if omap44xx_l3_main_2__aes2 = {
.master = &omap44xx_l4_per_hwmod,
.slave = &omap44xx_aes2_hwmod,
.clk = "l3_div_ck",
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/*
* 'des' class for DES3DES module
*/
static struct omap_hwmod_class_sysconfig omap44xx_des_sysc = {
.rev_offs = 0x30,
.sysc_offs = 0x34,
.syss_offs = 0x38,
.sysc_flags = SYSS_HAS_RESET_STATUS,
};
static struct omap_hwmod_class omap44xx_des_hwmod_class = {
.name = "des",
.sysc = &omap44xx_des_sysc,
};
static struct omap_hwmod omap44xx_des_hwmod = {
.name = "des",
.class = &omap44xx_des_hwmod_class,
.clkdm_name = "l4_secure_clkdm",
.main_clk = "l3_div_ck",
.prcm = {
.omap4 = {
.context_offs = OMAP4_RM_L4SEC_DES3DES_CONTEXT_OFFSET,
.clkctrl_offs = OMAP4_CM_L4SEC_DES3DES_CLKCTRL_OFFSET,
.modulemode = MODULEMODE_SWCTRL,
},
},
};
struct omap_hwmod_ocp_if omap44xx_l3_main_2__des = {
.master = &omap44xx_l3_main_2_hwmod,
.slave = &omap44xx_des_hwmod,
.clk = "l3_div_ck",
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* /*
* 'fdif' class * 'fdif' class
* face detection hw accelerator module * face detection hw accelerator module
...@@ -3882,6 +4014,14 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = { ...@@ -3882,6 +4014,14 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = {
.user = OCP_USER_MPU, .user = OCP_USER_MPU,
}; };
/* l3_main_2 -> sham */
static struct omap_hwmod_ocp_if omap44xx_l3_main_2__sha0 = {
.master = &omap44xx_l3_main_2_hwmod,
.slave = &omap44xx_sha0_hwmod,
.clk = "l3_div_ck",
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* l4_per -> elm */ /* l4_per -> elm */
static struct omap_hwmod_ocp_if omap44xx_l4_per__elm = { static struct omap_hwmod_ocp_if omap44xx_l4_per__elm = {
.master = &omap44xx_l4_per_hwmod, .master = &omap44xx_l4_per_hwmod,
...@@ -4793,6 +4933,10 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { ...@@ -4793,6 +4933,10 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
&omap44xx_l4_abe__wd_timer3_dma, &omap44xx_l4_abe__wd_timer3_dma,
&omap44xx_mpu__emif1, &omap44xx_mpu__emif1,
&omap44xx_mpu__emif2, &omap44xx_mpu__emif2,
&omap44xx_l3_main_2__aes1,
&omap44xx_l3_main_2__aes2,
&omap44xx_l3_main_2__des,
&omap44xx_l3_main_2__sha0,
NULL, NULL,
}; };
......
/*
* OMAP SoC specific OPP wrapper function
*
* Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/
* Nishanth Menon
* Kevin Hilman
* Copyright (C) 2010 Nokia Corporation.
* Eduardo Valentin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pm_opp.h>
#include <linux/cpu.h>
#include "omap_device.h"
#include "omap_opp_data.h"
/* Temp variable to allow multiple calls */
static u8 __initdata omap_table_init;
/**
* omap_init_opp_table() - Initialize opp table as per the CPU type
* @opp_def: opp default list for this silicon
* @opp_def_size: number of opp entries for this silicon
*
* Register the initial OPP table with the OPP library based on the CPU
* type. This is meant to be used only by SoC specific registration.
*/
int __init omap_init_opp_table(struct omap_opp_def *opp_def,
u32 opp_def_size)
{
int i, r;
if (of_have_populated_dt())
return -EINVAL;
if (!opp_def || !opp_def_size) {
pr_err("%s: invalid params!\n", __func__);
return -EINVAL;
}
/*
* Initialize only if not already initialized even if the previous
* call failed, because, no reason we'd succeed again.
*/
if (omap_table_init)
return -EEXIST;
omap_table_init = 1;
/* Lets now register with OPP library */
for (i = 0; i < opp_def_size; i++, opp_def++) {
struct omap_hwmod *oh;
struct device *dev;
if (!opp_def->hwmod_name) {
pr_err("%s: NULL name of omap_hwmod, failing [%d].\n",
__func__, i);
return -EINVAL;
}
if (!strncmp(opp_def->hwmod_name, "mpu", 3)) {
/*
* All current OMAPs share voltage rail and
* clock source, so CPU0 is used to represent
* the MPU-SS.
*/
dev = get_cpu_device(0);
} else {
oh = omap_hwmod_lookup(opp_def->hwmod_name);
if (!oh || !oh->od) {
pr_debug("%s: no hwmod or odev for %s, [%d] cannot add OPPs.\n",
__func__, opp_def->hwmod_name, i);
continue;
}
dev = &oh->od->pdev->dev;
}
r = dev_pm_opp_add(dev, opp_def->freq, opp_def->u_volt);
if (r) {
dev_err(dev, "%s: add OPP %ld failed for %s [%d] result=%d\n",
__func__, opp_def->freq,
opp_def->hwmod_name, i, r);
} else {
if (!opp_def->default_available)
r = dev_pm_opp_disable(dev, opp_def->freq);
if (r)
dev_err(dev, "%s: disable %ld failed for %s [%d] result=%d\n",
__func__, opp_def->freq,
opp_def->hwmod_name, i, r);
}
}
return 0;
}
...@@ -83,89 +83,3 @@ struct omap_volt_data omap36xx_vddcore_volt_data[] = { ...@@ -83,89 +83,3 @@ struct omap_volt_data omap36xx_vddcore_volt_data[] = {
VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16), VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16),
VOLT_DATA_DEFINE(0, 0, 0, 0), VOLT_DATA_DEFINE(0, 0, 0, 0),
}; };
/* OPP data */
static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
/* MPU OPP1 */
OPP_INITIALIZER("mpu", true, 125000000, OMAP3430_VDD_MPU_OPP1_UV),
/* MPU OPP2 */
OPP_INITIALIZER("mpu", true, 250000000, OMAP3430_VDD_MPU_OPP2_UV),
/* MPU OPP3 */
OPP_INITIALIZER("mpu", true, 500000000, OMAP3430_VDD_MPU_OPP3_UV),
/* MPU OPP4 */
OPP_INITIALIZER("mpu", true, 550000000, OMAP3430_VDD_MPU_OPP4_UV),
/* MPU OPP5 */
OPP_INITIALIZER("mpu", true, 600000000, OMAP3430_VDD_MPU_OPP5_UV),
/*
* L3 OPP1 - 41.5 MHz is disabled because: The voltage for that OPP is
* almost the same than the one at 83MHz thus providing very little
* gain for the power point of view. In term of energy it will even
* increase the consumption due to the very negative performance
* impact that frequency will do to the MPU and the whole system in
* general.
*/
OPP_INITIALIZER("l3_main", false, 41500000, OMAP3430_VDD_CORE_OPP1_UV),
/* L3 OPP2 */
OPP_INITIALIZER("l3_main", true, 83000000, OMAP3430_VDD_CORE_OPP2_UV),
/* L3 OPP3 */
OPP_INITIALIZER("l3_main", true, 166000000, OMAP3430_VDD_CORE_OPP3_UV),
/* DSP OPP1 */
OPP_INITIALIZER("iva", true, 90000000, OMAP3430_VDD_MPU_OPP1_UV),
/* DSP OPP2 */
OPP_INITIALIZER("iva", true, 180000000, OMAP3430_VDD_MPU_OPP2_UV),
/* DSP OPP3 */
OPP_INITIALIZER("iva", true, 360000000, OMAP3430_VDD_MPU_OPP3_UV),
/* DSP OPP4 */
OPP_INITIALIZER("iva", true, 400000000, OMAP3430_VDD_MPU_OPP4_UV),
/* DSP OPP5 */
OPP_INITIALIZER("iva", true, 430000000, OMAP3430_VDD_MPU_OPP5_UV),
};
static struct omap_opp_def __initdata omap36xx_opp_def_list[] = {
/* MPU OPP1 - OPP50 */
OPP_INITIALIZER("mpu", true, 300000000, OMAP3630_VDD_MPU_OPP50_UV),
/* MPU OPP2 - OPP100 */
OPP_INITIALIZER("mpu", true, 600000000, OMAP3630_VDD_MPU_OPP100_UV),
/* MPU OPP3 - OPP-Turbo */
OPP_INITIALIZER("mpu", false, 800000000, OMAP3630_VDD_MPU_OPP120_UV),
/* MPU OPP4 - OPP-SB */
OPP_INITIALIZER("mpu", false, 1000000000, OMAP3630_VDD_MPU_OPP1G_UV),
/* L3 OPP1 - OPP50 */
OPP_INITIALIZER("l3_main", true, 100000000, OMAP3630_VDD_CORE_OPP50_UV),
/* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */
OPP_INITIALIZER("l3_main", true, 200000000, OMAP3630_VDD_CORE_OPP100_UV),
/* DSP OPP1 - OPP50 */
OPP_INITIALIZER("iva", true, 260000000, OMAP3630_VDD_MPU_OPP50_UV),
/* DSP OPP2 - OPP100 */
OPP_INITIALIZER("iva", true, 520000000, OMAP3630_VDD_MPU_OPP100_UV),
/* DSP OPP3 - OPP-Turbo */
OPP_INITIALIZER("iva", false, 660000000, OMAP3630_VDD_MPU_OPP120_UV),
/* DSP OPP4 - OPP-SB */
OPP_INITIALIZER("iva", false, 800000000, OMAP3630_VDD_MPU_OPP1G_UV),
};
/**
* omap3_opp_init() - initialize omap3 opp table
*/
int __init omap3_opp_init(void)
{
int r = -ENODEV;
if (!cpu_is_omap34xx())
return r;
if (cpu_is_omap3630())
r = omap_init_opp_table(omap36xx_opp_def_list,
ARRAY_SIZE(omap36xx_opp_def_list));
else
r = omap_init_opp_table(omap34xx_opp_def_list,
ARRAY_SIZE(omap34xx_opp_def_list));
return r;
}
omap_device_initcall(omap3_opp_init);
...@@ -63,29 +63,6 @@ struct omap_volt_data omap443x_vdd_core_volt_data[] = { ...@@ -63,29 +63,6 @@ struct omap_volt_data omap443x_vdd_core_volt_data[] = {
VOLT_DATA_DEFINE(0, 0, 0, 0), VOLT_DATA_DEFINE(0, 0, 0, 0),
}; };
static struct omap_opp_def __initdata omap443x_opp_def_list[] = {
/* MPU OPP1 - OPP50 */
OPP_INITIALIZER("mpu", true, 300000000, OMAP4430_VDD_MPU_OPP50_UV),
/* MPU OPP2 - OPP100 */
OPP_INITIALIZER("mpu", true, 600000000, OMAP4430_VDD_MPU_OPP100_UV),
/* MPU OPP3 - OPP-Turbo */
OPP_INITIALIZER("mpu", true, 800000000, OMAP4430_VDD_MPU_OPPTURBO_UV),
/* MPU OPP4 - OPP-SB */
OPP_INITIALIZER("mpu", true, 1008000000, OMAP4430_VDD_MPU_OPPNITRO_UV),
/* L3 OPP1 - OPP50 */
OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4430_VDD_CORE_OPP50_UV),
/* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */
OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4430_VDD_CORE_OPP100_UV),
/* IVA OPP1 - OPP50 */
OPP_INITIALIZER("iva", true, 133000000, OMAP4430_VDD_IVA_OPP50_UV),
/* IVA OPP2 - OPP100 */
OPP_INITIALIZER("iva", true, 266100000, OMAP4430_VDD_IVA_OPP100_UV),
/* IVA OPP3 - OPP-Turbo */
OPP_INITIALIZER("iva", false, 332000000, OMAP4430_VDD_IVA_OPPTURBO_UV),
/* TODO: add DSP, aess, fdif, gpu */
};
#define OMAP4460_VDD_MPU_OPP50_UV 1025000 #define OMAP4460_VDD_MPU_OPP50_UV 1025000
#define OMAP4460_VDD_MPU_OPP100_UV 1200000 #define OMAP4460_VDD_MPU_OPP100_UV 1200000
#define OMAP4460_VDD_MPU_OPPTURBO_UV 1313000 #define OMAP4460_VDD_MPU_OPPTURBO_UV 1313000
...@@ -122,59 +99,3 @@ struct omap_volt_data omap446x_vdd_core_volt_data[] = { ...@@ -122,59 +99,3 @@ struct omap_volt_data omap446x_vdd_core_volt_data[] = {
VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16), VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16),
VOLT_DATA_DEFINE(0, 0, 0, 0), VOLT_DATA_DEFINE(0, 0, 0, 0),
}; };
static struct omap_opp_def __initdata omap446x_opp_def_list[] = {
/* MPU OPP1 - OPP50 */
OPP_INITIALIZER("mpu", true, 350000000, OMAP4460_VDD_MPU_OPP50_UV),
/* MPU OPP2 - OPP100 */
OPP_INITIALIZER("mpu", true, 700000000, OMAP4460_VDD_MPU_OPP100_UV),
/* MPU OPP3 - OPP-Turbo */
OPP_INITIALIZER("mpu", true, 920000000, OMAP4460_VDD_MPU_OPPTURBO_UV),
/*
* MPU OPP4 - OPP-Nitro + Disabled as the reference schematics
* recommends TPS623631 - confirm and enable the opp in board file
* XXX: May be we should enable these based on mpu capability and
* Exception board files disable it...
*/
OPP_INITIALIZER("mpu", false, 1200000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
/* MPU OPP4 - OPP-Nitro SpeedBin */
OPP_INITIALIZER("mpu", false, 1500000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
/* L3 OPP1 - OPP50 */
OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4460_VDD_CORE_OPP50_UV),
/* L3 OPP2 - OPP100 */
OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4460_VDD_CORE_OPP100_UV),
/* IVA OPP1 - OPP50 */
OPP_INITIALIZER("iva", true, 133000000, OMAP4460_VDD_IVA_OPP50_UV),
/* IVA OPP2 - OPP100 */
OPP_INITIALIZER("iva", true, 266100000, OMAP4460_VDD_IVA_OPP100_UV),
/*
* IVA OPP3 - OPP-Turbo + Disabled as the reference schematics
* recommends Phoenix VCORE2 which can supply only 600mA - so the ones
* above this OPP frequency, even though OMAP is capable, should be
* enabled by board file which is sure of the chip power capability
*/
OPP_INITIALIZER("iva", false, 332000000, OMAP4460_VDD_IVA_OPPTURBO_UV),
/* IVA OPP4 - OPP-Nitro */
OPP_INITIALIZER("iva", false, 430000000, OMAP4460_VDD_IVA_OPPNITRO_UV),
/* IVA OPP5 - OPP-Nitro SpeedBin*/
OPP_INITIALIZER("iva", false, 500000000, OMAP4460_VDD_IVA_OPPNITRO_UV),
/* TODO: add DSP, aess, fdif, gpu */
};
/**
* omap4_opp_init() - initialize omap4 opp table
*/
int __init omap4_opp_init(void)
{
int r = -ENODEV;
if (cpu_is_omap443x())
r = omap_init_opp_table(omap443x_opp_def_list,
ARRAY_SIZE(omap443x_opp_def_list));
else if (cpu_is_omap446x())
r = omap_init_opp_table(omap446x_opp_def_list,
ARRAY_SIZE(omap446x_opp_def_list));
return r;
}
omap_device_initcall(omap4_opp_init);
...@@ -71,7 +71,7 @@ void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) ...@@ -71,7 +71,7 @@ void omap_pm_get_oscillator(u32 *tstart, u32 *tshut)
} }
#endif #endif
int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
{ {
clkdm_allow_idle(clkdm); clkdm_allow_idle(clkdm);
return 0; return 0;
......
/*
* OMAP2 ARM Performance Monitoring Unit (PMU) Support
*
* Copyright (C) 2012 Texas Instruments, Inc.
*
* Contacts:
* Jon Hunter <jon-hunter@ti.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/of.h>
#include <asm/system_info.h>
#include "soc.h"
#include "omap_hwmod.h"
#include "omap_device.h"
static char *omap2_pmu_oh_names[] = {"mpu"};
static char *omap3_pmu_oh_names[] = {"mpu", "debugss"};
static char *omap4430_pmu_oh_names[] = {"l3_main_3", "l3_instr", "debugss"};
static struct platform_device *omap_pmu_dev;
/**
* omap2_init_pmu - creates and registers PMU platform device
* @oh_num: Number of OMAP HWMODs required to create PMU device
* @oh_names: Array of OMAP HWMODS names required to create PMU device
*
* Uses OMAP HWMOD framework to create and register an ARM PMU device
* from a list of HWMOD names passed. Currently supports OMAP2, OMAP3
* and OMAP4 devices.
*/
static int __init omap2_init_pmu(unsigned oh_num, char *oh_names[])
{
int i;
struct omap_hwmod *oh[3];
char *dev_name = cpu_architecture() == CPU_ARCH_ARMv6 ?
"armv6-pmu" : "armv7-pmu";
if ((!oh_num) || (oh_num > 3))
return -EINVAL;
for (i = 0; i < oh_num; i++) {
oh[i] = omap_hwmod_lookup(oh_names[i]);
if (!oh[i]) {
pr_err("Could not look up %s hwmod\n", oh_names[i]);
return -ENODEV;
}
}
omap_pmu_dev = omap_device_build_ss(dev_name, -1, oh, oh_num, NULL, 0);
WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
dev_name);
return PTR_ERR_OR_ZERO(omap_pmu_dev);
}
static int __init omap_init_pmu(void)
{
unsigned oh_num;
char **oh_names;
/* XXX Remove this check when the CTI driver is available */
if (cpu_is_omap443x()) {
pr_info("ARM PMU: not yet supported on OMAP4430 due to missing CTI driver\n");
return 0;
}
if (of_have_populated_dt())
return 0;
/*
* To create an ARM-PMU device the following HWMODs
* are required for the various OMAP2+ devices.
*
* OMAP24xx: mpu
* OMAP3xxx: mpu, debugss
* OMAP4430: l3_main_3, l3_instr, debugss
* OMAP4460/70: mpu, debugss
*/
if (cpu_is_omap443x()) {
oh_num = ARRAY_SIZE(omap4430_pmu_oh_names);
oh_names = omap4430_pmu_oh_names;
} else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
oh_num = ARRAY_SIZE(omap3_pmu_oh_names);
oh_names = omap3_pmu_oh_names;
} else {
oh_num = ARRAY_SIZE(omap2_pmu_oh_names);
oh_names = omap2_pmu_oh_names;
}
return omap2_init_pmu(oh_num, oh_names);
}
omap_subsys_initcall(omap_init_pmu);
...@@ -526,10 +526,16 @@ struct omap_prcm_irq_setup { ...@@ -526,10 +526,16 @@ struct omap_prcm_irq_setup {
.priority = _priority \ .priority = _priority \
} }
struct omap_domain_base {
u32 pa;
void __iomem *va;
};
/** /**
* struct omap_prcm_init_data - PRCM driver init data * struct omap_prcm_init_data - PRCM driver init data
* @index: clock memory mapping index to be used * @index: clock memory mapping index to be used
* @mem: IO mem pointer for this module * @mem: IO mem pointer for this module
* @phys: IO mem physical base address for this module
* @offset: module base address offset from the IO base * @offset: module base address offset from the IO base
* @flags: PRCM module init flags * @flags: PRCM module init flags
* @device_inst_offset: device instance offset within the module address space * @device_inst_offset: device instance offset within the module address space
...@@ -539,6 +545,7 @@ struct omap_prcm_irq_setup { ...@@ -539,6 +545,7 @@ struct omap_prcm_irq_setup {
struct omap_prcm_init_data { struct omap_prcm_init_data {
int index; int index;
void __iomem *mem; void __iomem *mem;
u32 phys;
s16 offset; s16 offset;
u16 flags; u16 flags;
s32 device_inst_offset; s32 device_inst_offset;
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
* prcm_mpu_base: the virtual address of the start of the PRCM_MPU IP * prcm_mpu_base: the virtual address of the start of the PRCM_MPU IP
* block registers * block registers
*/ */
void __iomem *prcm_mpu_base; struct omap_domain_base prcm_mpu_base;
/* PRCM_MPU low-level functions */ /* PRCM_MPU low-level functions */
...@@ -58,5 +58,5 @@ u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg) ...@@ -58,5 +58,5 @@ u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg)
*/ */
void __init omap2_set_globals_prcm_mpu(void __iomem *prcm_mpu) void __init omap2_set_globals_prcm_mpu(void __iomem *prcm_mpu)
{ {
prcm_mpu_base = prcm_mpu; prcm_mpu_base.va = prcm_mpu;
} }
...@@ -24,7 +24,9 @@ ...@@ -24,7 +24,9 @@
#define __ARCH_ARM_MACH_OMAP2_PRCM_MPU_44XX_54XX_H #define __ARCH_ARM_MACH_OMAP2_PRCM_MPU_44XX_54XX_H
#ifndef __ASSEMBLER__ #ifndef __ASSEMBLER__
extern void __iomem *prcm_mpu_base; #include "prcm-common.h"
extern struct omap_domain_base prcm_mpu_base;
extern u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 idx); extern u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 idx);
extern void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 idx); extern void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 idx);
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include "prcm-common.h" #include "prcm-common.h"
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
extern void __iomem *prm_base; extern struct omap_domain_base prm_base;
extern u16 prm_features; extern u16 prm_features;
extern void omap2_set_globals_prm(void __iomem *prm); extern void omap2_set_globals_prm(void __iomem *prm);
int omap_prcm_init(void); int omap_prcm_init(void);
......
...@@ -55,12 +55,12 @@ ...@@ -55,12 +55,12 @@
/* Power/reset management domain register get/set */ /* Power/reset management domain register get/set */
static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx) static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
{ {
return readl_relaxed(prm_base + module + idx); return readl_relaxed(prm_base.va + module + idx);
} }
static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx) static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx)
{ {
writel_relaxed(val, prm_base + module + idx); writel_relaxed(val, prm_base.va + module + idx);
} }
/* Read-modify-write a register in a PRM module. Caller must lock */ /* Read-modify-write a register in a PRM module. Caller must lock */
......
...@@ -30,13 +30,13 @@ ...@@ -30,13 +30,13 @@
/* Read a register in a PRM instance */ /* Read a register in a PRM instance */
static u32 am33xx_prm_read_reg(s16 inst, u16 idx) static u32 am33xx_prm_read_reg(s16 inst, u16 idx)
{ {
return readl_relaxed(prm_base + inst + idx); return readl_relaxed(prm_base.va + inst + idx);
} }
/* Write into a register in a PRM instance */ /* Write into a register in a PRM instance */
static void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx) static void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx)
{ {
writel_relaxed(val, prm_base + inst + idx); writel_relaxed(val, prm_base.va + inst + idx);
} }
/* Read-modify-write a register in PRM. Caller must lock */ /* Read-modify-write a register in PRM. Caller must lock */
......
...@@ -676,7 +676,7 @@ static struct prm_ll_data omap3xxx_prm_ll_data = { ...@@ -676,7 +676,7 @@ static struct prm_ll_data omap3xxx_prm_ll_data = {
int __init omap3xxx_prm_init(const struct omap_prcm_init_data *data) int __init omap3xxx_prm_init(const struct omap_prcm_init_data *data)
{ {
omap2_clk_legacy_provider_init(TI_CLKM_PRM, omap2_clk_legacy_provider_init(TI_CLKM_PRM,
prm_base + OMAP3430_IVA2_MOD); prm_base.va + OMAP3430_IVA2_MOD);
if (omap3_has_io_wakeup()) if (omap3_has_io_wakeup())
prm_features |= PRM_HAS_IO_WAKEUP; prm_features |= PRM_HAS_IO_WAKEUP;
...@@ -690,6 +690,8 @@ static const struct of_device_id omap3_prm_dt_match_table[] = { ...@@ -690,6 +690,8 @@ static const struct of_device_id omap3_prm_dt_match_table[] = {
static int omap3xxx_prm_late_init(void) static int omap3xxx_prm_late_init(void)
{ {
struct device_node *np;
int irq_num;
int ret; int ret;
if (!(prm_features & PRM_HAS_IO_WAKEUP)) if (!(prm_features & PRM_HAS_IO_WAKEUP))
...@@ -702,17 +704,12 @@ static int omap3xxx_prm_late_init(void) ...@@ -702,17 +704,12 @@ static int omap3xxx_prm_late_init(void)
omap3_prcm_irq_setup.reconfigure_io_chain = omap3_prcm_irq_setup.reconfigure_io_chain =
omap3430_pre_es3_1_reconfigure_io_chain; omap3430_pre_es3_1_reconfigure_io_chain;
if (of_have_populated_dt()) {
struct device_node *np;
int irq_num;
np = of_find_matching_node(NULL, omap3_prm_dt_match_table); np = of_find_matching_node(NULL, omap3_prm_dt_match_table);
if (np) { if (np) {
irq_num = of_irq_get(np, 0); irq_num = of_irq_get(np, 0);
if (irq_num >= 0) if (irq_num >= 0)
omap3_prcm_irq_setup.irq = irq_num; omap3_prcm_irq_setup.irq = irq_num;
} }
}
omap3xxx_prm_enable_io_wakeup(); omap3xxx_prm_enable_io_wakeup();
ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
......
...@@ -91,13 +91,13 @@ static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = { ...@@ -91,13 +91,13 @@ static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = {
/* Read a register in a CM/PRM instance in the PRM module */ /* Read a register in a CM/PRM instance in the PRM module */
static u32 omap4_prm_read_inst_reg(s16 inst, u16 reg) static u32 omap4_prm_read_inst_reg(s16 inst, u16 reg)
{ {
return readl_relaxed(prm_base + inst + reg); return readl_relaxed(prm_base.va + inst + reg);
} }
/* Write into a register in a CM/PRM instance in the PRM module */ /* Write into a register in a CM/PRM instance in the PRM module */
static void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg) static void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg)
{ {
writel_relaxed(val, prm_base + inst + reg); writel_relaxed(val, prm_base.va + inst + reg);
} }
/* Read-modify-write a register in a PRM module. Caller must lock */ /* Read-modify-write a register in a PRM module. Caller must lock */
...@@ -336,27 +336,6 @@ static void omap44xx_prm_reconfigure_io_chain(void) ...@@ -336,27 +336,6 @@ static void omap44xx_prm_reconfigure_io_chain(void)
return; return;
} }
/**
* omap44xx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
*
* Activates the I/O wakeup event latches and allows events logged by
* those latches to signal a wakeup event to the PRCM. For I/O wakeups
* to occur, WAKEUPENABLE bits must be set in the pad mux registers, and
* omap44xx_prm_reconfigure_io_chain() must be called. No return value.
*/
static void __init omap44xx_prm_enable_io_wakeup(void)
{
s32 inst = omap4_prmst_get_prm_dev_inst();
if (inst == PRM_INSTANCE_UNKNOWN)
return;
omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
OMAP4430_GLOBAL_WUEN_MASK,
inst,
omap4_prcm_irq_setup.pm_ctrl);
}
/** /**
* omap44xx_prm_read_reset_sources - return the last SoC reset source * omap44xx_prm_read_reset_sources - return the last SoC reset source
* *
...@@ -689,8 +668,6 @@ struct pwrdm_ops omap4_pwrdm_operations = { ...@@ -689,8 +668,6 @@ struct pwrdm_ops omap4_pwrdm_operations = {
.pwrdm_has_voltdm = omap4_check_vcvp, .pwrdm_has_voltdm = omap4_check_vcvp,
}; };
static int omap44xx_prm_late_init(void);
/* /*
* XXX document * XXX document
*/ */
...@@ -698,7 +675,6 @@ static struct prm_ll_data omap44xx_prm_ll_data = { ...@@ -698,7 +675,6 @@ static struct prm_ll_data omap44xx_prm_ll_data = {
.read_reset_sources = &omap44xx_prm_read_reset_sources, .read_reset_sources = &omap44xx_prm_read_reset_sources,
.was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old, .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
.clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old, .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old,
.late_init = &omap44xx_prm_late_init,
.assert_hardreset = omap4_prminst_assert_hardreset, .assert_hardreset = omap4_prminst_assert_hardreset,
.deassert_hardreset = omap4_prminst_deassert_hardreset, .deassert_hardreset = omap4_prminst_deassert_hardreset,
.is_hardreset_asserted = omap4_prminst_is_hardreset_asserted, .is_hardreset_asserted = omap4_prminst_is_hardreset_asserted,
...@@ -735,41 +711,6 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data) ...@@ -735,41 +711,6 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
return prm_register(&omap44xx_prm_ll_data); return prm_register(&omap44xx_prm_ll_data);
} }
static int omap44xx_prm_late_init(void)
{
int irq_num;
if (!(prm_features & PRM_HAS_IO_WAKEUP))
return 0;
/* OMAP4+ is DT only now */
if (!of_have_populated_dt())
return 0;
irq_num = of_irq_get(prm_init_data->np, 0);
/*
* Already have OMAP4 IRQ num. For all other platforms, we need
* IRQ numbers from DT
*/
if (irq_num < 0 && !(prm_init_data->flags & PRM_IRQ_DEFAULT)) {
if (irq_num == -EPROBE_DEFER)
return irq_num;
/* Have nothing to do */
return 0;
}
/* Once OMAP4 DT is filled as well */
if (irq_num >= 0) {
omap4_prcm_irq_setup.irq = irq_num;
omap4_prcm_irq_setup.xlate_irq = NULL;
}
omap44xx_prm_enable_io_wakeup();
return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
}
static void __exit omap44xx_prm_exit(void) static void __exit omap44xx_prm_exit(void)
{ {
prm_unregister(&omap44xx_prm_ll_data); prm_unregister(&omap44xx_prm_ll_data);
......
...@@ -66,7 +66,7 @@ static struct irq_chip_generic **prcm_irq_chips; ...@@ -66,7 +66,7 @@ static struct irq_chip_generic **prcm_irq_chips;
static struct omap_prcm_irq_setup *prcm_irq_setup; static struct omap_prcm_irq_setup *prcm_irq_setup;
/* prm_base: base virtual address of the PRM IP block */ /* prm_base: base virtual address of the PRM IP block */
void __iomem *prm_base; struct omap_domain_base prm_base;
u16 prm_features; u16 prm_features;
...@@ -267,10 +267,9 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) ...@@ -267,10 +267,9 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
{ {
int nr_regs; int nr_regs;
u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG]; u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG];
int offset, i; int offset, i, irq;
struct irq_chip_generic *gc; struct irq_chip_generic *gc;
struct irq_chip_type *ct; struct irq_chip_type *ct;
unsigned int irq;
if (!irq_setup) if (!irq_setup)
return -EINVAL; return -EINVAL;
...@@ -325,7 +324,7 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) ...@@ -325,7 +324,7 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
for (i = 0; i < irq_setup->nr_regs; i++) { for (i = 0; i < irq_setup->nr_regs; i++) {
gc = irq_alloc_generic_chip("PRCM", 1, gc = irq_alloc_generic_chip("PRCM", 1,
irq_setup->base_irq + i * 32, prm_base, irq_setup->base_irq + i * 32, prm_base.va,
handle_level_irq); handle_level_irq);
if (!gc) { if (!gc) {
...@@ -344,10 +343,8 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) ...@@ -344,10 +343,8 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
prcm_irq_chips[i] = gc; prcm_irq_chips[i] = gc;
} }
if (of_have_populated_dt()) { irq = omap_prcm_event_to_irq("io");
int irq = omap_prcm_event_to_irq("io");
omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain); omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain);
}
return 0; return 0;
...@@ -364,7 +361,7 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) ...@@ -364,7 +361,7 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
*/ */
void __init omap2_set_globals_prm(void __iomem *prm) void __init omap2_set_globals_prm(void __iomem *prm)
{ {
prm_base = prm; prm_base.va = prm;
} }
/** /**
...@@ -755,19 +752,22 @@ int __init omap2_prm_base_init(void) ...@@ -755,19 +752,22 @@ int __init omap2_prm_base_init(void)
struct device_node *np; struct device_node *np;
const struct of_device_id *match; const struct of_device_id *match;
struct omap_prcm_init_data *data; struct omap_prcm_init_data *data;
void __iomem *mem; struct resource res;
int ret;
for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) { for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) {
data = (struct omap_prcm_init_data *)match->data; data = (struct omap_prcm_init_data *)match->data;
mem = of_iomap(np, 0); ret = of_address_to_resource(np, 0, &res);
if (!mem) if (ret)
return -ENOMEM; return ret;
if (data->index == TI_CLKM_PRM) data->mem = ioremap(res.start, resource_size(&res));
prm_base = mem + data->offset;
data->mem = mem; if (data->index == TI_CLKM_PRM) {
prm_base.va = data->mem + data->offset;
prm_base.pa = res.start + data->offset;
}
data->np = np; data->np = np;
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "prcm_mpu44xx.h" #include "prcm_mpu44xx.h"
#include "soc.h" #include "soc.h"
static void __iomem *_prm_bases[OMAP4_MAX_PRCM_PARTITIONS]; static struct omap_domain_base _prm_bases[OMAP4_MAX_PRCM_PARTITIONS];
static s32 prm_dev_inst = PRM_INSTANCE_UNKNOWN; static s32 prm_dev_inst = PRM_INSTANCE_UNKNOWN;
...@@ -41,8 +41,10 @@ static s32 prm_dev_inst = PRM_INSTANCE_UNKNOWN; ...@@ -41,8 +41,10 @@ static s32 prm_dev_inst = PRM_INSTANCE_UNKNOWN;
*/ */
void omap_prm_base_init(void) void omap_prm_base_init(void)
{ {
_prm_bases[OMAP4430_PRM_PARTITION] = prm_base; memcpy(&_prm_bases[OMAP4430_PRM_PARTITION], &prm_base,
_prm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base; sizeof(prm_base));
memcpy(&_prm_bases[OMAP4430_PRCM_MPU_PARTITION], &prcm_mpu_base,
sizeof(prcm_mpu_base));
} }
s32 omap4_prmst_get_prm_dev_inst(void) s32 omap4_prmst_get_prm_dev_inst(void)
...@@ -60,8 +62,8 @@ u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx) ...@@ -60,8 +62,8 @@ u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx)
{ {
BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
part == OMAP4430_INVALID_PRCM_PARTITION || part == OMAP4430_INVALID_PRCM_PARTITION ||
!_prm_bases[part]); !_prm_bases[part].va);
return readl_relaxed(_prm_bases[part] + inst + idx); return readl_relaxed(_prm_bases[part].va + inst + idx);
} }
/* Write into a register in a PRM instance */ /* Write into a register in a PRM instance */
...@@ -69,8 +71,8 @@ void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx) ...@@ -69,8 +71,8 @@ void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx)
{ {
BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
part == OMAP4430_INVALID_PRCM_PARTITION || part == OMAP4430_INVALID_PRCM_PARTITION ||
!_prm_bases[part]); !_prm_bases[part].va);
writel_relaxed(val, _prm_bases[part] + inst + idx); writel_relaxed(val, _prm_bases[part].va + inst + idx);
} }
/* Read-modify-write a register in PRM. Caller must lock */ /* Read-modify-write a register in PRM. Caller must lock */
......
...@@ -44,13 +44,9 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, ...@@ -44,13 +44,9 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
while (volt_data[count].volt_nominal) while (volt_data[count].volt_nominal)
count++; count++;
nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count, nvalue_table = kcalloc(count, sizeof(*nvalue_table), GFP_KERNEL);
GFP_KERNEL); if (!nvalue_table)
if (!nvalue_table) {
pr_err("OMAP: SmartReflex: cannot allocate memory for n-value table\n");
return; return;
}
for (i = 0, j = 0; i < count; i++) { for (i = 0, j = 0; i < count; i++) {
u32 v; u32 v;
...@@ -102,12 +98,9 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user) ...@@ -102,12 +98,9 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
char *name = "smartreflex"; char *name = "smartreflex";
static int i; static int i;
sr_data = kzalloc(sizeof(struct omap_sr_data), GFP_KERNEL); sr_data = kzalloc(sizeof(*sr_data), GFP_KERNEL);
if (!sr_data) { if (!sr_data)
pr_err("%s: Unable to allocate memory for %s sr_data\n",
__func__, oh->name);
return -ENOMEM; return -ENOMEM;
}
sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr; sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr;
if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) { if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) {
......
...@@ -68,6 +68,9 @@ ...@@ -68,6 +68,9 @@
static struct omap_dm_timer clkev; static struct omap_dm_timer clkev;
static struct clock_event_device clockevent_gpt; static struct clock_event_device clockevent_gpt;
/* Clockevent hwmod for am335x and am437x suspend */
static struct omap_hwmod *clockevent_gpt_hwmod;
#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
static unsigned long arch_timer_freq; static unsigned long arch_timer_freq;
...@@ -125,6 +128,23 @@ static int omap2_gp_timer_set_periodic(struct clock_event_device *evt) ...@@ -125,6 +128,23 @@ static int omap2_gp_timer_set_periodic(struct clock_event_device *evt)
return 0; return 0;
} }
static void omap_clkevt_idle(struct clock_event_device *unused)
{
if (!clockevent_gpt_hwmod)
return;
omap_hwmod_idle(clockevent_gpt_hwmod);
}
static void omap_clkevt_unidle(struct clock_event_device *unused)
{
if (!clockevent_gpt_hwmod)
return;
omap_hwmod_enable(clockevent_gpt_hwmod);
__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
}
static struct clock_event_device clockevent_gpt = { static struct clock_event_device clockevent_gpt = {
.features = CLOCK_EVT_FEAT_PERIODIC | .features = CLOCK_EVT_FEAT_PERIODIC |
CLOCK_EVT_FEAT_ONESHOT, CLOCK_EVT_FEAT_ONESHOT,
...@@ -232,15 +252,12 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, ...@@ -232,15 +252,12 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
const char **timer_name, const char **timer_name,
int posted) int posted)
{ {
char name[10]; /* 10 = sizeof("gptXX_Xck0") */
const char *oh_name = NULL; const char *oh_name = NULL;
struct device_node *np; struct device_node *np;
struct omap_hwmod *oh; struct omap_hwmod *oh;
struct resource irq, mem;
struct clk *src; struct clk *src;
int r = 0; int r = 0;
if (of_have_populated_dt()) {
np = omap_get_timer_dt(omap_timer_match, property); np = omap_get_timer_dt(omap_timer_match, property);
if (!np) if (!np)
return -ENODEV; return -ENODEV;
...@@ -255,14 +272,9 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, ...@@ -255,14 +272,9 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
timer->io_base = of_iomap(np, 0); timer->io_base = of_iomap(np, 0);
of_node_put(np); timer->fclk = of_clk_get_by_name(np, "fck");
} else {
if (omap_dm_timer_reserve_systimer(timer->id))
return -ENODEV;
sprintf(name, "timer%d", timer->id); of_node_put(np);
oh_name = name;
}
oh = omap_hwmod_lookup(oh_name); oh = omap_hwmod_lookup(oh_name);
if (!oh) if (!oh)
...@@ -270,28 +282,13 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, ...@@ -270,28 +282,13 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
*timer_name = oh->name; *timer_name = oh->name;
if (!of_have_populated_dt()) {
r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL,
&irq);
if (r)
return -ENXIO;
timer->irq = irq.start;
r = omap_hwmod_get_resource_byname(oh, IORESOURCE_MEM, NULL,
&mem);
if (r)
return -ENXIO;
/* Static mapping, never released */
timer->io_base = ioremap(mem.start, mem.end - mem.start);
}
if (!timer->io_base) if (!timer->io_base)
return -ENXIO; return -ENXIO;
omap_hwmod_setup_one(oh_name); omap_hwmod_setup_one(oh_name);
/* After the dmtimer is using hwmod these clocks won't be needed */ /* After the dmtimer is using hwmod these clocks won't be needed */
if (IS_ERR_OR_NULL(timer->fclk))
timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh));
if (IS_ERR(timer->fclk)) if (IS_ERR(timer->fclk))
return PTR_ERR(timer->fclk); return PTR_ERR(timer->fclk);
...@@ -358,6 +355,14 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, ...@@ -358,6 +355,14 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
3, /* Timer internal resynch latency */ 3, /* Timer internal resynch latency */
0xffffffff); 0xffffffff);
if (soc_is_am33xx() || soc_is_am43xx()) {
clockevent_gpt.suspend = omap_clkevt_idle;
clockevent_gpt.resume = omap_clkevt_unidle;
clockevent_gpt_hwmod =
omap_hwmod_lookup(clockevent_gpt.name);
}
pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name, pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name,
clkev.rate); clkev.rate);
} }
...@@ -405,10 +410,8 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void) ...@@ -405,10 +410,8 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
const char *oh_name = "counter_32k"; const char *oh_name = "counter_32k";
/* /*
* If device-tree is present, then search the DT blob * See if the 32kHz counter is supported.
* to see if the 32kHz counter is supported.
*/ */
if (of_have_populated_dt()) {
np = omap_get_timer_dt(omap_counter_match, NULL); np = omap_get_timer_dt(omap_counter_match, NULL);
if (!np) if (!np)
return -ENODEV; return -ENODEV;
...@@ -416,7 +419,6 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void) ...@@ -416,7 +419,6 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
if (!oh_name) if (!oh_name)
return -ENODEV; return -ENODEV;
}
/* /*
* First check hwmod data is available for sync32k counter * First check hwmod data is available for sync32k counter
...@@ -434,18 +436,6 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void) ...@@ -434,18 +436,6 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
return ret; return ret;
} }
if (!of_have_populated_dt()) {
void __iomem *vbase;
vbase = omap_hwmod_get_mpu_rt_va(oh);
ret = omap_init_clocksource_32k(vbase);
if (ret) {
pr_warn("%s: failed to initialize counter_32k as a clocksource (%d)\n",
__func__, ret);
omap_hwmod_idle(oh);
}
}
return ret; return ret;
} }
...@@ -660,96 +650,6 @@ void __init omap5_realtime_timer_init(void) ...@@ -660,96 +650,6 @@ void __init omap5_realtime_timer_init(void)
} }
#endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */ #endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */
/**
* omap_timer_init - build and register timer device with an
* associated timer hwmod
* @oh: timer hwmod pointer to be used to build timer device
* @user: parameter that can be passed from calling hwmod API
*
* Called by omap_hwmod_for_each_by_class to register each of the timer
* devices present in the system. The number of timer devices is known
* by parsing through the hwmod database for a given class name. At the
* end of function call memory is allocated for timer device and it is
* registered to the framework ready to be proved by the driver.
*/
static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
{
int id;
int ret = 0;
char *name = "omap_timer";
struct dmtimer_platform_data *pdata;
struct platform_device *pdev;
struct omap_timer_capability_dev_attr *timer_dev_attr;
pr_debug("%s: %s\n", __func__, oh->name);
/* on secure device, do not register secure timer */
timer_dev_attr = oh->dev_attr;
if (omap_type() != OMAP2_DEVICE_TYPE_GP && timer_dev_attr)
if (timer_dev_attr->timer_capability == OMAP_TIMER_SECURE)
return ret;
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
pr_err("%s: No memory for [%s]\n", __func__, oh->name);
return -ENOMEM;
}
/*
* Extract the IDs from name field in hwmod database
* and use the same for constructing ids' for the
* timer devices. In a way, we are avoiding usage of
* static variable witin the function to do the same.
* CAUTION: We have to be careful and make sure the
* name in hwmod database does not change in which case
* we might either make corresponding change here or
* switch back static variable mechanism.
*/
sscanf(oh->name, "timer%2d", &id);
if (timer_dev_attr)
pdata->timer_capability = timer_dev_attr->timer_capability;
pdata->timer_errata = omap_dm_timer_get_errata();
pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata));
if (IS_ERR(pdev)) {
pr_err("%s: Can't build omap_device for %s: %s.\n",
__func__, name, oh->name);
ret = -EINVAL;
}
kfree(pdata);
return ret;
}
/**
* omap2_dm_timer_init - top level regular device initialization
*
* Uses dedicated hwmod api to parse through hwmod database for
* given class name and then build and register the timer device.
*/
static int __init omap2_dm_timer_init(void)
{
int ret;
/* If dtb is there, the devices will be created dynamically */
if (of_have_populated_dt())
return -ENODEV;
ret = omap_hwmod_for_each_by_class("timer", omap_timer_init, NULL);
if (unlikely(ret)) {
pr_err("%s: device registration failed.\n", __func__);
return -EINVAL;
}
return 0;
}
omap_arch_initcall(omap2_dm_timer_init);
/** /**
* omap2_override_clocksource - clocksource override with user configuration * omap2_override_clocksource - clocksource override with user configuration
* *
......
...@@ -102,31 +102,3 @@ int omap2_wd_timer_reset(struct omap_hwmod *oh) ...@@ -102,31 +102,3 @@ int omap2_wd_timer_reset(struct omap_hwmod *oh)
return (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : return (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT :
omap2_wd_timer_disable(oh); omap2_wd_timer_disable(oh);
} }
static int __init omap_init_wdt(void)
{
int id = -1;
struct platform_device *pdev;
struct omap_hwmod *oh;
char *oh_name = "wd_timer2";
char *dev_name = "omap_wdt";
struct omap_wd_timer_platform_data pdata;
if (!cpu_class_is_omap2() || of_have_populated_dt())
return 0;
oh = omap_hwmod_lookup(oh_name);
if (!oh) {
pr_err("Could not look up wd_timer%d hwmod\n", id);
return -EINVAL;
}
pdata.read_reset_sources = prm_read_reset_sources;
pdev = omap_device_build(dev_name, id, oh, &pdata,
sizeof(struct omap_wd_timer_platform_data));
WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
dev_name, oh->name);
return 0;
}
omap_subsys_initcall(omap_init_wdt);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment