aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/cache-l2x0.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2014-09-26 04:01:58 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2014-10-02 16:26:37 -0400
commitf3354ab67476dc800463df32e33423158003d80b (patch)
treebd26897e55ccd61423d900d9f150222639b694d0 /arch/arm/mm/cache-l2x0.c
parentfe82dcec644244676d55a1384c958d5f67979adb (diff)
ARM: 8169/1: l2c: parse cache properties from ePAPR definitions
When both 'cache-size' and 'cache-sets' are specified for a L2 cache controller node, parse those properties and set up the set size based on which type of L2 cache controller we are using. Update the L2 cache controller Device Tree binding with the optional 'cache-size', 'cache-sets', 'cache-block-size' and 'cache-line-size' properties. These come from the ePAPR specification. Using the cache size, number of sets and cache line size we can calculate desired associativity of the L2 cache. This is done by the calculation: set size = cache size / sets ways = set size / line size way size = cache size / ways = sets * line size associativity = cache size / way size Example output from the PB1176 DT that look like this: L2: l2-cache { compatible = "arm,l220-cache"; (...) arm,override-auxreg; cache-size = <131072>; // 128kB cache-sets = <512>; cache-line-size = <32>; }; Ends up like this: L2C OF: override cache size: 131072 bytes (128KB) L2C OF: override line size: 32 bytes L2C OF: override way size: 16384 bytes (16KB) L2C OF: override associativity: 8 L2C: DT/platform modifies aux control register: 0x02020fff -> 0x02030fff L2C-220 cache controller enabled, 8 ways, 128 kB L2C-220: CACHE_ID 0x41000486, AUX_CTRL 0x06030fff Which is consistent with the value earlier hardcoded for the PB1176 platform. This patch is an extended version based on the initial patch by Florian Fainelli. Reviewed-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm/cache-l2x0.c')
-rw-r--r--arch/arm/mm/cache-l2x0.c121
1 files changed, 121 insertions, 0 deletions
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 = {