* [PATCH] Retain the write-only OD from being clobbered @ 2005-11-22 20:59 Jordan Crouse 2005-11-22 21:10 ` Sergei Shtylylov 0 siblings, 1 reply; 8+ messages in thread From: Jordan Crouse @ 2005-11-22 20:59 UTC (permalink / raw) To: linux-mips; +Cc: ralf First of several patches forwarded to me by Sergei Shtylyov. Ralf, these should be good to go for the tree. Retain the write-only OD bit from being clobbered by coherency_setup() Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Acked-by: Jordan Crouse <jordan.crouse@amd.com> --- arch/mips/mm/c-r4k.c | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 38223b4..044c468 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -29,6 +29,10 @@ #include <asm/war.h> #include <asm/cacheflush.h> /* for run_uncached() */ +#ifdef CONFIG_SOC_AU1X00 +#include <au1000.h> +#endif + /* * Must die. */ @@ -1203,6 +1207,16 @@ static inline void coherency_setup(void) { change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); +#ifdef CONFIG_SOC_AU1X00 + /* + * c0_config.od (bit 19) is write only (and reads as 0) on many early + * revs of AMD Au1x00 SOCs. It disables the bus transaction overlapping + * and needs to be set to correct the various errata. So if it has been + * set by the board setup code we must leave it set... + */ + if (cur_cpu_spec[0]->cpu_od) + set_c0_config(1 << 19); +#endif /* * c0_status.cu=0 specifies that updates by the sc instruction use * the coherency mode specified by the TLB; 1 means cachable ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] Retain the write-only OD from being clobbered 2005-11-22 20:59 [PATCH] Retain the write-only OD from being clobbered Jordan Crouse @ 2005-11-22 21:10 ` Sergei Shtylylov 2005-12-28 22:25 ` Sergei Shtylylov 2006-03-24 20:33 ` Sergei Shtylyov 0 siblings, 2 replies; 8+ messages in thread From: Sergei Shtylylov @ 2005-11-22 21:10 UTC (permalink / raw) To: linux-mips Hello. Jordan Crouse wrote: > First of several patches forwarded to me by Sergei Shtylyov. Ralf, > these should be good to go for the tree. > > Retain the write-only OD bit from being clobbered by coherency_setup() > > Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> > Acked-by: Jordan Crouse <jordan.crouse@amd.com> A long story of a long standing bug follows... AMD Au1x00 board setup code in au1x00_setup() sets CONFIG.OD bit for the early steppings of the Au1x00 SOCs, consulting the PRID table in arch/mips/au1000/common/cputable.c. This bit disables the bus transaction overlapping which causes a number of errata in those early SOC steppings (including the one that I think we've run into with USB host--at least setting the bit back to 1 fixed it, although disabling USB host DMA coherency also seemd to help). The problem is that this bit is write-only and reads as 0 on almost all SOCs that need it set. So, when the arch/mm/c-r4k.c code does RMW to the CONFIG reg. in coherency_setup(), its value is lost, and the chip again becomes prone to all the nasty errata that it has just been saved from... :-) There's couple more places in the assembly code where the CP0 CONFIG reg. is written without care of OD bit: 1) In the cache parity error handler (arch/mips/mm/cex-gen.S) -- as the panic() call follows shortly, probably CACHE.OD=0 doesn't matter much at this point; 2) In arch/mips/au1000/common/sleeper.S, when the CPU regs are being restored on wakeup; Au1x00 PM code in 2.6 seem to have fallen out of maintenance, and the stack frame set up there seemed just erratic (2.4 situation in this module is much better). I didn't touch both those places. And of course, this CONFIG.OD bug is present in 2.4 kernels as well... WBR, Sergei ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Retain the write-only OD from being clobbered 2005-11-22 21:10 ` Sergei Shtylylov @ 2005-12-28 22:25 ` Sergei Shtylylov 2006-03-24 20:33 ` Sergei Shtylyov 1 sibling, 0 replies; 8+ messages in thread From: Sergei Shtylylov @ 2005-12-28 22:25 UTC (permalink / raw) To: Linux MIPS; +Cc: Manish Lachwani, Jordan Crouse, ralf [-- Attachment #1: Type: text/plain, Size: 2127 bytes --] Hello Sergei Shtylylov wrote: > Jordan Crouse wrote: >> First of several patches forwarded to me by Sergei Shtylyov. Ralf, >> these should be good to go for the tree. >> >> Retain the write-only OD bit from being clobbered by coherency_setup() >> >> Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> >> Acked-by: Jordan Crouse <jordan.crouse@amd.com> > A long story of a long standing bug follows... > AMD Au1x00 board setup code in au1x00_setup() sets CONFIG.OD bit for > the early steppings of the Au1x00 SOCs, consulting the PRID table in > arch/mips/au1000/common/cputable.c. This bit disables the bus > transaction overlapping which causes a number of errata in those early > SOC steppings (including the one that I think we've run into with USB > host--at least setting the bit back to 1 fixed it, although disabling > USB host DMA coherency also seemd to help). The problem is that this bit > is write-only and reads > as 0 on almost all SOCs that need it set. So, when the arch/mm/c-r4k.c code > does RMW to the CONFIG reg. in coherency_setup(), its value is lost, and > the > chip again becomes prone to all the nasty errata that it has just been > saved > from... :-) > There's couple more places in the assembly code where the CP0 > CONFIG reg. is written without care of OD bit: > 1) In the cache parity error handler (arch/mips/mm/cex-gen.S) -- as > the panic() call follows shortly, probably CACHE.OD=0 doesn't matter > much at this point; > 2) In arch/mips/au1000/common/sleeper.S, when the CPU regs are being > restored on wakeup; Au1x00 PM code in 2.6 seem to have fallen out of > maintenance, and the stack frame set up there seemed just erratic (2.4 > situation in this module is much better). > I didn't touch both those places. And of course, this CONFIG.OD bug is > present in 2.4 kernels as well... Posting the reworked patch at last -- this variant doesn't include machine-specific header into arch/mips/c-r4k.c... WBR, Sergei Signed-off-by: Konstantin Baidarov <kbaidarov@ru.mvista.com> Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> [-- Attachment #2: Au1x00-retain-OD-bit.patch --] [-- Type: text/plain, Size: 1588 bytes --] diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c index 08c8c85..e36289b 100644 --- a/arch/mips/au1000/common/setup.c +++ b/arch/mips/au1000/common/setup.c @@ -143,6 +143,17 @@ void __init plat_setup(void) au_writel(0, SYS_TOYTRIM); } +/* + * Fix up write-only Config[OD] bit after a write to that register. Since the + * bit always reads as 0 on those SOC revs that require it to be set to fight + * the various errata, we need to set it back to 1... + */ +void au1x00_fixup_config_od(void) +{ + if (cur_cpu_spec[0]->cpu_od) + set_c0_config(1<<19); +} + #if defined(CONFIG_64BIT_PHYS_ADDR) /* This routine should be valid for all Au1x based boards */ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 422b55f..8447699 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -1201,8 +1201,20 @@ static void __init setup_scache(void) static inline void coherency_setup(void) { + extern void au1x00_fixup_config_od(void); + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); +#ifdef CONFIG_SOC_AU1X00 + /* + * c0_config.od (bit 19) is write only (and reads as 0) on many early + * revs of AMD Au1x00 SOCs. It disables the bus transaction overlapping + * and needs to be set to correct the various errata. So if it has been + * set by the board setup code we must leave it set... + */ + au1x00_fixup_config_od(); +#endif + /* * c0_status.cu=0 specifies that updates by the sc instruction use * the coherency mode specified by the TLB; 1 means cachable ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] Retain the write-only OD from being clobbered 2005-11-22 21:10 ` Sergei Shtylylov 2005-12-28 22:25 ` Sergei Shtylylov @ 2006-03-24 20:33 ` Sergei Shtylyov 2006-05-26 3:43 ` [PATCH] Save write-only Config.OD " Sergei Shtylyov 1 sibling, 1 reply; 8+ messages in thread From: Sergei Shtylyov @ 2006-03-24 20:33 UTC (permalink / raw) To: Linux MIPS; +Cc: Jordan Crouse, ralf [-- Attachment #1: Type: text/plain, Size: 338 bytes --] Hello. Retain the write-only OD bit from being clobbered by coherency_setup(). WBR, Sergei PS: Looks like this patch is stuck uncommitted since December, while it's a serious issue causing the kernel lockups. Signed-off-by: Konstantin Baidarov <kbaidarov@ru.mvista.com> Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> [-- Attachment #2: Au1x00-retain-OD-bit.patch --] [-- Type: text/plain, Size: 1590 bytes --] diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c index 08c8c85..e36289b 100644 --- a/arch/mips/au1000/common/setup.c +++ b/arch/mips/au1000/common/setup.c @@ -143,6 +143,17 @@ void __init plat_setup(void) au_writel(0, SYS_TOYTRIM); } +/* + * Fix up write-only Config[OD] bit after a write to that register. Since the + * bit always reads as 0 on those SOC revs that require it to be set to fight + * the various errata, we need to set it back to 1... + */ +void au1x00_fixup_config_od(void) +{ + if (cur_cpu_spec[0]->cpu_od) + set_c0_config(1<<19); +} + #if defined(CONFIG_64BIT_PHYS_ADDR) /* This routine should be valid for all Au1x based boards */ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 422b55f..8447699 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -1201,8 +1201,20 @@ static void __init setup_scache(void) static inline void coherency_setup(void) { + extern void au1x00_fixup_config_od(void); + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); +#ifdef CONFIG_SOC_AU1X00 + /* + * c0_config.od (bit 19) is write only (and reads as 0) on many early + * revs of AMD Au1x00 SOCs. It disables the bus transaction overlapping + * and needs to be set to correct the various errata. So if it has been + * set by the board setup code we must leave it set... + */ + au1x00_fixup_config_od(); +#endif + /* * c0_status.cu=0 specifies that updates by the sc instruction use * the coherency mode specified by the TLB; 1 means cachable ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] Save write-only Config.OD from being clobbered 2006-03-24 20:33 ` Sergei Shtylyov @ 2006-05-26 3:43 ` Sergei Shtylyov 2006-05-26 15:44 ` [PATCH] Save write-only Config.OD from being clobbered (take 4) Sergei Shtylyov 0 siblings, 1 reply; 8+ messages in thread From: Sergei Shtylyov @ 2006-05-26 3:43 UTC (permalink / raw) To: Linux MIPS; +Cc: Jordan Crouse, ralf [-- Attachment #1: Type: text/plain, Size: 356 bytes --] Hello. Save the Config.OD bit from being clobbered by coherency_setup(). This bit, when set, fixes various errata in the early steppings of Au1x00 SOCs. Unfortunately, the bit was write-only on the most early of them. In addition, also restore the bit after a wakeup from sleep. WBR, Sergei Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> [-- Attachment #2: Au1x00-retain-OD-bit.patch --] [-- Type: text/plain, Size: 1779 bytes --] Index: linux-mips/arch/mips/au1000/common/sleeper.S =================================================================== --- linux-mips.orig/arch/mips/au1000/common/sleeper.S +++ linux-mips/arch/mips/au1000/common/sleeper.S @@ -112,6 +112,11 @@ sdsleep: mtc0 k0, CP0_PAGEMASK lw k0, 0x14(sp) mtc0 k0, CP0_CONFIG + + /* We need to catch the ealry Alchemy SOCs with + * the write-only Config[OD] bit and set it back to one... + */ + jal au1x00_fixup_config_od lw $1, PT_R1(sp) lw $2, PT_R2(sp) lw $3, PT_R3(sp) Index: linux-mips/arch/mips/mm/c-r4k.c =================================================================== --- linux-mips.orig/arch/mips/mm/c-r4k.c +++ linux-mips/arch/mips/mm/c-r4k.c @@ -1136,6 +1136,26 @@ static void __init setup_scache(void) c->options |= MIPS_CPU_SUBSET_CACHES; } +void au1x00_fixup_config_od(void) +{ + /* + * c0_config.od (bit 19) was write only (and read as 0) + * on the early revisions of Alchemy SOCs. It disables the bus + * transaction overlapping and needs to be set to fix various errata. + */ + switch (current_cpu_data.cputype) { + case CPU_AU1000: /* rev. DA, HA, HB */ + case CPU_AU1100: /* rev. AB, BA, BC ?? */ + if ((read_c0_prid() & 0xff) < 3) + set_c0_config(1 << 19); + break; + case CPU_AU1500: /* rev. AB */ + if ((read_c0_prid() & 0xff) < 1) + set_c0_config(1 << 19); + break; + } +} + static inline void coherency_setup(void) { change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); @@ -1156,6 +1176,13 @@ static inline void coherency_setup(void) case CPU_R4400MC: clear_c0_config(CONF_CU); break; + default: + /* + * We need to catch the ealry Alchemy SOCs with + * the write-only co_config.od bit and set it back to one... + */ + au1x00_fixup_config_od(); + break; } } ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] Save write-only Config.OD from being clobbered (take 4) 2006-05-26 3:43 ` [PATCH] Save write-only Config.OD " Sergei Shtylyov @ 2006-05-26 15:44 ` Sergei Shtylyov 2006-05-26 15:55 ` Martin Michlmayr 0 siblings, 1 reply; 8+ messages in thread From: Sergei Shtylyov @ 2006-05-26 15:44 UTC (permalink / raw) To: Linux MIPS; +Cc: Jordan Crouse, ralf [-- Attachment #1: Type: text/plain, Size: 348 bytes --] Save the Config.OD bit from being clobbered by coherency_setup(). This bit, when set, fixes various errata in the early steppings of Au1x00 SOCs. Unfortunately, the bit was write-only on the most early of them. In addition, also restore the bit after a wakeup from sleep. WBR, Sergei Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> [-- Attachment #2: Au1x00-retain-OD-bit.patch --] [-- Type: text/plain, Size: 2086 bytes --] Index: linux-mips/arch/mips/au1000/common/sleeper.S =================================================================== --- linux-mips.orig/arch/mips/au1000/common/sleeper.S +++ linux-mips/arch/mips/au1000/common/sleeper.S @@ -112,6 +112,11 @@ sdsleep: mtc0 k0, CP0_PAGEMASK lw k0, 0x14(sp) mtc0 k0, CP0_CONFIG + + /* We need to catch the ealry Alchemy SOCs with + * the write-only Config[OD] bit and set it back to one... + */ + jal au1x00_fixup_config_od lw $1, PT_R1(sp) lw $2, PT_R2(sp) lw $3, PT_R3(sp) Index: linux-mips/arch/mips/mm/c-r4k.c =================================================================== --- linux-mips.orig/arch/mips/mm/c-r4k.c +++ linux-mips/arch/mips/mm/c-r4k.c @@ -1136,6 +1136,31 @@ static void __init setup_scache(void) c->options |= MIPS_CPU_SUBSET_CACHES; } +void au1x00_fixup_config_od(void) +{ + /* + * c0_config.od (bit 19) was write only (and read as 0) + * on the early revisions of Alchemy SOCs. It disables the bus + * transaction overlapping and needs to be set to fix various errata. + */ + switch (read_c0_prid()) { + case 0x00030100: /* Au1000 DA */ + case 0x00030201: /* Au1000 HA */ + case 0x00030202: /* Au1000 HB */ + case 0x01030200: /* Au1500 AB */ + /* + * Au1100 errata actually keeps silence about this bit, so we set it + * just in case for those revisions that require it to be set according + * to arch/mips/au1000/common/cputable.c + */ + case 0x02030200: /* Au1100 AB */ + case 0x02030201: /* Au1100 BA */ + case 0x02030202: /* Au1100 BC */ + set_c0_config(1 << 19); + break; + } +} + static inline void coherency_setup(void) { change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); @@ -1156,6 +1181,15 @@ static inline void coherency_setup(void) case CPU_R4400MC: clear_c0_config(CONF_CU); break; + /* + * We need to catch the ealry Alchemy SOCs with + * the write-only co_config.od bit and set it back to one... + */ + case CPU_AU1000: /* rev. DA, HA, HB */ + case CPU_AU1100: /* rev. AB, BA, BC ?? */ + case CPU_AU1500: /* rev. AB */ + au1x00_fixup_config_od(); + break; } } ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Save write-only Config.OD from being clobbered (take 4) 2006-05-26 15:44 ` [PATCH] Save write-only Config.OD from being clobbered (take 4) Sergei Shtylyov @ 2006-05-26 15:55 ` Martin Michlmayr 2006-05-26 16:02 ` Sergei Shtylyov 0 siblings, 1 reply; 8+ messages in thread From: Martin Michlmayr @ 2006-05-26 15:55 UTC (permalink / raw) To: Sergei Shtylyov; +Cc: Linux MIPS, Jordan Crouse, ralf * Sergei Shtylyov <sshtylyov@ru.mvista.com> [2006-05-26 19:44]: > + /* We need to catch the ealry Alchemy SOCs with ^^^^^ typo > + * We need to catch the ealry Alchemy SOCs with likewise. -- Martin Michlmayr http://www.cyrius.com/ ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Save write-only Config.OD from being clobbered (take 4) 2006-05-26 15:55 ` Martin Michlmayr @ 2006-05-26 16:02 ` Sergei Shtylyov 0 siblings, 0 replies; 8+ messages in thread From: Sergei Shtylyov @ 2006-05-26 16:02 UTC (permalink / raw) To: Martin Michlmayr; +Cc: Linux MIPS Hello. Martin Michlmayr wrote: > * Sergei Shtylyov <sshtylyov@ru.mvista.com> [2006-05-26 19:44]: >>+ /* We need to catch the ealry Alchemy SOCs with ^^^^^ > typo >>+ * We need to catch the ealry Alchemy SOCs with > likewise. Too late, after 6 or so months, it's in. :-) WBR, Sergei ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2006-05-26 16:03 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-11-22 20:59 [PATCH] Retain the write-only OD from being clobbered Jordan Crouse 2005-11-22 21:10 ` Sergei Shtylylov 2005-12-28 22:25 ` Sergei Shtylylov 2006-03-24 20:33 ` Sergei Shtylyov 2006-05-26 3:43 ` [PATCH] Save write-only Config.OD " Sergei Shtylyov 2006-05-26 15:44 ` [PATCH] Save write-only Config.OD from being clobbered (take 4) Sergei Shtylyov 2006-05-26 15:55 ` Martin Michlmayr 2006-05-26 16:02 ` Sergei Shtylyov
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.