aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Burton <paul.burton@imgtec.com>2016-08-19 13:18:27 -0400
committerRalf Baechle <ralf@linux-mips.org>2016-09-29 12:59:49 -0400
commitebd0e0f503d0774407a63ebb5ec1a90bb54941f5 (patch)
treed16868a3dd85ee52fa64414f0c6062a29c5e28ec
parent72c70f010dfcc9ea6cc13500602a29e33748452f (diff)
MIPS: Configure FTLB after probing TLB sizes from config4
On some cores (proAptiv, P5600) we make use of the sizes of the TLBs to determine the desired FTLB:VTLB write ratio. However set_ftlb_enable & thus calculate_ftlb_probability is called before decode_config4. This results in us calculating a probability based on zero sizes, and we end up setting FTLBP=3 for a 3:1 FTLB:VTLB write ratio in all cases. This will make abysmal use of the available FTLB resources in the affected cores. Fix this by configuring the FTLB probability after having decoded config4. However we do need to have enabled the FTLB before that point such that fields in config4 actually reflect that an FTLB is present. So set_ftlb_enable is now called twice, with flags indicating that it should configure the write probability only the second time. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Fixes: cf0a8aa0226d ("MIPS: cpu-probe: Set the FTLB probability bit on supported cores") Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14022/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/kernel/cpu-probe.c43
1 files changed, 28 insertions, 15 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index ae290506873b..5069b5b1488f 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -352,7 +352,12 @@ __setup("nohtw", htw_disable);
352static int mips_ftlb_disabled; 352static int mips_ftlb_disabled;
353static int mips_has_ftlb_configured; 353static int mips_has_ftlb_configured;
354 354
355static int set_ftlb_enable(struct cpuinfo_mips *c, int enable); 355enum ftlb_flags {
356 FTLB_EN = 1 << 0,
357 FTLB_SET_PROB = 1 << 1,
358};
359
360static int set_ftlb_enable(struct cpuinfo_mips *c, enum ftlb_flags flags);
356 361
357static int __init ftlb_disable(char *s) 362static int __init ftlb_disable(char *s)
358{ 363{
@@ -531,7 +536,7 @@ static unsigned int calculate_ftlb_probability(struct cpuinfo_mips *c)
531 return 3; 536 return 3;
532} 537}
533 538
534static int set_ftlb_enable(struct cpuinfo_mips *c, int enable) 539static int set_ftlb_enable(struct cpuinfo_mips *c, enum ftlb_flags flags)
535{ 540{
536 unsigned int config; 541 unsigned int config;
537 542
@@ -542,28 +547,32 @@ static int set_ftlb_enable(struct cpuinfo_mips *c, int enable)
542 case CPU_P6600: 547 case CPU_P6600:
543 /* proAptiv & related cores use Config6 to enable the FTLB */ 548 /* proAptiv & related cores use Config6 to enable the FTLB */
544 config = read_c0_config6(); 549 config = read_c0_config6();
545 /* Clear the old probability value */ 550
546 config &= ~(3 << MIPS_CONF6_FTLBP_SHIFT); 551 if (flags & FTLB_EN)
547 if (enable) 552 config |= MIPS_CONF6_FTLBEN;
548 /* Enable FTLB */
549 write_c0_config6(config |
550 (calculate_ftlb_probability(c)
551 << MIPS_CONF6_FTLBP_SHIFT)
552 | MIPS_CONF6_FTLBEN);
553 else 553 else
554 /* Disable FTLB */ 554 config &= ~MIPS_CONF6_FTLBEN;
555 write_c0_config6(config & ~MIPS_CONF6_FTLBEN); 555
556 if (flags & FTLB_SET_PROB) {
557 config &= ~(3 << MIPS_CONF6_FTLBP_SHIFT);
558 config |= calculate_ftlb_probability(c)
559 << MIPS_CONF6_FTLBP_SHIFT;
560 }
561
562 write_c0_config6(config);
556 break; 563 break;
557 case CPU_I6400: 564 case CPU_I6400:
558 /* There's no way to disable the FTLB */ 565 /* There's no way to disable the FTLB */
559 return !enable; 566 if (!(flags & FTLB_EN))
567 return 1;
568 return 0;
560 case CPU_LOONGSON3: 569 case CPU_LOONGSON3:
561 /* Flush ITLB, DTLB, VTLB and FTLB */ 570 /* Flush ITLB, DTLB, VTLB and FTLB */
562 write_c0_diag(LOONGSON_DIAG_ITLB | LOONGSON_DIAG_DTLB | 571 write_c0_diag(LOONGSON_DIAG_ITLB | LOONGSON_DIAG_DTLB |
563 LOONGSON_DIAG_VTLB | LOONGSON_DIAG_FTLB); 572 LOONGSON_DIAG_VTLB | LOONGSON_DIAG_FTLB);
564 /* Loongson-3 cores use Config6 to enable the FTLB */ 573 /* Loongson-3 cores use Config6 to enable the FTLB */
565 config = read_c0_config6(); 574 config = read_c0_config6();
566 if (enable) 575 if (flags & FTLB_EN)
567 /* Enable FTLB */ 576 /* Enable FTLB */
568 write_c0_config6(config & ~MIPS_CONF6_FTLBDIS); 577 write_c0_config6(config & ~MIPS_CONF6_FTLBDIS);
569 else 578 else
@@ -783,6 +792,7 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
783 PAGE_SIZE, config4); 792 PAGE_SIZE, config4);
784 /* Switch FTLB off */ 793 /* Switch FTLB off */
785 set_ftlb_enable(c, 0); 794 set_ftlb_enable(c, 0);
795 mips_ftlb_disabled = 1;
786 break; 796 break;
787 } 797 }
788 c->tlbsizeftlbsets = 1 << 798 c->tlbsizeftlbsets = 1 <<
@@ -847,7 +857,7 @@ static void decode_configs(struct cpuinfo_mips *c)
847 c->scache.flags = MIPS_CACHE_NOT_PRESENT; 857 c->scache.flags = MIPS_CACHE_NOT_PRESENT;
848 858
849 /* Enable FTLB if present and not disabled */ 859 /* Enable FTLB if present and not disabled */
850 set_ftlb_enable(c, !mips_ftlb_disabled); 860 set_ftlb_enable(c, mips_ftlb_disabled ? 0 : FTLB_EN);
851 861
852 ok = decode_config0(c); /* Read Config registers. */ 862 ok = decode_config0(c); /* Read Config registers. */
853 BUG_ON(!ok); /* Arch spec violation! */ 863 BUG_ON(!ok); /* Arch spec violation! */
@@ -897,6 +907,9 @@ static void decode_configs(struct cpuinfo_mips *c)
897 } 907 }
898 } 908 }
899 909
910 /* configure the FTLB write probability */
911 set_ftlb_enable(c, (mips_ftlb_disabled ? 0 : FTLB_EN) | FTLB_SET_PROB);
912
900 mips_probe_watch_registers(c); 913 mips_probe_watch_registers(c);
901 914
902#ifndef CONFIG_MIPS_CPS 915#ifndef CONFIG_MIPS_CPS