intel-ixp4xx-eb.c (11514B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Intel IXP4xx Expansion Bus Controller 4 * Copyright (C) 2021 Linaro Ltd. 5 * 6 * Author: Linus Walleij <linus.walleij@linaro.org> 7 */ 8 9#include <linux/bitfield.h> 10#include <linux/bits.h> 11#include <linux/err.h> 12#include <linux/init.h> 13#include <linux/log2.h> 14#include <linux/mfd/syscon.h> 15#include <linux/module.h> 16#include <linux/of.h> 17#include <linux/of_platform.h> 18#include <linux/platform_device.h> 19#include <linux/regmap.h> 20 21#define IXP4XX_EXP_NUM_CS 8 22 23#define IXP4XX_EXP_TIMING_CS0 0x00 24#define IXP4XX_EXP_TIMING_CS1 0x04 25#define IXP4XX_EXP_TIMING_CS2 0x08 26#define IXP4XX_EXP_TIMING_CS3 0x0c 27#define IXP4XX_EXP_TIMING_CS4 0x10 28#define IXP4XX_EXP_TIMING_CS5 0x14 29#define IXP4XX_EXP_TIMING_CS6 0x18 30#define IXP4XX_EXP_TIMING_CS7 0x1c 31 32/* Bits inside each CS timing register */ 33#define IXP4XX_EXP_TIMING_STRIDE 0x04 34#define IXP4XX_EXP_CS_EN BIT(31) 35#define IXP456_EXP_PAR_EN BIT(30) /* Only on IXP45x and IXP46x */ 36#define IXP4XX_EXP_T1_MASK GENMASK(28, 27) 37#define IXP4XX_EXP_T1_SHIFT 28 38#define IXP4XX_EXP_T2_MASK GENMASK(27, 26) 39#define IXP4XX_EXP_T2_SHIFT 26 40#define IXP4XX_EXP_T3_MASK GENMASK(25, 22) 41#define IXP4XX_EXP_T3_SHIFT 22 42#define IXP4XX_EXP_T4_MASK GENMASK(21, 20) 43#define IXP4XX_EXP_T4_SHIFT 20 44#define IXP4XX_EXP_T5_MASK GENMASK(19, 16) 45#define IXP4XX_EXP_T5_SHIFT 16 46#define IXP4XX_EXP_CYC_TYPE_MASK GENMASK(15, 14) 47#define IXP4XX_EXP_CYC_TYPE_SHIFT 14 48#define IXP4XX_EXP_SIZE_MASK GENMASK(13, 10) 49#define IXP4XX_EXP_SIZE_SHIFT 10 50#define IXP4XX_EXP_CNFG_0 BIT(9) /* Always zero */ 51#define IXP43X_EXP_SYNC_INTEL BIT(8) /* Only on IXP43x */ 52#define IXP43X_EXP_EXP_CHIP BIT(7) /* Only on IXP43x */ 53#define IXP4XX_EXP_BYTE_RD16 BIT(6) 54#define IXP4XX_EXP_HRDY_POL BIT(5) /* Only on IXP42x */ 55#define IXP4XX_EXP_MUX_EN BIT(4) 56#define IXP4XX_EXP_SPLT_EN BIT(3) 57#define IXP4XX_EXP_WORD BIT(2) /* Always zero */ 58#define IXP4XX_EXP_WR_EN BIT(1) 59#define IXP4XX_EXP_BYTE_EN BIT(0) 60#define IXP42X_RESERVED (BIT(30)|IXP4XX_EXP_CNFG_0|BIT(8)|BIT(7)|IXP4XX_EXP_WORD) 61#define IXP43X_RESERVED (BIT(30)|IXP4XX_EXP_CNFG_0|BIT(5)|IXP4XX_EXP_WORD) 62 63#define IXP4XX_EXP_CNFG0 0x20 64#define IXP4XX_EXP_CNFG0_MEM_MAP BIT(31) 65#define IXP4XX_EXP_CNFG1 0x24 66 67#define IXP4XX_EXP_BOOT_BASE 0x00000000 68#define IXP4XX_EXP_NORMAL_BASE 0x50000000 69#define IXP4XX_EXP_STRIDE 0x01000000 70 71/* Fuses on the IXP43x */ 72#define IXP43X_EXP_UNIT_FUSE_RESET 0x28 73#define IXP43x_EXP_FUSE_SPEED_MASK GENMASK(23, 22) 74 75/* Number of device tree values in "reg" */ 76#define IXP4XX_OF_REG_SIZE 3 77 78struct ixp4xx_eb { 79 struct device *dev; 80 struct regmap *rmap; 81 u32 bus_base; 82 bool is_42x; 83 bool is_43x; 84}; 85 86struct ixp4xx_exp_tim_prop { 87 const char *prop; 88 u32 max; 89 u32 mask; 90 u16 shift; 91}; 92 93static const struct ixp4xx_exp_tim_prop ixp4xx_exp_tim_props[] = { 94 { 95 .prop = "intel,ixp4xx-eb-t1", 96 .max = 3, 97 .mask = IXP4XX_EXP_T1_MASK, 98 .shift = IXP4XX_EXP_T1_SHIFT, 99 }, 100 { 101 .prop = "intel,ixp4xx-eb-t2", 102 .max = 3, 103 .mask = IXP4XX_EXP_T2_MASK, 104 .shift = IXP4XX_EXP_T2_SHIFT, 105 }, 106 { 107 .prop = "intel,ixp4xx-eb-t3", 108 .max = 15, 109 .mask = IXP4XX_EXP_T3_MASK, 110 .shift = IXP4XX_EXP_T3_SHIFT, 111 }, 112 { 113 .prop = "intel,ixp4xx-eb-t4", 114 .max = 3, 115 .mask = IXP4XX_EXP_T4_MASK, 116 .shift = IXP4XX_EXP_T4_SHIFT, 117 }, 118 { 119 .prop = "intel,ixp4xx-eb-t5", 120 .max = 15, 121 .mask = IXP4XX_EXP_T5_MASK, 122 .shift = IXP4XX_EXP_T5_SHIFT, 123 }, 124 { 125 .prop = "intel,ixp4xx-eb-byte-access-on-halfword", 126 .max = 1, 127 .mask = IXP4XX_EXP_BYTE_RD16, 128 }, 129 { 130 .prop = "intel,ixp4xx-eb-hpi-hrdy-pol-high", 131 .max = 1, 132 .mask = IXP4XX_EXP_HRDY_POL, 133 }, 134 { 135 .prop = "intel,ixp4xx-eb-mux-address-and-data", 136 .max = 1, 137 .mask = IXP4XX_EXP_MUX_EN, 138 }, 139 { 140 .prop = "intel,ixp4xx-eb-ahb-split-transfers", 141 .max = 1, 142 .mask = IXP4XX_EXP_SPLT_EN, 143 }, 144 { 145 .prop = "intel,ixp4xx-eb-write-enable", 146 .max = 1, 147 .mask = IXP4XX_EXP_WR_EN, 148 }, 149 { 150 .prop = "intel,ixp4xx-eb-byte-access", 151 .max = 1, 152 .mask = IXP4XX_EXP_BYTE_EN, 153 }, 154}; 155 156static void ixp4xx_exp_setup_chipselect(struct ixp4xx_eb *eb, 157 struct device_node *np, 158 u32 cs_index, 159 u32 cs_size) 160{ 161 u32 cs_cfg; 162 u32 val; 163 u32 cur_cssize; 164 u32 cs_order; 165 int ret; 166 int i; 167 168 if (eb->is_42x && (cs_index > 7)) { 169 dev_err(eb->dev, 170 "invalid chipselect %u, we only support 0-7\n", 171 cs_index); 172 return; 173 } 174 if (eb->is_43x && (cs_index > 3)) { 175 dev_err(eb->dev, 176 "invalid chipselect %u, we only support 0-3\n", 177 cs_index); 178 return; 179 } 180 181 /* Several chip selects can be joined into one device */ 182 if (cs_size > IXP4XX_EXP_STRIDE) 183 cur_cssize = IXP4XX_EXP_STRIDE; 184 else 185 cur_cssize = cs_size; 186 187 188 /* 189 * The following will read/modify/write the configuration for one 190 * chipselect, attempting to leave the boot defaults in place unless 191 * something is explicitly defined. 192 */ 193 regmap_read(eb->rmap, IXP4XX_EXP_TIMING_CS0 + 194 IXP4XX_EXP_TIMING_STRIDE * cs_index, &cs_cfg); 195 dev_info(eb->dev, "CS%d at %#08x, size %#08x, config before: %#08x\n", 196 cs_index, eb->bus_base + IXP4XX_EXP_STRIDE * cs_index, 197 cur_cssize, cs_cfg); 198 199 /* Size set-up first align to 2^9 .. 2^24 */ 200 cur_cssize = roundup_pow_of_two(cur_cssize); 201 if (cur_cssize < 512) 202 cur_cssize = 512; 203 cs_order = ilog2(cur_cssize); 204 if (cs_order < 9 || cs_order > 24) { 205 dev_err(eb->dev, "illegal size order %d\n", cs_order); 206 return; 207 } 208 dev_dbg(eb->dev, "CS%d size order: %d\n", cs_index, cs_order); 209 cs_cfg &= ~(IXP4XX_EXP_SIZE_MASK); 210 cs_cfg |= ((cs_order - 9) << IXP4XX_EXP_SIZE_SHIFT); 211 212 for (i = 0; i < ARRAY_SIZE(ixp4xx_exp_tim_props); i++) { 213 const struct ixp4xx_exp_tim_prop *ip = &ixp4xx_exp_tim_props[i]; 214 215 /* All are regular u32 values */ 216 ret = of_property_read_u32(np, ip->prop, &val); 217 if (ret) 218 continue; 219 220 /* Handle bools (single bits) first */ 221 if (ip->max == 1) { 222 if (val) 223 cs_cfg |= ip->mask; 224 else 225 cs_cfg &= ~ip->mask; 226 dev_info(eb->dev, "CS%d %s %s\n", cs_index, 227 val ? "enabled" : "disabled", 228 ip->prop); 229 continue; 230 } 231 232 if (val > ip->max) { 233 dev_err(eb->dev, 234 "CS%d too high value for %s: %u, capped at %u\n", 235 cs_index, ip->prop, val, ip->max); 236 val = ip->max; 237 } 238 /* This assumes max value fills all the assigned bits (and it does) */ 239 cs_cfg &= ~ip->mask; 240 cs_cfg |= (val << ip->shift); 241 dev_info(eb->dev, "CS%d set %s to %u\n", cs_index, ip->prop, val); 242 } 243 244 ret = of_property_read_u32(np, "intel,ixp4xx-eb-cycle-type", &val); 245 if (!ret) { 246 if (val > 3) { 247 dev_err(eb->dev, "illegal cycle type %d\n", val); 248 return; 249 } 250 dev_info(eb->dev, "CS%d set cycle type %d\n", cs_index, val); 251 cs_cfg &= ~IXP4XX_EXP_CYC_TYPE_MASK; 252 cs_cfg |= val << IXP4XX_EXP_CYC_TYPE_SHIFT; 253 } 254 255 if (eb->is_42x) 256 cs_cfg &= ~IXP42X_RESERVED; 257 if (eb->is_43x) { 258 cs_cfg &= ~IXP43X_RESERVED; 259 /* 260 * This bit for Intel strata flash is currently unused, but let's 261 * report it if we find one. 262 */ 263 if (cs_cfg & IXP43X_EXP_SYNC_INTEL) 264 dev_info(eb->dev, "claims to be Intel strata flash\n"); 265 } 266 cs_cfg |= IXP4XX_EXP_CS_EN; 267 268 regmap_write(eb->rmap, 269 IXP4XX_EXP_TIMING_CS0 + IXP4XX_EXP_TIMING_STRIDE * cs_index, 270 cs_cfg); 271 dev_info(eb->dev, "CS%d wrote %#08x into CS config\n", cs_index, cs_cfg); 272 273 /* 274 * If several chip selects are joined together into one big 275 * device area, we call ourselves recursively for each successive 276 * chip select. For a 32MB flash chip this results in two calls 277 * for example. 278 */ 279 if (cs_size > IXP4XX_EXP_STRIDE) 280 ixp4xx_exp_setup_chipselect(eb, np, 281 cs_index + 1, 282 cs_size - IXP4XX_EXP_STRIDE); 283} 284 285static void ixp4xx_exp_setup_child(struct ixp4xx_eb *eb, 286 struct device_node *np) 287{ 288 u32 cs_sizes[IXP4XX_EXP_NUM_CS]; 289 int num_regs; 290 u32 csindex; 291 u32 cssize; 292 int ret; 293 int i; 294 295 num_regs = of_property_count_elems_of_size(np, "reg", IXP4XX_OF_REG_SIZE); 296 if (num_regs <= 0) 297 return; 298 dev_dbg(eb->dev, "child %s has %d register sets\n", 299 of_node_full_name(np), num_regs); 300 301 for (csindex = 0; csindex < IXP4XX_EXP_NUM_CS; csindex++) 302 cs_sizes[csindex] = 0; 303 304 for (i = 0; i < num_regs; i++) { 305 u32 rbase, rsize; 306 307 ret = of_property_read_u32_index(np, "reg", 308 i * IXP4XX_OF_REG_SIZE, &csindex); 309 if (ret) 310 break; 311 ret = of_property_read_u32_index(np, "reg", 312 i * IXP4XX_OF_REG_SIZE + 1, &rbase); 313 if (ret) 314 break; 315 ret = of_property_read_u32_index(np, "reg", 316 i * IXP4XX_OF_REG_SIZE + 2, &rsize); 317 if (ret) 318 break; 319 320 if (csindex >= IXP4XX_EXP_NUM_CS) { 321 dev_err(eb->dev, "illegal CS %d\n", csindex); 322 continue; 323 } 324 /* 325 * The memory window always starts from CS base so we need to add 326 * the start and size to get to the size from the start of the CS 327 * base. For example if CS0 is at 0x50000000 and the reg is 328 * <0 0xe40000 0x40000> the size is e80000. 329 * 330 * Roof this if we have several regs setting the same CS. 331 */ 332 cssize = rbase + rsize; 333 dev_dbg(eb->dev, "CS%d size %#08x\n", csindex, cssize); 334 if (cs_sizes[csindex] < cssize) 335 cs_sizes[csindex] = cssize; 336 } 337 338 for (csindex = 0; csindex < IXP4XX_EXP_NUM_CS; csindex++) { 339 cssize = cs_sizes[csindex]; 340 if (!cssize) 341 continue; 342 /* Just this one, so set it up and return */ 343 ixp4xx_exp_setup_chipselect(eb, np, csindex, cssize); 344 } 345} 346 347static int ixp4xx_exp_probe(struct platform_device *pdev) 348{ 349 struct device *dev = &pdev->dev; 350 struct device_node *np = dev->of_node; 351 struct ixp4xx_eb *eb; 352 struct device_node *child; 353 bool have_children = false; 354 u32 val; 355 int ret; 356 357 eb = devm_kzalloc(dev, sizeof(*eb), GFP_KERNEL); 358 if (!eb) 359 return -ENOMEM; 360 361 eb->dev = dev; 362 eb->is_42x = of_device_is_compatible(np, "intel,ixp42x-expansion-bus-controller"); 363 eb->is_43x = of_device_is_compatible(np, "intel,ixp43x-expansion-bus-controller"); 364 365 eb->rmap = syscon_node_to_regmap(np); 366 if (IS_ERR(eb->rmap)) 367 return dev_err_probe(dev, PTR_ERR(eb->rmap), "no regmap\n"); 368 369 /* We check that the regmap work only on first read */ 370 ret = regmap_read(eb->rmap, IXP4XX_EXP_CNFG0, &val); 371 if (ret) 372 return dev_err_probe(dev, ret, "cannot read regmap\n"); 373 if (val & IXP4XX_EXP_CNFG0_MEM_MAP) 374 eb->bus_base = IXP4XX_EXP_BOOT_BASE; 375 else 376 eb->bus_base = IXP4XX_EXP_NORMAL_BASE; 377 dev_info(dev, "expansion bus at %08x\n", eb->bus_base); 378 379 if (eb->is_43x) { 380 /* Check some fuses */ 381 regmap_read(eb->rmap, IXP43X_EXP_UNIT_FUSE_RESET, &val); 382 switch (FIELD_GET(IXP43x_EXP_FUSE_SPEED_MASK, val)) { 383 case 0: 384 dev_info(dev, "IXP43x at 533 MHz\n"); 385 break; 386 case 1: 387 dev_info(dev, "IXP43x at 400 MHz\n"); 388 break; 389 case 2: 390 dev_info(dev, "IXP43x at 667 MHz\n"); 391 break; 392 default: 393 dev_info(dev, "IXP43x unknown speed\n"); 394 break; 395 } 396 } 397 398 /* Walk over the child nodes and see what chipselects we use */ 399 for_each_available_child_of_node(np, child) { 400 ixp4xx_exp_setup_child(eb, child); 401 /* We have at least one child */ 402 have_children = true; 403 } 404 405 if (have_children) 406 return of_platform_default_populate(np, NULL, dev); 407 408 return 0; 409} 410 411static const struct of_device_id ixp4xx_exp_of_match[] = { 412 { .compatible = "intel,ixp42x-expansion-bus-controller", }, 413 { .compatible = "intel,ixp43x-expansion-bus-controller", }, 414 { .compatible = "intel,ixp45x-expansion-bus-controller", }, 415 { .compatible = "intel,ixp46x-expansion-bus-controller", }, 416 { } 417}; 418 419static struct platform_driver ixp4xx_exp_driver = { 420 .probe = ixp4xx_exp_probe, 421 .driver = { 422 .name = "intel-extbus", 423 .of_match_table = ixp4xx_exp_of_match, 424 }, 425}; 426module_platform_driver(ixp4xx_exp_driver); 427MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); 428MODULE_DESCRIPTION("Intel IXP4xx external bus driver"); 429MODULE_LICENSE("GPL");