summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDjamil Elaidi <d-elaidi@ti.com>2011-06-28 11:25:12 +0200
committerSebastien Jan <s-jan@ti.com>2011-07-05 14:29:52 +0200
commit7d16749e4d0366c21e04a5a50e6c8e06b9e4ad0f (patch)
treeb0515561ad6331644c7f9666cd0fb03c50bcd2be /drivers
parent7b3ce51ea4f579f1f352e437bdc88494a6fdab54 (diff)
OMAP4: HSI: SW WA for HSR in dead state after SW reset with pending errors
SW WA for HSI-C1BUG00088 "OMAP4430 HSI : No recovery from SW reset under specific circumstances" Description of issue: It seems that in certain cases after some errors are detected by HSR (frame timeout and/or tailing bit error and/or overrun), writing the SW reset bit (SYSCONFIG.SOFTERESET to 1) may put the HSI in a "dead" state in which it does not answer anymore to L4 OCP commands. It seems that in certain cases after some errors are detected by HSR (frame timeout and/or tailing bit error and/or overrun), writing the SW reset bit (SYSCONFIG.SOFTERESET to 1) may put the HSI in a "dead" state in which it does not answer anymore to L4 OCP commands. Workaround is: * Set HSR_MODE_P1.MODE_VAL = sleep and HSR_MODE_P2.MODE_VAL = sleep * Acknowledge all errors (do not care if there is any) by writing HSR_ERRORACK_P1 and HSR_ERRORACK_P2 * Set SW reset HW fix will be available for OMAP5430 Other changes: * Removed write to Read only register HSI_HSR_BREAK_REG Change-Id: I023d0fc8656808a8c294d7cfaec1bf3cb46da93f Signed-off-by: Djamil Elaidi <d-elaidi@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/omap_hsi/hsi_driver.c24
-rw-r--r--drivers/staging/omap_hsi/hsi_driver_if.c2
-rw-r--r--drivers/staging/omap_hsi/hsi_driver_int.c1
3 files changed, 24 insertions, 3 deletions
diff --git a/drivers/staging/omap_hsi/hsi_driver.c b/drivers/staging/omap_hsi/hsi_driver.c
index 8912dc0fc346..06368ea31886 100644
--- a/drivers/staging/omap_hsi/hsi_driver.c
+++ b/drivers/staging/omap_hsi/hsi_driver.c
@@ -272,12 +272,27 @@ void hsi_set_pm_force_hsi_on(struct hsi_dev *hsi_ctrl)
/* HSI_TODO : use the HWMOD API : omap_hwmod_set_slave_idlemode() */
}
+/**
+* hsi_softreset - Force a SW RESET of HSI (core + DMA)
+*
+* @hsi_ctrl - reference to the hsi controller to be reset.
+*
+*/
int hsi_softreset(struct hsi_dev *hsi_ctrl)
{
unsigned int ind = 0;
+ unsigned int port;
void __iomem *base = hsi_ctrl->base;
u32 status;
+ /* SW WA for HSI-C1BUG00088 OMAP4430 HSI : No recovery from SW reset */
+ /* under specific circumstances */
+ for (port = 1; port <= hsi_ctrl->max_p; port++) {
+ hsi_outl_and(HSI_HSR_MODE_MODE_VAL_SLEEP, base,
+ HSI_HSR_MODE_REG(port));
+ hsi_outl(HSI_HSR_ERROR_ALL, base, HSI_HSR_ERRORACK_REG(port));
+ }
+
/* Reseting HSI Block */
hsi_outl_or(HSI_SOFTRESET, base, HSI_SYS_SYSCONFIG_REG);
do {
@@ -405,6 +420,13 @@ static int hsi_port_channels_reset(struct hsi_port *port)
return 0;
}
+/**
+* hsi_softreset_driver - Must be called following HSI SW RESET, to re-align
+* variable states with new HW state.
+*
+* @hsi_ctrl - reference to the hsi controller to be re-aligned.
+*
+*/
void hsi_softreset_driver(struct hsi_dev *hsi_ctrl)
{
struct platform_device *pd = to_platform_device(hsi_ctrl->dev);
@@ -1000,7 +1022,7 @@ int hsi_runtime_suspend(struct device *dev)
HSI_HSR_MODE_REG(port));
}
- /* HSI is going to INA/RET/OFF, it needs IO wakeup mechanism enabled */
+ /* HSI is going to IDLE, it needs IO wakeup mechanism enabled */
if (device_may_wakeup(dev))
pdata->wakeup_enable(0);
else
diff --git a/drivers/staging/omap_hsi/hsi_driver_if.c b/drivers/staging/omap_hsi/hsi_driver_if.c
index 6a106e71922c..929bb938b914 100644
--- a/drivers/staging/omap_hsi/hsi_driver_if.c
+++ b/drivers/staging/omap_hsi/hsi_driver_if.c
@@ -676,7 +676,7 @@ EXPORT_SYMBOL(hsi_unpoll);
* @command - HSI I/O control command
* @arg - parameter associated to the control command. NULL, if no parameter.
*
- * Return 0 on sucess, a negative value on failure.
+ * Return 0 on success, a negative value on failure.
*
*/
int hsi_ioctl(struct hsi_device *dev, unsigned int command, void *arg)
diff --git a/drivers/staging/omap_hsi/hsi_driver_int.c b/drivers/staging/omap_hsi/hsi_driver_int.c
index 1a6117c4ed06..94d859ab3f2c 100644
--- a/drivers/staging/omap_hsi/hsi_driver_int.c
+++ b/drivers/staging/omap_hsi/hsi_driver_int.c
@@ -562,7 +562,6 @@ static u32 hsi_driver_int_proc(struct hsi_port *pport,
if (status_reg & HSI_BREAKDETECTED) {
dev_info(hsi_ctrl->dev, "Hardware BREAK on port %d\n", port);
- hsi_outl(0, base, HSI_HSR_BREAK_REG(port));
spin_unlock(&hsi_ctrl->lock);
hsi_port_event_handler(pport, HSI_EVENT_BREAK_DETECTED, NULL);
spin_lock(&hsi_ctrl->lock);