aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/l2cc.txt10
-rw-r--r--arch/arm/mm/cache-l2x0.c121
2 files changed, 131 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/arm/l2cc.txt b/Documentation/devicetree/bindings/arm/l2cc.txt
index af527ee111c2..292ef7ca3058 100644
--- a/Documentation/devicetree/bindings/arm/l2cc.txt
+++ b/Documentation/devicetree/bindings/arm/l2cc.txt
@@ -2,6 +2,10 @@
2 2
3ARM cores often have a separate level 2 cache controller. There are various 3ARM cores often have a separate level 2 cache controller. There are various
4implementations of the L2 cache controller with compatible programming models. 4implementations of the L2 cache controller with compatible programming models.
5Some of the properties that are just prefixed "cache-*" are taken from section
63.7.3 of the ePAPR v1.1 specification which can be found at:
7https://www.power.org/wp-content/uploads/2012/06/Power_ePAPR_APPROVED_v1.1.pdf
8
5The ARM L2 cache representation in the device tree should be done as follows: 9The ARM L2 cache representation in the device tree should be done as follows:
6 10
7Required properties: 11Required properties:
@@ -44,6 +48,12 @@ Optional properties:
44 I/O coherent mode. Valid only when the arm,pl310-cache compatible 48 I/O coherent mode. Valid only when the arm,pl310-cache compatible
45 string is used. 49 string is used.
46- interrupts : 1 combined interrupt. 50- interrupts : 1 combined interrupt.
51- cache-size : specifies the size in bytes of the cache
52- cache-sets : specifies the number of associativity sets of the cache
53- cache-block-size : specifies the size in bytes of a cache block
54- cache-line-size : specifies the size in bytes of a line in the cache,
55 if this is not specified, the line size is assumed to be equal to the
56 cache block size
47- cache-id-part: cache id part number to be used if it is not present 57- cache-id-part: cache id part number to be used if it is not present
48 on hardware 58 on hardware
49- wt-override: If present then L2 is forced to Write through mode 59- wt-override: If present then L2 is forced to Write through mode
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 5f2c988a06ac..55f9d6e0cc88 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -21,6 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/smp.h> 22#include <linux/smp.h>
23#include <linux/spinlock.h> 23#include <linux/spinlock.h>
24#include <linux/log2.h>
24#include <linux/io.h> 25#include <linux/io.h>
25#include <linux/of.h> 26#include <linux/of.h>
26#include <linux/of_address.h> 27#include <linux/of_address.h>
@@ -945,6 +946,98 @@ static int l2_wt_override;
945 * pass it though the device tree */ 946 * pass it though the device tree */
946static u32 cache_id_part_number_from_dt; 947static u32 cache_id_part_number_from_dt;
947 948
949/**
950 * l2x0_cache_size_of_parse() - read cache size parameters from DT
951 * @np: the device tree node for the l2 cache
952 * @aux_val: pointer to machine-supplied auxilary register value, to
953 * be augmented by the call (bits to be set to 1)
954 * @aux_mask: pointer to machine-supplied auxilary register mask, to
955 * be augmented by the call (bits to be set to 0)
956 * @associativity: variable to return the calculated associativity in
957 * @max_way_size: the maximum size in bytes for the cache ways
958 */
959static void __init l2x0_cache_size_of_parse(const struct device_node *np,
960 u32 *aux_val, u32 *aux_mask,
961 u32 *associativity,
962 u32 max_way_size)
963{
964 u32 mask = 0, val = 0;
965 u32 cache_size = 0, sets = 0;
966 u32 way_size_bits = 1;
967 u32 way_size = 0;
968 u32 block_size = 0;
969 u32 line_size = 0;
970
971 of_property_read_u32(np, "cache-size", &cache_size);
972 of_property_read_u32(np, "cache-sets", &sets);
973 of_property_read_u32(np, "cache-block-size", &block_size);
974 of_property_read_u32(np, "cache-line-size", &line_size);
975
976 if (!cache_size || !sets)
977 return;
978
979 /* All these l2 caches have the same line = block size actually */
980 if (!line_size) {
981 if (block_size) {
982 /* If linesize if not given, it is equal to blocksize */
983 line_size = block_size;
984 } else {
985 /* Fall back to known size */
986 pr_warn("L2C OF: no cache block/line size given: "
987 "falling back to default size %d bytes\n",
988 CACHE_LINE_SIZE);
989 line_size = CACHE_LINE_SIZE;
990 }
991 }
992
993 if (line_size != CACHE_LINE_SIZE)
994 pr_warn("L2C OF: DT supplied line size %d bytes does "
995 "not match hardware line size of %d bytes\n",
996 line_size,
997 CACHE_LINE_SIZE);
998
999 /*
1000 * Since:
1001 * set size = cache size / sets
1002 * ways = cache size / (sets * line size)
1003 * way size = cache size / (cache size / (sets * line size))
1004 * way size = sets * line size
1005 * associativity = ways = cache size / way size
1006 */
1007 way_size = sets * line_size;
1008 *associativity = cache_size / way_size;
1009
1010 if (way_size > max_way_size) {
1011 pr_err("L2C OF: set size %dKB is too large\n", way_size);
1012 return;
1013 }
1014
1015 pr_info("L2C OF: override cache size: %d bytes (%dKB)\n",
1016 cache_size, cache_size >> 10);
1017 pr_info("L2C OF: override line size: %d bytes\n", line_size);
1018 pr_info("L2C OF: override way size: %d bytes (%dKB)\n",
1019 way_size, way_size >> 10);
1020 pr_info("L2C OF: override associativity: %d\n", *associativity);
1021
1022 /*
1023 * Calculates the bits 17:19 to set for way size:
1024 * 512KB -> 6, 256KB -> 5, ... 16KB -> 1
1025 */
1026 way_size_bits = ilog2(way_size >> 10) - 3;
1027 if (way_size_bits < 1 || way_size_bits > 6) {
1028 pr_err("L2C OF: cache way size illegal: %dKB is not mapped\n",
1029 way_size);
1030 return;
1031 }
1032
1033 mask |= L2C_AUX_CTRL_WAY_SIZE_MASK;
1034 val |= (way_size_bits << L2C_AUX_CTRL_WAY_SIZE_SHIFT);
1035
1036 *aux_val &= ~mask;
1037 *aux_val |= val;
1038 *aux_mask &= ~mask;
1039}
1040
948static void __init l2x0_of_parse(const struct device_node *np, 1041static void __init l2x0_of_parse(const struct device_node *np,
949 u32 *aux_val, u32 *aux_mask) 1042 u32 *aux_val, u32 *aux_mask)
950{ 1043{
@@ -952,6 +1045,7 @@ static void __init l2x0_of_parse(const struct device_node *np,
952 u32 tag = 0; 1045 u32 tag = 0;
953 u32 dirty = 0; 1046 u32 dirty = 0;
954 u32 val = 0, mask = 0; 1047 u32 val = 0, mask = 0;
1048 u32 assoc;
955 1049
956 of_property_read_u32(np, "arm,tag-latency", &tag); 1050 of_property_read_u32(np, "arm,tag-latency", &tag);
957 if (tag) { 1051 if (tag) {
@@ -974,6 +1068,15 @@ static void __init l2x0_of_parse(const struct device_node *np,
974 val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT; 1068 val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT;
975 } 1069 }
976 1070
1071 l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_256K);
1072 if (assoc > 8) {
1073 pr_err("l2x0 of: cache setting yield too high associativity\n");
1074 pr_err("l2x0 of: %d calculated, max 8\n", assoc);
1075 } else {
1076 mask |= L2X0_AUX_CTRL_ASSOC_MASK;
1077 val |= (assoc << L2X0_AUX_CTRL_ASSOC_SHIFT);
1078 }
1079
977 *aux_val &= ~mask; 1080 *aux_val &= ~mask;
978 *aux_val |= val; 1081 *aux_val |= val;
979 *aux_mask &= ~mask; 1082 *aux_mask &= ~mask;
@@ -1021,6 +1124,7 @@ static void __init l2c310_of_parse(const struct device_node *np,
1021 u32 data[3] = { 0, 0, 0 }; 1124 u32 data[3] = { 0, 0, 0 };
1022 u32 tag[3] = { 0, 0, 0 }; 1125 u32 tag[3] = { 0, 0, 0 };
1023 u32 filter[2] = { 0, 0 }; 1126 u32 filter[2] = { 0, 0 };
1127 u32 assoc;
1024 1128
1025 of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag)); 1129 of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
1026 if (tag[0] && tag[1] && tag[2]) 1130 if (tag[0] && tag[1] && tag[2])
@@ -1047,6 +1151,23 @@ static void __init l2c310_of_parse(const struct device_node *np,
1047 writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L310_ADDR_FILTER_EN, 1151 writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L310_ADDR_FILTER_EN,
1048 l2x0_base + L310_ADDR_FILTER_START); 1152 l2x0_base + L310_ADDR_FILTER_START);
1049 } 1153 }
1154
1155 l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_512K);
1156 switch (assoc) {
1157 case 16:
1158 *aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK;
1159 *aux_val |= L310_AUX_CTRL_ASSOCIATIVITY_16;
1160 *aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK;
1161 break;
1162 case 8:
1163 *aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK;
1164 *aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK;
1165 break;
1166 default:
1167 pr_err("PL310 OF: cache setting yield illegal associativity\n");
1168 pr_err("PL310 OF: %d calculated, only 8 and 16 legal\n", assoc);
1169 break;
1170 }
1050} 1171}
1051 1172
1052static const struct l2c_init_data of_l2c310_data __initconst = { 1173static const struct l2c_init_data of_l2c310_data __initconst = {