diff options
Diffstat (limited to 'arch/mips/kernel/cpu-probe.c')
-rw-r--r-- | arch/mips/kernel/cpu-probe.c | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index a88d44247cc8..dd3175442c9e 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -352,7 +352,12 @@ __setup("nohtw", htw_disable); | |||
352 | static int mips_ftlb_disabled; | 352 | static int mips_ftlb_disabled; |
353 | static int mips_has_ftlb_configured; | 353 | static int mips_has_ftlb_configured; |
354 | 354 | ||
355 | static int set_ftlb_enable(struct cpuinfo_mips *c, int enable); | 355 | enum ftlb_flags { |
356 | FTLB_EN = 1 << 0, | ||
357 | FTLB_SET_PROB = 1 << 1, | ||
358 | }; | ||
359 | |||
360 | static int set_ftlb_enable(struct cpuinfo_mips *c, enum ftlb_flags flags); | ||
356 | 361 | ||
357 | static int __init ftlb_disable(char *s) | 362 | static int __init ftlb_disable(char *s) |
358 | { | 363 | { |
@@ -371,8 +376,6 @@ static int __init ftlb_disable(char *s) | |||
371 | return 1; | 376 | return 1; |
372 | } | 377 | } |
373 | 378 | ||
374 | back_to_back_c0_hazard(); | ||
375 | |||
376 | config4 = read_c0_config4(); | 379 | config4 = read_c0_config4(); |
377 | 380 | ||
378 | /* Check that FTLB has been disabled */ | 381 | /* Check that FTLB has been disabled */ |
@@ -531,7 +534,7 @@ static unsigned int calculate_ftlb_probability(struct cpuinfo_mips *c) | |||
531 | return 3; | 534 | return 3; |
532 | } | 535 | } |
533 | 536 | ||
534 | static int set_ftlb_enable(struct cpuinfo_mips *c, int enable) | 537 | static int set_ftlb_enable(struct cpuinfo_mips *c, enum ftlb_flags flags) |
535 | { | 538 | { |
536 | unsigned int config; | 539 | unsigned int config; |
537 | 540 | ||
@@ -542,33 +545,33 @@ static int set_ftlb_enable(struct cpuinfo_mips *c, int enable) | |||
542 | case CPU_P6600: | 545 | case CPU_P6600: |
543 | /* proAptiv & related cores use Config6 to enable the FTLB */ | 546 | /* proAptiv & related cores use Config6 to enable the FTLB */ |
544 | config = read_c0_config6(); | 547 | config = read_c0_config6(); |
545 | /* Clear the old probability value */ | 548 | |
546 | config &= ~(3 << MIPS_CONF6_FTLBP_SHIFT); | 549 | if (flags & FTLB_EN) |
547 | if (enable) | 550 | 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 | 551 | else |
554 | /* Disable FTLB */ | 552 | config &= ~MIPS_CONF6_FTLBEN; |
555 | write_c0_config6(config & ~MIPS_CONF6_FTLBEN); | 553 | |
554 | if (flags & FTLB_SET_PROB) { | ||
555 | config &= ~(3 << MIPS_CONF6_FTLBP_SHIFT); | ||
556 | config |= calculate_ftlb_probability(c) | ||
557 | << MIPS_CONF6_FTLBP_SHIFT; | ||
558 | } | ||
559 | |||
560 | write_c0_config6(config); | ||
561 | back_to_back_c0_hazard(); | ||
556 | break; | 562 | break; |
557 | case CPU_I6400: | 563 | case CPU_I6400: |
558 | /* I6400 & related cores use Config7 to configure FTLB */ | 564 | /* There's no way to disable the FTLB */ |
559 | config = read_c0_config7(); | 565 | if (!(flags & FTLB_EN)) |
560 | /* Clear the old probability value */ | 566 | return 1; |
561 | config &= ~(3 << MIPS_CONF7_FTLBP_SHIFT); | 567 | return 0; |
562 | write_c0_config7(config | (calculate_ftlb_probability(c) | ||
563 | << MIPS_CONF7_FTLBP_SHIFT)); | ||
564 | break; | ||
565 | case CPU_LOONGSON3: | 568 | case CPU_LOONGSON3: |
566 | /* Flush ITLB, DTLB, VTLB and FTLB */ | 569 | /* Flush ITLB, DTLB, VTLB and FTLB */ |
567 | write_c0_diag(LOONGSON_DIAG_ITLB | LOONGSON_DIAG_DTLB | | 570 | write_c0_diag(LOONGSON_DIAG_ITLB | LOONGSON_DIAG_DTLB | |
568 | LOONGSON_DIAG_VTLB | LOONGSON_DIAG_FTLB); | 571 | LOONGSON_DIAG_VTLB | LOONGSON_DIAG_FTLB); |
569 | /* Loongson-3 cores use Config6 to enable the FTLB */ | 572 | /* Loongson-3 cores use Config6 to enable the FTLB */ |
570 | config = read_c0_config6(); | 573 | config = read_c0_config6(); |
571 | if (enable) | 574 | if (flags & FTLB_EN) |
572 | /* Enable FTLB */ | 575 | /* Enable FTLB */ |
573 | write_c0_config6(config & ~MIPS_CONF6_FTLBDIS); | 576 | write_c0_config6(config & ~MIPS_CONF6_FTLBDIS); |
574 | else | 577 | else |
@@ -788,6 +791,7 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c) | |||
788 | PAGE_SIZE, config4); | 791 | PAGE_SIZE, config4); |
789 | /* Switch FTLB off */ | 792 | /* Switch FTLB off */ |
790 | set_ftlb_enable(c, 0); | 793 | set_ftlb_enable(c, 0); |
794 | mips_ftlb_disabled = 1; | ||
791 | break; | 795 | break; |
792 | } | 796 | } |
793 | c->tlbsizeftlbsets = 1 << | 797 | c->tlbsizeftlbsets = 1 << |
@@ -852,7 +856,7 @@ static void decode_configs(struct cpuinfo_mips *c) | |||
852 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; | 856 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; |
853 | 857 | ||
854 | /* Enable FTLB if present and not disabled */ | 858 | /* Enable FTLB if present and not disabled */ |
855 | set_ftlb_enable(c, !mips_ftlb_disabled); | 859 | set_ftlb_enable(c, mips_ftlb_disabled ? 0 : FTLB_EN); |
856 | 860 | ||
857 | ok = decode_config0(c); /* Read Config registers. */ | 861 | ok = decode_config0(c); /* Read Config registers. */ |
858 | BUG_ON(!ok); /* Arch spec violation! */ | 862 | BUG_ON(!ok); /* Arch spec violation! */ |
@@ -902,6 +906,9 @@ static void decode_configs(struct cpuinfo_mips *c) | |||
902 | } | 906 | } |
903 | } | 907 | } |
904 | 908 | ||
909 | /* configure the FTLB write probability */ | ||
910 | set_ftlb_enable(c, (mips_ftlb_disabled ? 0 : FTLB_EN) | FTLB_SET_PROB); | ||
911 | |||
905 | mips_probe_watch_registers(c); | 912 | mips_probe_watch_registers(c); |
906 | 913 | ||
907 | #ifndef CONFIG_MIPS_CPS | 914 | #ifndef CONFIG_MIPS_CPS |