diff options
Diffstat (limited to 'arch/arm/mm/cache-l2x0.c')
-rw-r--r-- | arch/arm/mm/cache-l2x0.c | 112 |
1 files changed, 101 insertions, 11 deletions
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 5f381af1a7a4..a544f19c448f 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c | |||
@@ -32,6 +32,7 @@ struct l2c_init_data { | |||
32 | unsigned num_lock; | 32 | unsigned num_lock; |
33 | void (*of_parse)(const struct device_node *, u32 *, u32 *); | 33 | void (*of_parse)(const struct device_node *, u32 *, u32 *); |
34 | void (*enable)(void __iomem *, u32, unsigned); | 34 | void (*enable)(void __iomem *, u32, unsigned); |
35 | void (*fixup)(void __iomem *, u32, struct outer_cache_fns *); | ||
35 | void (*save)(void __iomem *); | 36 | void (*save)(void __iomem *); |
36 | struct outer_cache_fns outer_cache; | 37 | struct outer_cache_fns outer_cache; |
37 | }; | 38 | }; |
@@ -394,9 +395,80 @@ static const struct l2c_init_data l2x0_init_fns __initconst = { | |||
394 | }, | 395 | }, |
395 | }; | 396 | }; |
396 | 397 | ||
398 | /* | ||
399 | * L2C-310 specific code. | ||
400 | * | ||
401 | * Errata: | ||
402 | * 588369: PL310 R0P0->R1P0, fixed R2P0. | ||
403 | * Affects: all clean+invalidate operations | ||
404 | * clean and invalidate skips the invalidate step, so we need to issue | ||
405 | * separate operations. We also require the above debug workaround | ||
406 | * enclosing this code fragment on affected parts. On unaffected parts, | ||
407 | * we must not use this workaround without the debug register writes | ||
408 | * to avoid exposing a problem similar to 727915. | ||
409 | * | ||
410 | * 727915: PL310 R2P0->R3P0, fixed R3P1. | ||
411 | * Affects: clean+invalidate by way | ||
412 | * clean and invalidate by way runs in the background, and a store can | ||
413 | * hit the line between the clean operation and invalidate operation, | ||
414 | * resulting in the store being lost. | ||
415 | * | ||
416 | * 753970: PL310 R3P0, fixed R3P1. | ||
417 | * Affects: sync | ||
418 | * prevents merging writes after the sync operation, until another L2C | ||
419 | * operation is performed (or a number of other conditions.) | ||
420 | * | ||
421 | * 769419: PL310 R0P0->R3P1, fixed R3P2. | ||
422 | * Affects: store buffer | ||
423 | * store buffer is not automatically drained. | ||
424 | */ | ||
425 | static void __init l2c310_fixup(void __iomem *base, u32 cache_id, | ||
426 | struct outer_cache_fns *fns) | ||
427 | { | ||
428 | unsigned revision = cache_id & L2X0_CACHE_ID_RTL_MASK; | ||
429 | const char *errata[4]; | ||
430 | unsigned n = 0; | ||
431 | |||
432 | if (revision <= L310_CACHE_ID_RTL_R3P0) | ||
433 | fns->set_debug = pl310_set_debug; | ||
434 | |||
435 | if (IS_ENABLED(CONFIG_PL310_ERRATA_753970) && | ||
436 | revision == L310_CACHE_ID_RTL_R3P0) { | ||
437 | sync_reg_offset = L2X0_DUMMY_REG; | ||
438 | errata[n++] = "753970"; | ||
439 | } | ||
440 | |||
441 | if (IS_ENABLED(CONFIG_PL310_ERRATA_769419)) | ||
442 | errata[n++] = "769419"; | ||
443 | |||
444 | if (n) { | ||
445 | unsigned i; | ||
446 | |||
447 | pr_info("L2C-310 errat%s", n > 1 ? "a" : "um"); | ||
448 | for (i = 0; i < n; i++) | ||
449 | pr_cont(" %s", errata[i]); | ||
450 | pr_cont(" enabled\n"); | ||
451 | } | ||
452 | } | ||
453 | |||
454 | static const struct l2c_init_data l2c310_init_fns __initconst = { | ||
455 | .num_lock = 8, | ||
456 | .enable = l2c_enable, | ||
457 | .fixup = l2c310_fixup, | ||
458 | .outer_cache = { | ||
459 | .inv_range = l2x0_inv_range, | ||
460 | .clean_range = l2x0_clean_range, | ||
461 | .flush_range = l2x0_flush_range, | ||
462 | .flush_all = l2x0_flush_all, | ||
463 | .disable = l2x0_disable, | ||
464 | .sync = l2x0_cache_sync, | ||
465 | }, | ||
466 | }; | ||
467 | |||
397 | static void __init __l2c_init(const struct l2c_init_data *data, | 468 | static void __init __l2c_init(const struct l2c_init_data *data, |
398 | u32 aux_val, u32 aux_mask, u32 cache_id) | 469 | u32 aux_val, u32 aux_mask, u32 cache_id) |
399 | { | 470 | { |
471 | struct outer_cache_fns fns; | ||
400 | u32 aux; | 472 | u32 aux; |
401 | u32 way_size = 0; | 473 | u32 way_size = 0; |
402 | int ways; | 474 | int ways; |
@@ -423,23 +495,20 @@ static void __init __l2c_init(const struct l2c_init_data *data, | |||
423 | else | 495 | else |
424 | ways = 8; | 496 | ways = 8; |
425 | type = "L310"; | 497 | type = "L310"; |
426 | #ifdef CONFIG_PL310_ERRATA_753970 | ||
427 | /* Unmapped register. */ | ||
428 | sync_reg_offset = L2X0_DUMMY_REG; | ||
429 | #endif | ||
430 | break; | 498 | break; |
499 | |||
431 | case L2X0_CACHE_ID_PART_L210: | 500 | case L2X0_CACHE_ID_PART_L210: |
432 | ways = (aux >> 13) & 0xf; | 501 | ways = (aux >> 13) & 0xf; |
433 | type = "L210"; | 502 | type = "L210"; |
434 | break; | 503 | break; |
435 | 504 | ||
436 | case AURORA_CACHE_ID: | 505 | case AURORA_CACHE_ID: |
437 | sync_reg_offset = AURORA_SYNC_REG; | ||
438 | ways = (aux >> 13) & 0xf; | 506 | ways = (aux >> 13) & 0xf; |
439 | ways = 2 << ((ways + 1) >> 2); | 507 | ways = 2 << ((ways + 1) >> 2); |
440 | way_size_shift = AURORA_WAY_SIZE_SHIFT; | 508 | way_size_shift = AURORA_WAY_SIZE_SHIFT; |
441 | type = "Aurora"; | 509 | type = "Aurora"; |
442 | break; | 510 | break; |
511 | |||
443 | default: | 512 | default: |
444 | /* Assume unknown chips have 8 ways */ | 513 | /* Assume unknown chips have 8 ways */ |
445 | ways = 8; | 514 | ways = 8; |
@@ -457,6 +526,10 @@ static void __init __l2c_init(const struct l2c_init_data *data, | |||
457 | 526 | ||
458 | l2x0_size = ways * way_size * SZ_1K; | 527 | l2x0_size = ways * way_size * SZ_1K; |
459 | 528 | ||
529 | fns = data->outer_cache; | ||
530 | if (data->fixup) | ||
531 | data->fixup(l2x0_base, cache_id, &fns); | ||
532 | |||
460 | /* | 533 | /* |
461 | * Check if l2x0 controller is already enabled. If we are booting | 534 | * Check if l2x0 controller is already enabled. If we are booting |
462 | * in non-secure mode accessing the below registers will fault. | 535 | * in non-secure mode accessing the below registers will fault. |
@@ -470,11 +543,7 @@ static void __init __l2c_init(const struct l2c_init_data *data, | |||
470 | /* Save the value for resuming. */ | 543 | /* Save the value for resuming. */ |
471 | l2x0_saved_regs.aux_ctrl = aux; | 544 | l2x0_saved_regs.aux_ctrl = aux; |
472 | 545 | ||
473 | outer_cache = data->outer_cache; | 546 | outer_cache = fns; |
474 | |||
475 | if ((cache_id & L2X0_CACHE_ID_PART_MASK) == L2X0_CACHE_ID_PART_L310 && | ||
476 | (cache_id & L2X0_CACHE_ID_RTL_MASK) <= L310_CACHE_ID_RTL_R3P0) | ||
477 | outer_cache.set_debug = pl310_set_debug; | ||
478 | 547 | ||
479 | pr_info("%s cache controller enabled\n", type); | 548 | pr_info("%s cache controller enabled\n", type); |
480 | pr_info("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d kB\n", | 549 | pr_info("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d kB\n", |
@@ -483,13 +552,24 @@ static void __init __l2c_init(const struct l2c_init_data *data, | |||
483 | 552 | ||
484 | void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) | 553 | void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) |
485 | { | 554 | { |
555 | const struct l2c_init_data *data; | ||
486 | u32 cache_id; | 556 | u32 cache_id; |
487 | 557 | ||
488 | l2x0_base = base; | 558 | l2x0_base = base; |
489 | 559 | ||
490 | cache_id = readl_relaxed(base + L2X0_CACHE_ID); | 560 | cache_id = readl_relaxed(base + L2X0_CACHE_ID); |
491 | 561 | ||
492 | __l2c_init(&l2x0_init_fns, aux_val, aux_mask, cache_id); | 562 | switch (cache_id & L2X0_CACHE_ID_PART_MASK) { |
563 | default: | ||
564 | data = &l2x0_init_fns; | ||
565 | break; | ||
566 | |||
567 | case L2X0_CACHE_ID_PART_L310: | ||
568 | data = &l2c310_init_fns; | ||
569 | break; | ||
570 | } | ||
571 | |||
572 | __l2c_init(data, aux_val, aux_mask, cache_id); | ||
493 | } | 573 | } |
494 | 574 | ||
495 | #ifdef CONFIG_OF | 575 | #ifdef CONFIG_OF |
@@ -659,6 +739,7 @@ static const struct l2c_init_data of_pl310_data __initconst = { | |||
659 | .num_lock = 8, | 739 | .num_lock = 8, |
660 | .of_parse = pl310_of_parse, | 740 | .of_parse = pl310_of_parse, |
661 | .enable = l2c_enable, | 741 | .enable = l2c_enable, |
742 | .fixup = l2c310_fixup, | ||
662 | .save = pl310_save, | 743 | .save = pl310_save, |
663 | .outer_cache = { | 744 | .outer_cache = { |
664 | .inv_range = l2x0_inv_range, | 745 | .inv_range = l2x0_inv_range, |
@@ -802,6 +883,12 @@ static void __init aurora_enable_no_outer(void __iomem *base, u32 aux, | |||
802 | l2c_enable(base, aux, num_lock); | 883 | l2c_enable(base, aux, num_lock); |
803 | } | 884 | } |
804 | 885 | ||
886 | static void __init aurora_fixup(void __iomem *base, u32 cache_id, | ||
887 | struct outer_cache_fns *fns) | ||
888 | { | ||
889 | sync_reg_offset = AURORA_SYNC_REG; | ||
890 | } | ||
891 | |||
805 | static void __init aurora_of_parse(const struct device_node *np, | 892 | static void __init aurora_of_parse(const struct device_node *np, |
806 | u32 *aux_val, u32 *aux_mask) | 893 | u32 *aux_val, u32 *aux_mask) |
807 | { | 894 | { |
@@ -828,6 +915,7 @@ static const struct l2c_init_data of_aurora_with_outer_data __initconst = { | |||
828 | .num_lock = 4, | 915 | .num_lock = 4, |
829 | .of_parse = aurora_of_parse, | 916 | .of_parse = aurora_of_parse, |
830 | .enable = l2c_enable, | 917 | .enable = l2c_enable, |
918 | .fixup = aurora_fixup, | ||
831 | .save = aurora_save, | 919 | .save = aurora_save, |
832 | .outer_cache = { | 920 | .outer_cache = { |
833 | .inv_range = aurora_inv_range, | 921 | .inv_range = aurora_inv_range, |
@@ -844,6 +932,7 @@ static const struct l2c_init_data of_aurora_no_outer_data __initconst = { | |||
844 | .num_lock = 4, | 932 | .num_lock = 4, |
845 | .of_parse = aurora_of_parse, | 933 | .of_parse = aurora_of_parse, |
846 | .enable = aurora_enable_no_outer, | 934 | .enable = aurora_enable_no_outer, |
935 | .fixup = aurora_fixup, | ||
847 | .save = aurora_save, | 936 | .save = aurora_save, |
848 | .outer_cache = { | 937 | .outer_cache = { |
849 | .resume = aurora_resume, | 938 | .resume = aurora_resume, |
@@ -995,6 +1084,7 @@ static const struct l2c_init_data of_bcm_l2x0_data __initconst = { | |||
995 | .num_lock = 8, | 1084 | .num_lock = 8, |
996 | .of_parse = pl310_of_parse, | 1085 | .of_parse = pl310_of_parse, |
997 | .enable = l2c_enable, | 1086 | .enable = l2c_enable, |
1087 | .fixup = l2c310_fixup, | ||
998 | .save = pl310_save, | 1088 | .save = pl310_save, |
999 | .outer_cache = { | 1089 | .outer_cache = { |
1000 | .inv_range = bcm_inv_range, | 1090 | .inv_range = bcm_inv_range, |