Commit 1dea581f authored by Olof Johansson's avatar Olof Johansson

Merge tag 'for-v4.5-rc/omap-critical-fixes-a' of...

Merge tag 'for-v4.5-rc/omap-critical-fixes-a' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into fixes

ARM: OMAP2+: critical DRA7xx fix for v4.5-rc

Force the DRA7xx Ethernet internal clock source to stay enabled
per TI erratum i877:

http://www.ti.com/lit/er/sprz429h/sprz429h.pdf

Otherwise, if the Ethernet internal clock source is disabled, the
chip will age prematurely, and the RGMII I/O timing will soon
fail to meet the delay time and skew specifications for 1000Mbps
Ethernet.

This fix should go in as soon as possible.

Basic build, boot, and PM test results are available here:

http://www.pwsan.com/omap/testlogs/omap-critical-fixes-for-v4.5-rc/20160307014209/

* tag 'for-v4.5-rc/omap-critical-fixes-a' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending:
  ARM: dts: dra7: do not gate cpsw clock due to errata i877
  ARM: OMAP2+: hwmod: Introduce ti,no-idle dt property
Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents f3c87e99 0f514e69
...@@ -23,6 +23,7 @@ Optional properties: ...@@ -23,6 +23,7 @@ Optional properties:
during suspend. during suspend.
- ti,no-reset-on-init: When present, the module should not be reset at init - ti,no-reset-on-init: When present, the module should not be reset at init
- ti,no-idle-on-init: When present, the module should not be idled at init - ti,no-idle-on-init: When present, the module should not be idled at init
- ti,no-idle: When present, the module is never allowed to idle.
Example: Example:
......
...@@ -1500,6 +1500,16 @@ mac: ethernet@48484000 { ...@@ -1500,6 +1500,16 @@ mac: ethernet@48484000 {
0x48485200 0x2E00>; 0x48485200 0x2E00>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
/*
* Do not allow gating of cpsw clock as workaround
* for errata i877. Keeping internal clock disabled
* causes the device switching characteristics
* to degrade over time and eventually fail to meet
* the data manual delay time/skew specs.
*/
ti,no-idle;
/* /*
* rx_thresh_pend * rx_thresh_pend
* rx_pend * rx_pend
......
...@@ -2200,6 +2200,11 @@ static int _enable(struct omap_hwmod *oh) ...@@ -2200,6 +2200,11 @@ static int _enable(struct omap_hwmod *oh)
*/ */
static int _idle(struct omap_hwmod *oh) static int _idle(struct omap_hwmod *oh)
{ {
if (oh->flags & HWMOD_NO_IDLE) {
oh->_int_flags |= _HWMOD_SKIP_ENABLE;
return 0;
}
pr_debug("omap_hwmod: %s: idling\n", oh->name); pr_debug("omap_hwmod: %s: idling\n", oh->name);
if (oh->_state != _HWMOD_STATE_ENABLED) { if (oh->_state != _HWMOD_STATE_ENABLED) {
...@@ -2504,6 +2509,8 @@ static int __init _init(struct omap_hwmod *oh, void *data) ...@@ -2504,6 +2509,8 @@ static int __init _init(struct omap_hwmod *oh, void *data)
oh->flags |= HWMOD_INIT_NO_RESET; oh->flags |= HWMOD_INIT_NO_RESET;
if (of_find_property(np, "ti,no-idle-on-init", NULL)) if (of_find_property(np, "ti,no-idle-on-init", NULL))
oh->flags |= HWMOD_INIT_NO_IDLE; oh->flags |= HWMOD_INIT_NO_IDLE;
if (of_find_property(np, "ti,no-idle", NULL))
oh->flags |= HWMOD_NO_IDLE;
} }
oh->_state = _HWMOD_STATE_INITIALIZED; oh->_state = _HWMOD_STATE_INITIALIZED;
...@@ -2630,7 +2637,7 @@ static void __init _setup_postsetup(struct omap_hwmod *oh) ...@@ -2630,7 +2637,7 @@ static void __init _setup_postsetup(struct omap_hwmod *oh)
* XXX HWMOD_INIT_NO_IDLE does not belong in hwmod data - * XXX HWMOD_INIT_NO_IDLE does not belong in hwmod data -
* it should be set by the core code as a runtime flag during startup * it should be set by the core code as a runtime flag during startup
*/ */
if ((oh->flags & HWMOD_INIT_NO_IDLE) && if ((oh->flags & (HWMOD_INIT_NO_IDLE | HWMOD_NO_IDLE)) &&
(postsetup_state == _HWMOD_STATE_IDLE)) { (postsetup_state == _HWMOD_STATE_IDLE)) {
oh->_int_flags |= _HWMOD_SKIP_ENABLE; oh->_int_flags |= _HWMOD_SKIP_ENABLE;
postsetup_state = _HWMOD_STATE_ENABLED; postsetup_state = _HWMOD_STATE_ENABLED;
......
...@@ -525,6 +525,8 @@ struct omap_hwmod_omap4_prcm { ...@@ -525,6 +525,8 @@ struct omap_hwmod_omap4_prcm {
* or idled. * or idled.
* HWMOD_OPT_CLKS_NEEDED: The optional clocks are needed for the module to * HWMOD_OPT_CLKS_NEEDED: The optional clocks are needed for the module to
* operate and they need to be handled at the same time as the main_clk. * operate and they need to be handled at the same time as the main_clk.
* HWMOD_NO_IDLE: Do not idle the hwmod at all. Useful to handle certain
* IPs like CPSW on DRA7, where clocks to this module cannot be disabled.
*/ */
#define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_SIDLE (1 << 0)
#define HWMOD_SWSUP_MSTANDBY (1 << 1) #define HWMOD_SWSUP_MSTANDBY (1 << 1)
...@@ -541,6 +543,7 @@ struct omap_hwmod_omap4_prcm { ...@@ -541,6 +543,7 @@ struct omap_hwmod_omap4_prcm {
#define HWMOD_SWSUP_SIDLE_ACT (1 << 12) #define HWMOD_SWSUP_SIDLE_ACT (1 << 12)
#define HWMOD_RECONFIG_IO_CHAIN (1 << 13) #define HWMOD_RECONFIG_IO_CHAIN (1 << 13)
#define HWMOD_OPT_CLKS_NEEDED (1 << 14) #define HWMOD_OPT_CLKS_NEEDED (1 << 14)
#define HWMOD_NO_IDLE (1 << 15)
/* /*
* omap_hwmod._int_flags definitions * omap_hwmod._int_flags definitions
......
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