aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/Makefile1
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c21
-rw-r--r--arch/arm/mach-omap2/devices.c93
-rw-r--r--arch/arm/mach-omap2/id.c1
-rw-r--r--arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h56
-rw-r--r--arch/arm/mach-omap2/omap2plus-cpufreq.c209
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c124
-rw-r--r--arch/arm/mach-omap2/opp4xxx_data.c39
-rw-r--r--arch/arm/mach-omap2/pm44xx.c4
-rw-r--r--arch/arm/mach-omap2/temp_sensor_device.c95
-rw-r--r--arch/arm/plat-omap/Kconfig10
-rw-r--r--arch/arm/plat-omap/devices.c96
-rw-r--r--arch/arm/plat-omap/include/plat/dsscomp.h2
-rw-r--r--arch/arm/plat-omap/include/plat/temperature_sensor.h65
14 files changed, 658 insertions, 158 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 95fd52f..c3072d4 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
obj-$(CONFIG_OMAP_TPS6236X) += omap_tps6236x.o
+obj-$(CONFIG_OMAP_TEMP_SENSOR) +=temp_sensor_device.o
# SMP support ONLY available for OMAP4
obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index 836ab86..6f3e3a7 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -1286,11 +1286,26 @@ static struct clk l4_wkup_clk_mux_ck = {
.recalc = &omap2_clksel_recalc,
};
+static const struct clksel_rate div3_8to32_rates[] = {
+ { .div = 8, .val = 0, .flags = RATE_IN_44XX },
+ { .div = 16, .val = 1, .flags = RATE_IN_44XX },
+ { .div = 32, .val = 2, .flags = RATE_IN_44XX },
+ { .div = 0 },
+};
+
+static const struct clksel div_ts_ck_div[] = {
+ { .parent = &l4_wkup_clk_mux_ck, .rates = div3_8to32_rates },
+ { .parent = NULL },
+};
+
static struct clk div_ts_ck = {
.name = "div_ts_ck",
.parent = &l4_wkup_clk_mux_ck,
+ .clksel = div_ts_ck_div,
+ .clksel_reg = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_24_25_MASK,
.ops = &clkops_null,
- .recalc = &followparent_recalc,
+ .recalc = &omap2_clksel_recalc,
};
static const struct clksel per_abe_nc_fclk_div[] = {
@@ -3281,8 +3296,8 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "aes1_fck", &aes1_fck, CK_44XX),
CLK(NULL, "aes2_fck", &aes2_fck, CK_44XX),
CLK(NULL, "aess_fck", &aess_fck, CK_44XX),
- CLK(NULL, "bandgap_fclk", &bandgap_fclk, CK_443X),
- CLK(NULL, "bandgap_ts_fclk", &bandgap_ts_fclk, CK_446X),
+ CLK("omap_temp_sensor.0", "fck", &bandgap_fclk, CK_443X),
+ CLK("omap_temp_sensor.0", "fck", &bandgap_ts_fclk, CK_446X),
CLK(NULL, "des3des_fck", &des3des_fck, CK_44XX),
CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_44XX),
CLK(NULL, "dmic_fck", &dmic_fck, CK_44XX),
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 3dc233d..d9add97 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -33,6 +33,9 @@
#include <plat/omap_hwmod.h>
#include <plat/omap_device.h>
#include <plat/omap4-keypad.h>
+#include <plat/mcpdm.h>
+
+#include <sound/omap-abe-dsp.h>
#include "mux.h"
#include "control.h"
@@ -294,6 +297,94 @@ static inline void omap_init_mbox(void) { }
static inline void omap_init_sti(void) {}
+#if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \
+ defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE)
+
+static struct omap_device_pm_latency omap_mcpdm_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static void omap_init_mcpdm(void)
+{
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ struct omap_mcpdm_platform_data *pdata;
+ char *oh_name = "mcpdm";
+ char *dev_name = "omap-mcpdm";
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("%s: could not look up %s\n", __func__, oh_name);
+ return;
+ }
+
+ pdata = kzalloc(sizeof(struct omap_mcpdm_platform_data), GFP_KERNEL);
+ if (!pdata) {
+ pr_err("%s: could not allocate platform data\n", __func__);
+ return;
+ }
+
+ od = omap_device_build(dev_name, -1, oh, pdata,
+ sizeof(struct omap_mcpdm_platform_data),
+ omap_mcpdm_latency,
+ ARRAY_SIZE(omap_mcpdm_latency), 0);
+ WARN(IS_ERR(od), "could not build omap_device for %s:%s\n",
+ oh_name, dev_name);
+}
+#else
+static inline void omap_init_mcpdm(void) {}
+#endif
+
+#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP) || \
+ defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
+
+static struct omap_device_pm_latency omap_aess_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static void omap_init_aess(void)
+{
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ struct omap4_abe_dsp_pdata *pdata;
+ char *oh_name = "aess";
+ char *dev_name = "aess";
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("%s: could not look up %s\n", __func__, oh_name);
+ return;
+ }
+
+ pdata = kzalloc(sizeof(struct omap4_abe_dsp_pdata), GFP_KERNEL);
+ if (!pdata) {
+ pr_err("%s: could not allocate platform data\n", __func__);
+ return;
+ }
+
+ pdata->device_scale = omap_device_scale;
+
+ od = omap_device_build(dev_name, -1, oh, pdata,
+ sizeof(struct omap4_abe_dsp_pdata),
+ omap_aess_latency,
+ ARRAY_SIZE(omap_aess_latency), 0);
+ WARN(IS_ERR(od), "could not build omap_device for %s:%s\n",
+ oh_name, dev_name);
+
+ kfree(pdata);
+}
+#else
+static inline void omap_init_aess(void) {}
+#endif
+
#if defined CONFIG_ARCH_OMAP4
static struct platform_device omap_abe_dai = {
@@ -760,6 +851,8 @@ static int __init omap2_init_devices(void)
* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
+ omap_init_mcpdm();
+ omap_init_aess();
omap_init_abe();
omap_init_audio();
omap_init_camera();
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 72526f1..fe9dab5 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -242,6 +242,7 @@ static void __init omap4_check_features(void)
case 2:
/* High performance device */
omap4_features |= OMAP4_HAS_MPU_1_5GHZ;
+ omap4_features |= OMAP4_HAS_MPU_1_2GHZ;
break;
case 1:
default:
diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h
index 2f7ac70..1e60707 100644
--- a/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h
+++ b/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h
@@ -257,18 +257,50 @@
#define OMAP4_LDOSRAMCORE_ACTMODE_VSET_OUT_MASK (0x1f << 0)
/* TEMP_SENSOR */
-#define OMAP4_BGAP_TEMPSOFF_SHIFT 12
-#define OMAP4_BGAP_TEMPSOFF_MASK (1 << 12)
-#define OMAP4_BGAP_TSHUT_SHIFT 11
-#define OMAP4_BGAP_TSHUT_MASK (1 << 11)
-#define OMAP4_BGAP_TEMP_SENSOR_CONTCONV_SHIFT 10
-#define OMAP4_BGAP_TEMP_SENSOR_CONTCONV_MASK (1 << 10)
-#define OMAP4_BGAP_TEMP_SENSOR_SOC_SHIFT 9
-#define OMAP4_BGAP_TEMP_SENSOR_SOC_MASK (1 << 9)
-#define OMAP4_BGAP_TEMP_SENSOR_EOCZ_SHIFT 8
-#define OMAP4_BGAP_TEMP_SENSOR_EOCZ_MASK (1 << 8)
-#define OMAP4_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0
-#define OMAP4_BGAP_TEMP_SENSOR_DTEMP_MASK (0xff << 0)
+#define OMAP4_BGAP_TEMPSOFF_SHIFT 13
+#define OMAP4_BGAP_TEMPSOFF_MASK (1 << 13)
+#define OMAP4_BGAP_TEMP_SENSOR_CONTCONV_SHIFT 12
+#define OMAP4_BGAP_TEMP_SENSOR_CONTCONV_MASK (1 << 12)
+#define OMAP4_BGAP_TEMP_SENSOR_SOC_SHIFT 11
+#define OMAP4_BGAP_TEMP_SENSOR_SOC_MASK (1 << 11)
+#define OMAP4_BGAP_TEMP_SENSOR_EOCZ_SHIFT 10
+#define OMAP4_BGAP_TEMP_SENSOR_EOCZ_MASK (1 << 10)
+#define OMAP4_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0
+#define OMAP4_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff << 0)
+
+/* BANDGAP_CTRL */
+#define OMAP4_SINGLE_MODE_SHIFT 31
+#define OMAP4_SINGLE_MODE_MASK (1 << 31)
+#define OMAP4_MASK_HOT_SHIFT 1
+#define OMAP4_MASK_HOT_MASK (1 << 1)
+#define OMAP4_MASK_COLD_SHIFT 0
+#define OMAP4_MASK_COLD_MASK (1 << 0)
+
+/* BANDGAP_COUNTER */
+#define OMAP4_COUNTER_SHIFT 0
+#define OMAP4_COUNTER_MASK (0xffffff << 0)
+
+/* BANDGAP_THRESHOLD */
+#define OMAP4_T_HOT_SHIFT 16
+#define OMAP4_T_HOT_MASK (0x3ff << 16)
+#define OMAP4_T_COLD_SHIFT 0
+#define OMAP4_T_COLD_MASK (0x3ff << 0)
+
+/* TSHUT_THRESHOLD */
+#define OMAP4_TSHUT_HOT_SHIFT 16
+#define OMAP4_TSHUT_HOT_MASK (0x3ff << 16)
+#define OMAP4_TSHUT_COLD_SHIFT 0
+#define OMAP4_TSHUT_COLD_MASK (0x3ff << 0)
+
+/* BANDGAP_STATUS */
+#define OMAP4_CLEAN_STOP_SHIFT 3
+#define OMAP4_CLEAN_STOP_MASK (1 << 3)
+#define OMAP4_BGAP_ALERT_SHIFT 2
+#define OMAP4_BGAP_ALERT_MASK (1 << 2)
+#define OMAP4_HOT_FLAG_SHIFT 1
+#define OMAP4_HOT_FLAG_MASK (1 << 1)
+#define OMAP4_COLD_FLAG_SHIFT 0
+#define OMAP4_COLD_FLAG_MASK (1 << 0)
/* DPLL_NWELL_TRIM_0 */
#define OMAP4_DPLL_ABE_NWELL_TRIM_MUX_CTRL_SHIFT 29
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
index 883325f..99a2f77 100644
--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
@@ -46,6 +46,8 @@ struct lpj_info {
unsigned int freq;
};
+#define THROTTLE_DELAY_MS 1000
+
static DEFINE_PER_CPU(struct lpj_info, lpj_ref);
static struct lpj_info global_lpj_ref;
#endif
@@ -55,13 +57,11 @@ static atomic_t freq_table_users = ATOMIC_INIT(0);
static struct clk *mpu_clk;
static char *mpu_clk_name;
static struct device *mpu_dev;
+static DEFINE_MUTEX(omap_cpufreq_lock);
-static int omap_verify_speed(struct cpufreq_policy *policy)
-{
- if (!freq_table)
- return -EINVAL;
- return cpufreq_frequency_table_verify(policy, freq_table);
-}
+static unsigned int max_thermal;
+static unsigned int max_freq;
+static unsigned int current_target_freq;
static unsigned int omap_getspeed(unsigned int cpu)
{
@@ -74,45 +74,28 @@ static unsigned int omap_getspeed(unsigned int cpu)
return rate;
}
-static int omap_target(struct cpufreq_policy *policy,
- unsigned int target_freq,
- unsigned int relation)
+static int omap_cpufreq_scale(unsigned int target_freq, unsigned int cur_freq)
{
unsigned int i;
- int ret = 0;
+ int ret;
struct cpufreq_freqs freqs;
- if (!freq_table) {
- dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__,
- policy->cpu);
- return -EINVAL;
- }
+ freqs.new = target_freq;
+ freqs.old = omap_getspeed(0);
- ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
- relation, &i);
- if (ret) {
- dev_dbg(mpu_dev, "%s: cpu%d: no freq match for %d(ret=%d)\n",
- __func__, policy->cpu, target_freq, ret);
- return ret;
- }
- freqs.new = freq_table[i].frequency;
- if (!freqs.new) {
- dev_err(mpu_dev, "%s: cpu%d: no match for freq %d\n", __func__,
- policy->cpu, target_freq);
- return -EINVAL;
- }
-
- freqs.old = omap_getspeed(policy->cpu);
- freqs.cpu = policy->cpu;
+ /*
+ * If the new frequency is more than the thermal max allowed
+ * frequency, go ahead and scale the mpu device to proper frequency.
+ */
+ if (freqs.new > max_thermal)
+ freqs.new = max_thermal;
- if (freqs.old == freqs.new && policy->cur == freqs.new)
- return ret;
+ if ((freqs.old == freqs.new) && (cur_freq = freqs.new))
+ return 0;
/* notifiers */
- for_each_cpu(i, policy->cpus) {
- freqs.cpu = i;
+ for_each_online_cpu(freqs.cpu)
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- }
#ifdef CONFIG_CPU_FREQ_DEBUG
pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
@@ -120,7 +103,7 @@ static int omap_target(struct cpufreq_policy *policy,
ret = omap_device_scale(mpu_dev, mpu_dev, freqs.new * 1000);
- freqs.new = omap_getspeed(policy->cpu);
+ freqs.new = omap_getspeed(0);
#ifdef CONFIG_SMP
/*
@@ -128,7 +111,7 @@ static int omap_target(struct cpufreq_policy *policy,
* cpufreq driver. So, update the per-CPU loops_per_jiffy value
* on frequency transition. We need to update all dependent CPUs.
*/
- for_each_cpu(i, policy->cpus) {
+ for_each_possible_cpu(i) {
struct lpj_info *lpj = &per_cpu(lpj_ref, i);
if (!lpj->freq) {
lpj->ref = per_cpu(cpu_data, i).loops_per_jiffy;
@@ -149,11 +132,152 @@ static int omap_target(struct cpufreq_policy *policy,
#endif
/* notifiers */
- for_each_cpu(i, policy->cpus) {
- freqs.cpu = i;
+ for_each_online_cpu(freqs.cpu)
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return ret;
+}
+
+static unsigned int omap_thermal_lower_speed(void)
+{
+ unsigned int max = 0;
+ unsigned int curr;
+ int i;
+
+ curr = max_thermal;
+
+ for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++)
+ if (freq_table[i].frequency > max &&
+ freq_table[i].frequency < curr)
+ max = freq_table[i].frequency;
+
+ if (!max)
+ return curr;
+
+ return max;
+}
+
+static void throttle_delayed_work_fn(struct work_struct *work);
+
+static DECLARE_DELAYED_WORK(throttle_delayed_work, throttle_delayed_work_fn);
+
+static void throttle_delayed_work_fn(struct work_struct *work)
+{
+ unsigned int new_max;
+ unsigned int cur;
+
+ mutex_lock(&omap_cpufreq_lock);
+
+ if (max_thermal == max_freq)
+ goto out;
+
+ new_max = omap_thermal_lower_speed();
+ if (new_max == max_thermal)
+ goto out;
+
+ max_thermal = new_max;
+
+ pr_warn("%s: temperature still too high, throttling cpu to max %u\n",
+ __func__, max_thermal);
+
+ cur = omap_getspeed(0);
+ if (cur > max_thermal)
+ omap_cpufreq_scale(max_thermal, cur);
+
+ schedule_delayed_work(&throttle_delayed_work,
+ msecs_to_jiffies(THROTTLE_DELAY_MS));
+
+out:
+ mutex_unlock(&omap_cpufreq_lock);
+}
+
+void omap_thermal_throttle(void)
+{
+ unsigned int cur;
+
+ mutex_lock(&omap_cpufreq_lock);
+
+ if (max_thermal != max_freq) {
+ pr_warn("%s: already throttling\n", __func__);
+ goto out;
+ }
+
+ max_thermal = omap_thermal_lower_speed();
+
+ pr_warn("%s: temperature too high, starting cpu throttling at max %u\n",
+ __func__, max_thermal);
+
+ cur = omap_getspeed(0);
+ if (cur > max_thermal)
+ omap_cpufreq_scale(max_thermal, cur);
+
+ schedule_delayed_work(&throttle_delayed_work,
+ msecs_to_jiffies(THROTTLE_DELAY_MS));
+
+out:
+ mutex_unlock(&omap_cpufreq_lock);
+}
+
+void omap_thermal_unthrottle(void)
+{
+ unsigned int cur;
+
+ mutex_lock(&omap_cpufreq_lock);
+
+ if (max_thermal == max_freq) {
+ pr_warn("%s: not throttling\n", __func__);
+ goto out;
+ }
+
+ max_thermal = max_freq;
+
+ cancel_delayed_work_sync(&throttle_delayed_work);
+
+ pr_warn("%s: temperature reduced, ending cpu throttling\n", __func__);
+
+ cur = omap_getspeed(0);
+ omap_cpufreq_scale(current_target_freq, cur);
+
+out:
+ mutex_unlock(&omap_cpufreq_lock);
+}
+
+static int omap_verify_speed(struct cpufreq_policy *policy)
+{
+ if (!freq_table)
+ return -EINVAL;
+ return cpufreq_frequency_table_verify(policy, freq_table);
+}
+
+static int omap_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ unsigned int i;
+ int ret = 0;
+
+ if (!freq_table) {
+ dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__,
+ policy->cpu);
+ return -EINVAL;
}
+ ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
+ relation, &i);
+ if (ret) {
+ dev_dbg(mpu_dev, "%s: cpu%d: no freq match for %d(ret=%d)\n",
+ __func__, policy->cpu, target_freq, ret);
+ return ret;
+ }
+
+ mutex_lock(&omap_cpufreq_lock);
+
+ current_target_freq = freq_table[i].frequency;
+
+ ret = omap_cpufreq_scale(current_target_freq, policy->cur);
+
+ mutex_unlock(&omap_cpufreq_lock);
+
return ret;
}
@@ -166,6 +290,7 @@ static inline void freq_table_free(void)
static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
{
int result = 0;
+ int i;
mpu_clk = clk_get(NULL, mpu_clk_name);
if (IS_ERR(mpu_clk))
@@ -197,6 +322,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
policy->max = policy->cpuinfo.max_freq;
policy->cur = omap_getspeed(policy->cpu);
+ for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++)
+ max_freq = max(freq_table[i].frequency, max_freq);
+ max_thermal = max_freq;
+
/*
* On OMAP SMP configuartion, both processors share the voltage
* and clock. So both CPUs needs to be scaled together and hence
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 333e813..5562def 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -1036,6 +1036,124 @@ static struct omap_hwmod omap44xx_aess_hwmod = {
};
/*
+ * 'ctrl_module' class
+ * attila core control module
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_ctrl_module_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_ctrl_module_hwmod_class = {
+ .name = "ctrl_module",
+ .sysc = &omap44xx_ctrl_module_sysc,
+};
+
+/* ctrl_module_core */
+static struct omap_hwmod omap44xx_ctrl_module_core_hwmod;
+static struct omap_hwmod_irq_info omap44xx_ctrl_module_core_irqs[] = {
+ { .name = "sec_evts", .irq = 8 + OMAP44XX_IRQ_GIC_START },
+ { .name = "thermal_alert", .irq = 126 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_ctrl_module_core_addrs[] = {
+ {
+ .pa_start = 0x4a002000,
+ .pa_end = 0x4a0027ff,
+
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> ctrl_module_core */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ctrl_module_core = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_ctrl_module_core_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_ctrl_module_core_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_ctrl_module_core_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* ctrl_module_core slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_ctrl_module_core_slaves[] = {
+ &omap44xx_l4_cfg__ctrl_module_core,
+};
+
+static struct omap_hwmod omap44xx_ctrl_module_core_hwmod = {
+ .name = "ctrl_module_core",
+ .class = &omap44xx_ctrl_module_hwmod_class,
+ .mpu_irqs = omap44xx_ctrl_module_core_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_ctrl_module_core_irqs),
+ .main_clk = "l4_div_ck",
+ .slaves = omap44xx_ctrl_module_core_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_ctrl_module_core_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP446X),
+};
+/*
+ * 'thermal_sensor' class
+ * thermal sensor module inside the bandgap / control module
+ */
+
+static struct omap_hwmod_class omap44xx_thermal_sensor_hwmod_class = {
+ .name = "thermal_sensor",
+};
+
+static struct omap_hwmod_irq_info omap44xx_thermal_sensor_irqs[] = {
+ { .name = "thermal_alert", .irq = 126 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_thermal_sensor_addrs[] = {
+ {
+ .pa_start = 0x4a002378,
+ .pa_end = 0x4a0023ff,
+ },
+};
+
+static struct omap_hwmod omap44xx_thermal_sensor_hwmod;
+/* l4_cfg -> ctrl_module_core */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__thermal_sensor = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_thermal_sensor_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_thermal_sensor_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_thermal_sensor_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* ctrl_module_core slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_thermal_sensor_slaves[] = {
+ &omap44xx_l4_cfg__thermal_sensor,
+};
+
+static struct omap_hwmod_opt_clk thermal_sensor446x_opt_clks[] = {
+ { .role = "fclk", .clk = "bandgap_ts_fclk" },
+};
+
+static struct omap_hwmod omap44xx_thermal_sensor_hwmod = {
+ .name = "thermal_sensor",
+ .class = &omap44xx_thermal_sensor_hwmod_class,
+ .mpu_irqs = omap44xx_thermal_sensor_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_thermal_sensor_irqs),
+ .main_clk = "bandgap_ts_fclk",
+ .slaves = omap44xx_thermal_sensor_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_thermal_sensor_slaves),
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
+ },
+ },
+ .opt_clks = thermal_sensor446x_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(thermal_sensor446x_opt_clks),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP446X),
+};
+
+/*
* 'bandgap' class
* bangap reference for ldo regulators
*/
@@ -5947,6 +6065,12 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
&omap44xx_timer10_hwmod,
&omap44xx_timer11_hwmod,
+ /* ctrl module class */
+ &omap44xx_ctrl_module_core_hwmod,
+
+ /* thermal sensor hwmod */
+ &omap44xx_thermal_sensor_hwmod,
+
/* uart class */
&omap44xx_uart1_hwmod,
&omap44xx_uart2_hwmod,
diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c
index 9ea8aa7..1d5400f 100644
--- a/arch/arm/mach-omap2/opp4xxx_data.c
+++ b/arch/arm/mach-omap2/opp4xxx_data.c
@@ -19,8 +19,10 @@
* GNU General Public License for more details.
*/
#include <linux/module.h>
+#include <linux/opp.h>
#include <plat/cpu.h>
+#include <plat/common.h>
#include "control.h"
#include "omap_opp_data.h"
@@ -228,12 +230,7 @@ static struct omap_opp_def __initdata omap446x_opp_def_list[] = {
OPP_INITIALIZER("mpu", "virt_dpll_mpu_ck", "mpu", true, 700000000, OMAP4460_VDD_MPU_OPP100_UV),
/* MPU OPP3 - OPP-Turbo */
OPP_INITIALIZER("mpu", "virt_dpll_mpu_ck", "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...
- */
+ /* MPU OPP4 - OPP-Nitro */
OPP_INITIALIZER("mpu", "virt_dpll_mpu_ck", "mpu", false, 1200000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
/* MPU OPP4 - OPP-Nitro SpeedBin */
OPP_INITIALIZER("mpu", "virt_dpll_mpu_ck", "mpu", false, 1500000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
@@ -286,6 +283,28 @@ static struct omap_opp_def __initdata omap446x_opp_def_list[] = {
};
/**
+ * omap4_mpu_opp_enable() - helper to enable the OPP
+ * @freq: frequency to enable
+ */
+static void __init omap4_mpu_opp_enable(unsigned long freq)
+{
+ struct device *mpu_dev;
+ int r;
+
+ mpu_dev = omap2_get_mpuss_device();
+ if (!mpu_dev) {
+ pr_err("%s: no mpu_dev, did not enable f=%ld\n", __func__,
+ freq);
+ return;
+ }
+
+ r = opp_enable(mpu_dev, freq);
+ if (r < 0)
+ dev_err(mpu_dev, "%s: opp_enable failed(%d) f=%ld\n", __func__,
+ r, freq);
+}
+
+/**
* omap4_opp_init() - initialize omap4 opp table
*/
int __init omap4_opp_init(void)
@@ -300,6 +319,14 @@ int __init omap4_opp_init(void)
else if (cpu_is_omap446x())
r = omap_init_opp_table(omap446x_opp_def_list,
ARRAY_SIZE(omap446x_opp_def_list));
+
+ if (!r) {
+ if (omap4_has_mpu_1_2ghz())
+ omap4_mpu_opp_enable(1200000000);
+ if (omap4_has_mpu_1_5ghz())
+ omap4_mpu_opp_enable(1500000000);
+ }
+
return r;
}
device_initcall(omap4_opp_init);
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index faf93ec..2d3bb51 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -26,6 +26,7 @@
#include <mach/omap4-common.h>
#include <plat/omap_hsi.h>
#include <plat/common.h>
+#include <plat/temperature_sensor.h>
#include <plat/usb.h>
#include "powerdomain.h"
@@ -144,6 +145,7 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend)
omap_vc_set_auto_trans(iva_voltdm,
OMAP_VC_CHANNEL_AUTO_TRANSITION_RETENTION);
+ omap_temp_sensor_prepare_idle();
omap2_gpio_prepare_for_idle(0);
}
}
@@ -159,6 +161,8 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend)
OMAP_VC_CHANNEL_AUTO_TRANSITION_DISABLE);
omap_vc_set_auto_trans(iva_voltdm,
OMAP_VC_CHANNEL_AUTO_TRANSITION_DISABLE);
+
+ omap_temp_sensor_resume_idle();
omap2_gpio_resume_after_idle();
if (!suspend) {
omap_sr_enable(iva_voltdm);
diff --git a/arch/arm/mach-omap2/temp_sensor_device.c b/arch/arm/mach-omap2/temp_sensor_device.c
new file mode 100644
index 0000000..0a647a3
--- /dev/null
+++ b/arch/arm/mach-omap2/temp_sensor_device.c
@@ -0,0 +1,95 @@
+/*
+ * OMAP on die Temperature sensor device file
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: J Keerthy <j-keerthy@ti.com>
+ *
+ * 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 in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <plat/omap_device.h>
+#include "control.h"
+#include "pm.h"
+#include <plat/temperature_sensor.h>
+
+void omap_temp_sensor_resume_idle(void)
+{
+ omap_temp_sensor_idle(0);
+}
+
+void omap_temp_sensor_prepare_idle(void)
+{
+ omap_temp_sensor_idle(1);
+}
+
+static struct omap_device_pm_latency omap_temp_sensor_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ }
+};
+
+static int temp_sensor_dev_init(struct omap_hwmod *oh, void *user)
+{
+ struct omap_temp_sensor_pdata *temp_sensor_pdata;
+ struct omap_device *od;
+ static int i;
+ int ret = 0;
+
+ temp_sensor_pdata =
+ kzalloc(sizeof(struct omap_temp_sensor_pdata), GFP_KERNEL);
+ if (!temp_sensor_pdata) {
+ pr_err
+ ("%s: Unable to allocate memory for %s.Error!\n",
+ __func__, oh->name);
+ return -ENOMEM;
+ }
+
+ temp_sensor_pdata->offset = OMAP4_CTRL_MODULE_CORE_TEMP_SENSOR;
+
+ temp_sensor_pdata->name = "omap_temp_sensor";
+
+ od = omap_device_build(temp_sensor_pdata->name, i, oh, temp_sensor_pdata,
+ sizeof(*temp_sensor_pdata),
+ omap_temp_sensor_latency,
+ ARRAY_SIZE(omap_temp_sensor_latency), 0);
+ if (IS_ERR(od)) {
+ pr_warning("%s: Could not build omap_device for %s: %s.\n\n",
+ __func__, temp_sensor_pdata->name, oh->name);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ i++;
+done:
+ kfree(temp_sensor_pdata);
+ return ret;
+}
+
+int __init omap_devinit_temp_sensor(void)
+{
+ if (!cpu_is_omap446x())
+ return 0;
+
+ return omap_hwmod_for_each_by_class("thermal_sensor",
+ temp_sensor_dev_init, NULL);
+}
+
+arch_initcall(omap_devinit_temp_sensor);
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index e85abd8..77a1f82 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -220,6 +220,16 @@ config OMAP_SERIAL_WAKE
to data on the serial RX line. This allows you to wake the
system from serial console.
+config OMAP_TEMP_SENSOR
+ bool "OMAP Temp Sensor Support"
+ depends on ARCH_OMAP4
+ default n
+ help
+ Say Y here if you want support for the temp sensor on OMAP4460.
+ This provides the temperature of the MPU
+ subsystem. Only one instance of on die temperature
+ sensor is present.
+
# this carveout should probably become generic and not omap specific
config OMAP_REMOTEPROC_MEMPOOL_SIZE
hex "Physical carveout memory pool size (Byte)"
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index bb60ff7..d8add7e7 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -30,12 +30,9 @@
#include <mach/gpio.h>
#include <plat/menelaus.h>
#include <plat/mcbsp.h>
-#include <plat/mcpdm.h>
#include <plat/remoteproc.h>
#include <plat/omap44xx.h>
-#include <sound/omap-abe-dsp.h>
-
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_OMAP_MCBSP) || defined(CONFIG_OMAP_MCBSP_MODULE)
@@ -81,48 +78,6 @@ void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
/*-------------------------------------------------------------------------*/
-#if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \
- defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE)
-
-static struct omap_device_pm_latency omap_mcpdm_latency[] = {
- {
- .deactivate_func = omap_device_idle_hwmods,
- .activate_func = omap_device_enable_hwmods,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
- },
-};
-
-static void omap_init_mcpdm(void)
-{
- struct omap_hwmod *oh;
- struct omap_device *od;
- struct omap_mcpdm_platform_data *pdata;
-
- oh = omap_hwmod_lookup("mcpdm");
- if (!oh) {
- printk(KERN_ERR "Could not look up mcpdm hw_mod\n");
- return;
- }
-
- pdata = kzalloc(sizeof(struct omap_mcpdm_platform_data), GFP_KERNEL);
- if (!pdata) {
- printk(KERN_ERR "Could not allocate platform data\n");
- return;
- }
-
- od = omap_device_build("omap-mcpdm", -1, oh, pdata,
- sizeof(struct omap_mcpdm_platform_data),
- omap_mcpdm_latency,
- ARRAY_SIZE(omap_mcpdm_latency), 0);
- if (IS_ERR(od))
- printk(KERN_ERR "Could not build omap_device for omap-mcpdm-dai\n");
-}
-#else
-static inline void omap_init_mcpdm(void) {}
-#endif
-
-/*-------------------------------------------------------------------------*/
-
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
@@ -173,55 +128,6 @@ fail:
/*-------------------------------------------------------------------------*/
-#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP) || \
- defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
-
-static struct omap_device_pm_latency omap_aess_latency[] = {
- {
- .deactivate_func = omap_device_idle_hwmods,
- .activate_func = omap_device_enable_hwmods,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
- },
-};
-
-static void omap_init_aess(void)
-{
- struct omap_hwmod *oh;
- struct omap_device *od;
- struct omap4_abe_dsp_pdata *pdata;
-
- oh = omap_hwmod_lookup("aess");
- if (!oh) {
- printk (KERN_ERR "Could not look up aess hw_mod\n");
- return;
- }
-
- pdata = kzalloc(sizeof(struct omap4_abe_dsp_pdata), GFP_KERNEL);
- if (!pdata) {
- printk(KERN_ERR "Could not allocate platform data\n");
- return;
- }
-
- /* FIXME: Add correct context loss counter */
- //pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
-
- od = omap_device_build("aess", -1, oh, pdata,
- sizeof(struct omap4_abe_dsp_pdata),
- omap_aess_latency,
- ARRAY_SIZE(omap_aess_latency), 0);
-
- kfree(pdata);
-
- if (IS_ERR(od))
- printk(KERN_ERR "Could not build omap_device for omap-aess-audio\n");
-}
-#else
-static inline void omap_init_aess(void) {}
-#endif
-
-
-/*-------------------------------------------------------------------------*/
-
#if defined(CONFIG_HW_RANDOM_OMAP) || defined(CONFIG_HW_RANDOM_OMAP_MODULE)
#ifdef CONFIG_ARCH_OMAP2
@@ -421,8 +327,6 @@ static int __init omap_init_devices(void)
* in alphabetical order so they're easier to sort through.
*/
omap_init_rng();
- omap_init_mcpdm();
- omap_init_aess();
omap_init_uwire();
return 0;
}
diff --git a/arch/arm/plat-omap/include/plat/dsscomp.h b/arch/arm/plat-omap/include/plat/dsscomp.h
index b9f5773..f9f87cb 100644
--- a/arch/arm/plat-omap/include/plat/dsscomp.h
+++ b/arch/arm/plat-omap/include/plat/dsscomp.h
@@ -18,7 +18,7 @@ int dsscomp_delayed_apply(dsscomp_t comp);
void dsscomp_drop(dsscomp_t c);
struct tiler_pa_info;
-int dsscomp_gralloc_queue(struct dsscomp_setup_mgr_data *d,
+int dsscomp_gralloc_queue(struct dsscomp_setup_dispc_data *d,
struct tiler_pa_info **pas,
void (*cb_fn)(void *, int), void *cb_arg);
#endif
diff --git a/arch/arm/plat-omap/include/plat/temperature_sensor.h b/arch/arm/plat-omap/include/plat/temperature_sensor.h
new file mode 100644
index 0000000..5f0d6b3
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/temperature_sensor.h
@@ -0,0 +1,65 @@
+/*
+ * OMAP446x Temperature sensor header file
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: J Keerthy <j-keerthy@ti.com>
+ *
+ * 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 in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_TEMPERATURE_SENSOR_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_TEMPERATURE_SENSOR_H
+
+/*
+ * Offsets from the base of temperature sensor registers
+ */
+#define TEMP_SENSOR_CTRL_OFFSET 0x00
+#define BGAP_CTRL_OFFSET 0x4c
+#define BGAP_COUNTER_OFFSET 0x50
+#define BGAP_THRESHOLD_OFFSET 0x54
+#define BGAP_TSHUT_OFFSET 0x58
+#define BGAP_STATUS_OFFSET 0x5c
+
+#define OMAP_TSHUT_GPIO 86
+
+
+/*
+ * omap_temp_sensor platform data
+ * @name - name
+ * @irq - Irq number for thermal alertemp_sensor
+ * @offset - offset of the temp sensor ctrl register
+ */
+struct omap_temp_sensor_pdata {
+ char *name;
+ u32 offset;
+ int irq;
+};
+
+#ifdef CONFIG_OMAP_TEMP_SENSOR
+void omap_temp_sensor_resume_idle(void);
+void omap_temp_sensor_prepare_idle(void);
+#else
+static inline void omap_temp_sensor_resume_idle(void) { }
+static inline void omap_temp_sensor_prepare_idle(void) { }
+#endif
+
+#ifdef CONFIG_OMAP_DIE_TEMP_SENSOR
+void omap_temp_sensor_idle(int idle_state);
+#else
+static inline void omap_temp_sensor_idle(int idle_state) { }
+#endif
+
+#endif