Fixes for omaps that were not considered urgent enough for the -rc cycle.

This is mostly to enable errata 798181 and thermal support for dra7,
 configure ocp2scp for am437x, remove dead code for OMAP4_ERRATA_I688
 and fix build warnings for omap1510 only config.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJVFc/qAAoJEBvUPslcq6VzopMQAN8i0DkYqm8cM8mK/UitjG7o
 +vfGo2ik3sk7AidU7vnjLdQFJOxo8T9LI9+OGr2YJ9JmbzkH1H2QsGVF/MYTaox7
 i/Eb9MEPFuu9ek3iKAUVVwPTHi0ft3/W5EzwHIdKHHz6UGjrVuBNxyInNXJiVm4y
 mAragQWKQGwtSEqCpdSDgkzBh0VOPo9BSpa/1QXOsYLarOurAUNPKgbc6VoSzF9d
 nkvbwlXhVobvVIv5Qyhef9CHssRGL6pEgvJIoNVcqgBzjrPgat4l+qYE4ns/FEMp
 LjbE2p3pr2ODECC5xETWFqtKXlqywj1+4HtEcGOD6L52fBdpE5yshOEa81goHpI2
 WMu4l4qus+u92g/012sOMH/KT0lTDPj1OTnjtgxonpmi12oJjWtKy/WQsussBfIU
 ttAiCZCoEguKrWAFiYZ4A3x5cUHFiC0Xn99h0p6I6fc434ORy6T5uBotgjGfQuBr
 YkpS8ok6wNkYWQUpxji0dO0MkUjf2VbQXWuFfhs5sK2yiwv6cDNK5a8rpDvgls1H
 JMwRxqqX7jL9d+yYXban6PZv2BKSpOzJTOVEdvpFUUYMHtRoNMqkAIuhtKtWWclc
 W9CnZCx2CBvfaz+Hs7IACWy7KhdhYj5xjiBgSpykJVWHmHU3HugbY27LJnxTFd2n
 ElZlY1NH1iZPjeAl3Q43
 =Uqd0
 -----END PGP SIGNATURE-----

Merge tag 'omap-for-v4.1/fixes-0' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/fixes-non-critical

Merge "omap non-urgent fixes for v4.1" from Tony Lindgren:

Fixes for omaps that were not considered urgent enough for the -rc cycle.

This is mostly to enable errata 798181 and thermal support for dra7,
configure ocp2scp for am437x, remove dead code for OMAP4_ERRATA_I688
and fix build warnings for omap1510 only config.

* tag 'omap-for-v4.1/fixes-0' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  ARM: DRA7: Enable Cortex A15 errata 798181
  ARM: dts: am57xx-beagle-x15: Add thermal map to include fan and tmp102
  ARM: dts: DRA7: Add bandgap and related thermal nodes
  bus: ocp2scp: SYNC2 value should be changed to 0x6
  ARM: dts: am4372: Add "ti,am437x-ocp2scp" as compatible string for OCP2SCP
  ARM: OMAP2+: remove superfluous NULL pointer check
  ARM: OMAP4: remove dead kconfig option OMAP4_ERRATA_I688
  MAINTAINERS: add OMAP defconfigs under OMAP SUPPORT
  ARM: OMAP1: PM: fix some build warnings on 1510-only Kconfigs

Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
Olof Johansson 2015-04-03 13:40:34 -07:00
commit 77e3c09e45
18 changed files with 151 additions and 137 deletions

View File

@ -1,7 +1,8 @@
* OMAP OCP2SCP - ocp interface to scp interface * OMAP OCP2SCP - ocp interface to scp interface
properties: properties:
- compatible : Should be "ti,omap-ocp2scp" - compatible : Should be "ti,am437x-ocp2scp" for AM437x processor
Should be "ti,omap-ocp2scp" for all others
- reg : Address and length of the register set for the device - reg : Address and length of the register set for the device
- #address-cells, #size-cells : Must be present if the device has sub-nodes - #address-cells, #size-cells : Must be present if the device has sub-nodes
- ranges : the child address space are mapped 1:1 onto the parent address space - ranges : the child address space are mapped 1:1 onto the parent address space

View File

@ -6947,6 +6947,8 @@ Q: http://patchwork.kernel.org/project/linux-omap/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git
S: Maintained S: Maintained
F: arch/arm/*omap*/ F: arch/arm/*omap*/
F: arch/arm/configs/omap1_defconfig
F: arch/arm/configs/omap2plus_defconfig
F: drivers/i2c/busses/i2c-omap.c F: drivers/i2c/busses/i2c-omap.c
F: drivers/irqchip/irq-omap-intc.c F: drivers/irqchip/irq-omap-intc.c
F: drivers/mfd/*omap*.c F: drivers/mfd/*omap*.c

View File

@ -787,7 +787,7 @@
}; };
ocp2scp0: ocp2scp@483a8000 { ocp2scp0: ocp2scp@483a8000 {
compatible = "ti,omap-ocp2scp"; compatible = "ti,am437x-ocp2scp", "ti,omap-ocp2scp";
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
ranges; ranges;
@ -806,7 +806,7 @@
}; };
ocp2scp1: ocp2scp@483e8000 { ocp2scp1: ocp2scp@483e8000 {
compatible = "ti,omap-ocp2scp"; compatible = "ti,am437x-ocp2scp", "ti,omap-ocp2scp";
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
ranges; ranges;

View File

@ -87,6 +87,7 @@
gpios = <&tps659038_gpio 1 GPIO_ACTIVE_HIGH>; gpios = <&tps659038_gpio 1 GPIO_ACTIVE_HIGH>;
gpio-fan,speed-map = <0 0>, gpio-fan,speed-map = <0 0>,
<13000 1>; <13000 1>;
#cooling-cells = <2>;
}; };
extcon_usb1: extcon_usb1 { extcon_usb1: extcon_usb1 {
@ -442,6 +443,7 @@
pinctrl-0 = <&tmp102_pins_default>; pinctrl-0 = <&tmp102_pins_default>;
interrupt-parent = <&gpio7>; interrupt-parent = <&gpio7>;
interrupts = <16 IRQ_TYPE_LEVEL_LOW>; interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
#thermal-sensor-cells = <1>;
}; };
}; };
@ -552,3 +554,50 @@
&usb2 { &usb2 {
dr_mode = "peripheral"; dr_mode = "peripheral";
}; };
&cpu_trips {
cpu_alert1: cpu_alert1 {
temperature = <50000>; /* millicelsius */
hysteresis = <2000>; /* millicelsius */
type = "active";
};
};
&cpu_cooling_maps {
map1 {
trip = <&cpu_alert1>;
cooling-device = <&gpio_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
&thermal_zones {
board_thermal: board_thermal {
polling-delay-passive = <1250>; /* milliseconds */
polling-delay = <1500>; /* milliseconds */
/* sensor ID */
thermal-sensors = <&tmp102 0>;
board_trips: trips {
board_alert0: board_alert {
temperature = <40000>; /* millicelsius */
hysteresis = <2000>; /* millicelsius */
type = "active";
};
board_crit: board_crit {
temperature = <105000>; /* millicelsius */
hysteresis = <0>; /* millicelsius */
type = "critical";
};
};
board_cooling_maps: cooling-maps {
map0 {
trip = <&board_alert0>;
cooling-device =
<&gpio_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
};
};

View File

@ -177,6 +177,18 @@
}; };
}; };
bandgap: bandgap@4a0021e0 {
reg = <0x4a0021e0 0xc
0x4a00232c 0xc
0x4a002380 0x2c
0x4a0023C0 0x3c
0x4a002564 0x8
0x4a002574 0x50>;
compatible = "ti,dra752-bandgap";
interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
#thermal-sensor-cells = <1>;
};
cm_core_aon: cm_core_aon@4a005000 { cm_core_aon: cm_core_aon@4a005000 {
compatible = "ti,dra7-cm-core-aon"; compatible = "ti,dra7-cm-core-aon";
reg = <0x4a005000 0x2000>; reg = <0x4a005000 0x2000>;
@ -1426,6 +1438,17 @@
status = "disabled"; status = "disabled";
}; };
}; };
thermal_zones: thermal-zones {
#include "omap4-cpu-thermal.dtsi"
#include "omap5-gpu-thermal.dtsi"
#include "omap5-core-thermal.dtsi"
};
};
&cpu_thermal {
polling-delay = <500>; /* milliseconds */
}; };
/include/ "dra7xx-clocks.dtsi" /include/ "dra7xx-clocks.dtsi"

View File

@ -20,6 +20,11 @@
device_type = "cpu"; device_type = "cpu";
compatible = "arm,cortex-a15"; compatible = "arm,cortex-a15";
reg = <0>; reg = <0>;
/* cooling options */
cooling-min-level = <0>;
cooling-max-level = <2>;
#cooling-cells = <2>; /* min followed by max */
}; };
}; };

View File

@ -31,6 +31,11 @@
clock-names = "cpu"; clock-names = "cpu";
clock-latency = <300000>; /* From omap-cpufreq driver */ clock-latency = <300000>; /* From omap-cpufreq driver */
/* cooling options */
cooling-min-level = <0>;
cooling-max-level = <2>;
#cooling-cells = <2>; /* min followed by max */
}; };
cpu@1 { cpu@1 {
device_type = "cpu"; device_type = "cpu";

View File

@ -18,7 +18,7 @@ cpu_thermal: cpu_thermal {
/* sensor ID */ /* sensor ID */
thermal-sensors = <&bandgap 0>; thermal-sensors = <&bandgap 0>;
trips { cpu_trips: trips {
cpu_alert0: cpu_alert { cpu_alert0: cpu_alert {
temperature = <100000>; /* millicelsius */ temperature = <100000>; /* millicelsius */
hysteresis = <2000>; /* millicelsius */ hysteresis = <2000>; /* millicelsius */
@ -31,7 +31,7 @@ cpu_thermal: cpu_thermal {
}; };
}; };
cooling-maps { cpu_cooling_maps: cooling-maps {
map0 { map0 {
trip = <&cpu_alert0>; trip = <&cpu_alert0>;
cooling-device = cooling-device =

View File

@ -71,13 +71,7 @@ static unsigned int mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_SIZE];
static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE]; static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
#ifndef CONFIG_OMAP_32K_TIMER static unsigned short enable_dyn_sleep;
static unsigned short enable_dyn_sleep = 0;
#else
static unsigned short enable_dyn_sleep = 1;
static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr, static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf) char *buf)
@ -90,8 +84,9 @@ static ssize_t idle_store(struct kobject *kobj, struct kobj_attribute *attr,
{ {
unsigned short value; unsigned short value;
if (sscanf(buf, "%hu", &value) != 1 || if (sscanf(buf, "%hu", &value) != 1 ||
(value != 0 && value != 1)) { (value != 0 && value != 1) ||
printk(KERN_ERR "idle_sleep_store: Invalid value\n"); (value != 0 && !IS_ENABLED(CONFIG_OMAP_32K_TIMER))) {
pr_err("idle_sleep_store: Invalid value\n");
return -EINVAL; return -EINVAL;
} }
enable_dyn_sleep = value; enable_dyn_sleep = value;
@ -101,7 +96,6 @@ static ssize_t idle_store(struct kobject *kobj, struct kobj_attribute *attr,
static struct kobj_attribute sleep_while_idle_attr = static struct kobj_attribute sleep_while_idle_attr =
__ATTR(sleep_while_idle, 0644, idle_show, idle_store); __ATTR(sleep_while_idle, 0644, idle_show, idle_store);
#endif
static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL; static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
@ -115,16 +109,11 @@ void omap1_pm_idle(void)
{ {
extern __u32 arm_idlect1_mask; extern __u32 arm_idlect1_mask;
__u32 use_idlect1 = arm_idlect1_mask; __u32 use_idlect1 = arm_idlect1_mask;
int do_sleep = 0;
local_fiq_disable(); local_fiq_disable();
#if defined(CONFIG_OMAP_MPU_TIMER) && !defined(CONFIG_OMAP_DM_TIMER) #if defined(CONFIG_OMAP_MPU_TIMER) && !defined(CONFIG_OMAP_DM_TIMER)
#warning Enable 32kHz OS timer in order to allow sleep states in idle
use_idlect1 = use_idlect1 & ~(1 << 9); use_idlect1 = use_idlect1 & ~(1 << 9);
#else
if (enable_dyn_sleep)
do_sleep = 1;
#endif #endif
#ifdef CONFIG_OMAP_DM_TIMER #ifdef CONFIG_OMAP_DM_TIMER
@ -134,10 +123,12 @@ void omap1_pm_idle(void)
if (omap_dma_running()) if (omap_dma_running())
use_idlect1 &= ~(1 << 6); use_idlect1 &= ~(1 << 6);
/* We should be able to remove the do_sleep variable and multiple /*
* We should be able to remove the do_sleep variable and multiple
* tests above as soon as drivers, timer and DMA code have been fixed. * tests above as soon as drivers, timer and DMA code have been fixed.
* Even the sleep block count should become obsolete. */ * Even the sleep block count should become obsolete.
if ((use_idlect1 != ~0) || !do_sleep) { */
if ((use_idlect1 != ~0) || !enable_dyn_sleep) {
__u32 saved_idlect1 = omap_readl(ARM_IDLECT1); __u32 saved_idlect1 = omap_readl(ARM_IDLECT1);
if (cpu_is_omap15xx()) if (cpu_is_omap15xx())
@ -635,15 +626,25 @@ static const struct platform_suspend_ops omap_pm_ops = {
static int __init omap_pm_init(void) static int __init omap_pm_init(void)
{ {
int error = 0;
#ifdef CONFIG_OMAP_32K_TIMER
int error;
#endif
if (!cpu_class_is_omap1()) if (!cpu_class_is_omap1())
return -ENODEV; return -ENODEV;
printk("Power Management for TI OMAP.\n"); pr_info("Power Management for TI OMAP.\n");
if (!IS_ENABLED(CONFIG_OMAP_32K_TIMER))
pr_info("OMAP1 PM: sleep states in idle disabled due to no 32KiHz timer\n");
if (!IS_ENABLED(CONFIG_OMAP_DM_TIMER))
pr_info("OMAP1 PM: sleep states in idle disabled due to no DMTIMER support\n");
if (IS_ENABLED(CONFIG_OMAP_32K_TIMER) &&
IS_ENABLED(CONFIG_OMAP_DM_TIMER)) {
/* OMAP16xx only */
pr_info("OMAP1 PM: sleep states in idle enabled\n");
enable_dyn_sleep = 1;
}
/* /*
* We copy the assembler sleep/wakeup routines to SRAM. * We copy the assembler sleep/wakeup routines to SRAM.
@ -693,17 +694,15 @@ static int __init omap_pm_init(void)
omap_pm_init_debugfs(); omap_pm_init_debugfs();
#endif #endif
#ifdef CONFIG_OMAP_32K_TIMER
error = sysfs_create_file(power_kobj, &sleep_while_idle_attr.attr); error = sysfs_create_file(power_kobj, &sleep_while_idle_attr.attr);
if (error) if (error)
printk(KERN_ERR "sysfs_create_file failed: %d\n", error); printk(KERN_ERR "sysfs_create_file failed: %d\n", error);
#endif
if (cpu_is_omap16xx()) { if (cpu_is_omap16xx()) {
/* configure LOW_PWR pin */ /* configure LOW_PWR pin */
omap_cfg_reg(T20_1610_LOW_PWR); omap_cfg_reg(T20_1610_LOW_PWR);
} }
return 0; return error;
} }
__initcall(omap_pm_init); __initcall(omap_pm_init);

View File

@ -69,6 +69,7 @@ config SOC_DRA7XX
select ARM_GIC select ARM_GIC
select HAVE_ARM_ARCH_TIMER select HAVE_ARM_ARCH_TIMER
select IRQ_CROSSBAR select IRQ_CROSSBAR
select ARM_ERRATA_798181 if SMP
config ARCH_OMAP2PLUS config ARCH_OMAP2PLUS
bool bool
@ -278,27 +279,6 @@ config OMAP3_SDRC_AC_TIMING
wish to say no. Selecting yes without understanding what is wish to say no. Selecting yes without understanding what is
going on could result in system crashes; going on could result in system crashes;
config OMAP4_ERRATA_I688
bool "OMAP4 errata: Async Bridge Corruption"
depends on (ARCH_OMAP4 || SOC_OMAP5) && !ARCH_MULTIPLATFORM
select ARCH_HAS_BARRIERS
help
If a data is stalled inside asynchronous bridge because of back
pressure, it may be accepted multiple times, creating pointer
misalignment that will corrupt next transfers on that data path
until next reset of the system (No recovery procedure once the
issue is hit, the path remains consistently broken). Async bridge
can be found on path between MPU to EMIF and MPU to L3 interconnect.
This situation can happen only when the idle is initiated by a
Master Request Disconnection (which is trigged by software when
executing WFI on CPU).
The work-around for this errata needs all the initiators connected
through async bridge must ensure that data path is properly drained
before issuing WFI. This condition will be met if one Strongly ordered
access is performed to the target right before executing the WFI.
In MPU case, L3 T2ASYNC FIFO and DDR T2ASYNC FIFO needs to be drained.
IO barrier ensure that there is no synchronisation loss on initiators
operating on both interconnect port simultaneously.
endmenu endmenu
endif endif

View File

@ -30,5 +30,4 @@ int __weak omap_secure_ram_reserve_memblock(void)
void __init omap_reserve(void) void __init omap_reserve(void)
{ {
omap_secure_ram_reserve_memblock(); omap_secure_ram_reserve_memblock();
omap_barrier_reserve_memblock();
} }

View File

@ -200,9 +200,6 @@ void __init omap4_map_io(void);
void __init omap5_map_io(void); void __init omap5_map_io(void);
void __init ti81xx_map_io(void); void __init ti81xx_map_io(void);
/* omap_barriers_init() is OMAP4 only */
void omap_barriers_init(void);
/** /**
* omap_test_timeout - busy-loop, testing a condition * omap_test_timeout - busy-loop, testing a condition
* @cond: condition to test until it evaluates to true * @cond: condition to test until it evaluates to true

View File

@ -306,7 +306,6 @@ void __init am33xx_map_io(void)
void __init omap4_map_io(void) void __init omap4_map_io(void)
{ {
iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc)); iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc));
omap_barriers_init();
} }
#endif #endif
@ -314,7 +313,6 @@ void __init omap4_map_io(void)
void __init omap5_map_io(void) void __init omap5_map_io(void)
{ {
iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc)); iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc));
omap_barriers_init();
} }
#endif #endif
/* /*

View File

@ -1053,7 +1053,7 @@ static void __init omap_mux_init_list(struct omap_mux_partition *partition,
struct omap_mux *entry; struct omap_mux *entry;
#ifdef CONFIG_OMAP_MUX #ifdef CONFIG_OMAP_MUX
if (!superset->muxnames || !superset->muxnames[0]) { if (!superset->muxnames[0]) {
superset++; superset++;
continue; continue;
} }

View File

@ -70,13 +70,6 @@ extern u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs,
extern u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits); extern u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits);
extern u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag); extern u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag);
#ifdef CONFIG_OMAP4_ERRATA_I688
extern int omap_barrier_reserve_memblock(void);
#else
static inline void omap_barrier_reserve_memblock(void)
{ }
#endif
#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
void set_cntfreq(void); void set_cntfreq(void);
#else #else

View File

@ -52,75 +52,6 @@ static void __iomem *twd_base;
#define IRQ_LOCALTIMER 29 #define IRQ_LOCALTIMER 29
#ifdef CONFIG_OMAP4_ERRATA_I688
/* Used to implement memory barrier on DRAM path */
#define OMAP4_DRAM_BARRIER_VA 0xfe600000
void __iomem *dram_sync, *sram_sync;
static phys_addr_t paddr;
static u32 size;
void omap_bus_sync(void)
{
if (dram_sync && sram_sync) {
writel_relaxed(readl_relaxed(dram_sync), dram_sync);
writel_relaxed(readl_relaxed(sram_sync), sram_sync);
isb();
}
}
EXPORT_SYMBOL(omap_bus_sync);
static int __init omap4_sram_init(void)
{
struct device_node *np;
struct gen_pool *sram_pool;
np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu");
if (!np)
pr_warn("%s:Unable to allocate sram needed to handle errata I688\n",
__func__);
sram_pool = of_get_named_gen_pool(np, "sram", 0);
if (!sram_pool)
pr_warn("%s:Unable to get sram pool needed to handle errata I688\n",
__func__);
else
sram_sync = (void *)gen_pool_alloc(sram_pool, PAGE_SIZE);
return 0;
}
omap_arch_initcall(omap4_sram_init);
/* Steal one page physical memory for barrier implementation */
int __init omap_barrier_reserve_memblock(void)
{
size = ALIGN(PAGE_SIZE, SZ_1M);
paddr = arm_memblock_steal(size, SZ_1M);
return 0;
}
void __init omap_barriers_init(void)
{
struct map_desc dram_io_desc[1];
dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA;
dram_io_desc[0].pfn = __phys_to_pfn(paddr);
dram_io_desc[0].length = size;
dram_io_desc[0].type = MT_MEMORY_RW_SO;
iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc));
dram_sync = (void __iomem *) dram_io_desc[0].virtual;
pr_info("OMAP4: Map 0x%08llx to 0x%08lx for dram barrier\n",
(long long) paddr, dram_io_desc[0].virtual);
}
#else
void __init omap_barriers_init(void)
{}
#endif
void gic_dist_disable(void) void gic_dist_disable(void)
{ {
if (gic_dist_base_addr) if (gic_dist_base_addr)

View File

@ -333,11 +333,9 @@ ENDPROC(omap4_cpu_resume)
#endif /* defined(CONFIG_SMP) && defined(CONFIG_PM) */ #endif /* defined(CONFIG_SMP) && defined(CONFIG_PM) */
#ifndef CONFIG_OMAP4_ERRATA_I688
ENTRY(omap_bus_sync) ENTRY(omap_bus_sync)
ret lr ret lr
ENDPROC(omap_bus_sync) ENDPROC(omap_bus_sync)
#endif
ENTRY(omap_do_wfi) ENTRY(omap_do_wfi)
stmfd sp!, {lr} stmfd sp!, {lr}

View File

@ -16,6 +16,7 @@
* *
*/ */
#include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/err.h> #include <linux/err.h>
@ -23,6 +24,9 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#define OCP2SCP_TIMING 0x18
#define SYNC2_MASK 0xf
static int ocp2scp_remove_devices(struct device *dev, void *c) static int ocp2scp_remove_devices(struct device *dev, void *c)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
@ -35,6 +39,9 @@ static int ocp2scp_remove_devices(struct device *dev, void *c)
static int omap_ocp2scp_probe(struct platform_device *pdev) static int omap_ocp2scp_probe(struct platform_device *pdev)
{ {
int ret; int ret;
u32 reg;
void __iomem *regs;
struct resource *res;
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
if (np) { if (np) {
@ -47,6 +54,32 @@ static int omap_ocp2scp_probe(struct platform_device *pdev)
} }
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
/*
* As per AM572x TRM: http://www.ti.com/lit/ug/spruhz6/spruhz6.pdf
* under section 26.3.2.2, table 26-26 OCP2SCP TIMING Caution;
* As per OMAP4430 TRM: http://www.ti.com/lit/ug/swpu231ap/swpu231ap.pdf
* under section 23.12.6.2.2 , Table 23-1213 OCP2SCP TIMING Caution;
* As per OMAP4460 TRM: http://www.ti.com/lit/ug/swpu235ab/swpu235ab.pdf
* under section 23.12.6.2.2, Table 23-1213 OCP2SCP TIMING Caution;
* As per OMAP543x TRM http://www.ti.com/lit/pdf/swpu249
* under section 27.3.2.2, Table 27-27 OCP2SCP TIMING Caution;
*
* Read path of OCP2SCP is not working properly due to low reset value
* of SYNC2 parameter in OCP2SCP. Suggested reset value is 0x6 or more.
*/
if (!of_device_is_compatible(np, "ti,am437x-ocp2scp")) {
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(regs))
goto err0;
pm_runtime_get_sync(&pdev->dev);
reg = readl_relaxed(regs + OCP2SCP_TIMING);
reg &= ~(SYNC2_MASK);
reg |= 0x6;
writel_relaxed(reg, regs + OCP2SCP_TIMING);
pm_runtime_put_sync(&pdev->dev);
}
return 0; return 0;
@ -67,6 +100,7 @@ static int omap_ocp2scp_remove(struct platform_device *pdev)
#ifdef CONFIG_OF #ifdef CONFIG_OF
static const struct of_device_id omap_ocp2scp_id_table[] = { static const struct of_device_id omap_ocp2scp_id_table[] = {
{ .compatible = "ti,omap-ocp2scp" }, { .compatible = "ti,omap-ocp2scp" },
{ .compatible = "ti,am437x-ocp2scp" },
{} {}
}; };
MODULE_DEVICE_TABLE(of, omap_ocp2scp_id_table); MODULE_DEVICE_TABLE(of, omap_ocp2scp_id_table);