1 /* 2 * Address map functions for Marvell EBU SoCs (Kirkwood, Armada 3 * 370/XP, Dove, Orion5x and MV78xx0) 4 * 5 * This file is licensed under the terms of the GNU General Public 6 * License version 2. This program is licensed "as is" without any 7 * warranty of any kind, whether express or implied. 8 * 9 * The Marvell EBU SoCs have a configurable physical address space: 10 * the physical address at which certain devices (PCIe, NOR, NAND, 11 * etc.) sit can be configured. The configuration takes place through 12 * two sets of registers: 13 * 14 * - One to configure the access of the CPU to the devices. Depending 15 * on the families, there are between 8 and 20 configurable windows, 16 * each can be use to create a physical memory window that maps to a 17 * specific device. Devices are identified by a tuple (target, 18 * attribute). 19 * 20 * - One to configure the access to the CPU to the SDRAM. There are 21 * either 2 (for Dove) or 4 (for other families) windows to map the 22 * SDRAM into the physical address space. 23 * 24 * This driver: 25 * 26 * - Reads out the SDRAM address decoding windows at initialization 27 * time, and fills the mvebu_mbus_dram_info structure with these 28 * informations. The exported function mv_mbus_dram_info() allow 29 * device drivers to get those informations related to the SDRAM 30 * address decoding windows. This is because devices also have their 31 * own windows (configured through registers that are part of each 32 * device register space), and therefore the drivers for Marvell 33 * devices have to configure those device -> SDRAM windows to ensure 34 * that DMA works properly. 35 * 36 * - Provides an API for platform code or device drivers to 37 * dynamically add or remove address decoding windows for the CPU -> 38 * device accesses. This API is mvebu_mbus_add_window_by_id(), 39 * mvebu_mbus_add_window_remap_by_id() and 40 * mvebu_mbus_del_window(). 41 * 42 * - Provides a debugfs interface in /sys/kernel/debug/mvebu-mbus/ to 43 * see the list of CPU -> SDRAM windows and their configuration 44 * (file 'sdram') and the list of CPU -> devices windows and their 45 * configuration (file 'devices'). 46 */ 47 48 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 49 50 #include <linux/kernel.h> 51 #include <linux/module.h> 52 #include <linux/init.h> 53 #include <linux/mbus.h> 54 #include <linux/io.h> 55 #include <linux/ioport.h> 56 #include <linux/of.h> 57 #include <linux/of_address.h> 58 #include <linux/debugfs.h> 59 #include <linux/log2.h> 60 #include <linux/syscore_ops.h> 61 62 /* 63 * DDR target is the same on all platforms. 64 */ 65 #define TARGET_DDR 0 66 67 /* 68 * CPU Address Decode Windows registers 69 */ 70 #define WIN_CTRL_OFF 0x0000 71 #define WIN_CTRL_ENABLE BIT(0) 72 #define WIN_CTRL_TGT_MASK 0xf0 73 #define WIN_CTRL_TGT_SHIFT 4 74 #define WIN_CTRL_ATTR_MASK 0xff00 75 #define WIN_CTRL_ATTR_SHIFT 8 76 #define WIN_CTRL_SIZE_MASK 0xffff0000 77 #define WIN_CTRL_SIZE_SHIFT 16 78 #define WIN_BASE_OFF 0x0004 79 #define WIN_BASE_LOW 0xffff0000 80 #define WIN_BASE_HIGH 0xf 81 #define WIN_REMAP_LO_OFF 0x0008 82 #define WIN_REMAP_LOW 0xffff0000 83 #define WIN_REMAP_HI_OFF 0x000c 84 85 #define ATTR_HW_COHERENCY (0x1 << 4) 86 87 #define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) 88 #define DDR_BASE_CS_HIGH_MASK 0xf 89 #define DDR_BASE_CS_LOW_MASK 0xff000000 90 #define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) 91 #define DDR_SIZE_ENABLED BIT(0) 92 #define DDR_SIZE_CS_MASK 0x1c 93 #define DDR_SIZE_CS_SHIFT 2 94 #define DDR_SIZE_MASK 0xff000000 95 96 #define DOVE_DDR_BASE_CS_OFF(n) ((n) << 4) 97 98 /* Relative to mbusbridge_base */ 99 #define MBUS_BRIDGE_CTRL_OFF 0x0 100 #define MBUS_BRIDGE_BASE_OFF 0x4 101 102 /* Maximum number of windows, for all known platforms */ 103 #define MBUS_WINS_MAX 20 104 105 struct mvebu_mbus_state; 106 107 struct mvebu_mbus_soc_data { 108 unsigned int num_wins; 109 unsigned int num_remappable_wins; 110 bool has_mbus_bridge; 111 unsigned int (*win_cfg_offset)(const int win); 112 void (*setup_cpu_target)(struct mvebu_mbus_state *s); 113 int (*save_cpu_target)(struct mvebu_mbus_state *s, 114 u32 *store_addr); 115 int (*show_cpu_target)(struct mvebu_mbus_state *s, 116 struct seq_file *seq, void *v); 117 }; 118 119 /* 120 * Used to store the state of one MBus window accross suspend/resume. 121 */ 122 struct mvebu_mbus_win_data { 123 u32 ctrl; 124 u32 base; 125 u32 remap_lo; 126 u32 remap_hi; 127 }; 128 129 struct mvebu_mbus_state { 130 void __iomem *mbuswins_base; 131 void __iomem *sdramwins_base; 132 void __iomem *mbusbridge_base; 133 phys_addr_t sdramwins_phys_base; 134 struct dentry *debugfs_root; 135 struct dentry *debugfs_sdram; 136 struct dentry *debugfs_devs; 137 struct resource pcie_mem_aperture; 138 struct resource pcie_io_aperture; 139 const struct mvebu_mbus_soc_data *soc; 140 int hw_io_coherency; 141 142 /* Used during suspend/resume */ 143 u32 mbus_bridge_ctrl; 144 u32 mbus_bridge_base; 145 struct mvebu_mbus_win_data wins[MBUS_WINS_MAX]; 146 }; 147 148 static struct mvebu_mbus_state mbus_state; 149 150 static struct mbus_dram_target_info mvebu_mbus_dram_info; 151 const struct mbus_dram_target_info *mv_mbus_dram_info(void) 152 { 153 return &mvebu_mbus_dram_info; 154 } 155 EXPORT_SYMBOL_GPL(mv_mbus_dram_info); 156 157 /* 158 * Functions to manipulate the address decoding windows 159 */ 160 161 static void mvebu_mbus_read_window(struct mvebu_mbus_state *mbus, 162 int win, int *enabled, u64 *base, 163 u32 *size, u8 *target, u8 *attr, 164 u64 *remap) 165 { 166 void __iomem *addr = mbus->mbuswins_base + 167 mbus->soc->win_cfg_offset(win); 168 u32 basereg = readl(addr + WIN_BASE_OFF); 169 u32 ctrlreg = readl(addr + WIN_CTRL_OFF); 170 171 if (!(ctrlreg & WIN_CTRL_ENABLE)) { 172 *enabled = 0; 173 return; 174 } 175 176 *enabled = 1; 177 *base = ((u64)basereg & WIN_BASE_HIGH) << 32; 178 *base |= (basereg & WIN_BASE_LOW); 179 *size = (ctrlreg | ~WIN_CTRL_SIZE_MASK) + 1; 180 181 if (target) 182 *target = (ctrlreg & WIN_CTRL_TGT_MASK) >> WIN_CTRL_TGT_SHIFT; 183 184 if (attr) 185 *attr = (ctrlreg & WIN_CTRL_ATTR_MASK) >> WIN_CTRL_ATTR_SHIFT; 186 187 if (remap) { 188 if (win < mbus->soc->num_remappable_wins) { 189 u32 remap_low = readl(addr + WIN_REMAP_LO_OFF); 190 u32 remap_hi = readl(addr + WIN_REMAP_HI_OFF); 191 *remap = ((u64)remap_hi << 32) | remap_low; 192 } else 193 *remap = 0; 194 } 195 } 196 197 static void mvebu_mbus_disable_window(struct mvebu_mbus_state *mbus, 198 int win) 199 { 200 void __iomem *addr; 201 202 addr = mbus->mbuswins_base + mbus->soc->win_cfg_offset(win); 203 204 writel(0, addr + WIN_BASE_OFF); 205 writel(0, addr + WIN_CTRL_OFF); 206 if (win < mbus->soc->num_remappable_wins) { 207 writel(0, addr + WIN_REMAP_LO_OFF); 208 writel(0, addr + WIN_REMAP_HI_OFF); 209 } 210 } 211 212 /* Checks whether the given window number is available */ 213 static int mvebu_mbus_window_is_free(struct mvebu_mbus_state *mbus, 214 const int win) 215 { 216 void __iomem *addr = mbus->mbuswins_base + 217 mbus->soc->win_cfg_offset(win); 218 u32 ctrl = readl(addr + WIN_CTRL_OFF); 219 return !(ctrl & WIN_CTRL_ENABLE); 220 } 221 222 /* 223 * Checks whether the given (base, base+size) area doesn't overlap an 224 * existing region 225 */ 226 static int mvebu_mbus_window_conflicts(struct mvebu_mbus_state *mbus, 227 phys_addr_t base, size_t size, 228 u8 target, u8 attr) 229 { 230 u64 end = (u64)base + size; 231 int win; 232 233 for (win = 0; win < mbus->soc->num_wins; win++) { 234 u64 wbase, wend; 235 u32 wsize; 236 u8 wtarget, wattr; 237 int enabled; 238 239 mvebu_mbus_read_window(mbus, win, 240 &enabled, &wbase, &wsize, 241 &wtarget, &wattr, NULL); 242 243 if (!enabled) 244 continue; 245 246 wend = wbase + wsize; 247 248 /* 249 * Check if the current window overlaps with the 250 * proposed physical range 251 */ 252 if ((u64)base < wend && end > wbase) 253 return 0; 254 } 255 256 return 1; 257 } 258 259 static int mvebu_mbus_find_window(struct mvebu_mbus_state *mbus, 260 phys_addr_t base, size_t size) 261 { 262 int win; 263 264 for (win = 0; win < mbus->soc->num_wins; win++) { 265 u64 wbase; 266 u32 wsize; 267 int enabled; 268 269 mvebu_mbus_read_window(mbus, win, 270 &enabled, &wbase, &wsize, 271 NULL, NULL, NULL); 272 273 if (!enabled) 274 continue; 275 276 if (base == wbase && size == wsize) 277 return win; 278 } 279 280 return -ENODEV; 281 } 282 283 static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus, 284 int win, phys_addr_t base, size_t size, 285 phys_addr_t remap, u8 target, 286 u8 attr) 287 { 288 void __iomem *addr = mbus->mbuswins_base + 289 mbus->soc->win_cfg_offset(win); 290 u32 ctrl, remap_addr; 291 292 if (!is_power_of_2(size)) { 293 WARN(true, "Invalid MBus window size: 0x%zx\n", size); 294 return -EINVAL; 295 } 296 297 if ((base & (phys_addr_t)(size - 1)) != 0) { 298 WARN(true, "Invalid MBus base/size: %pa len 0x%zx\n", &base, 299 size); 300 return -EINVAL; 301 } 302 303 ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) | 304 (attr << WIN_CTRL_ATTR_SHIFT) | 305 (target << WIN_CTRL_TGT_SHIFT) | 306 WIN_CTRL_ENABLE; 307 308 writel(base & WIN_BASE_LOW, addr + WIN_BASE_OFF); 309 writel(ctrl, addr + WIN_CTRL_OFF); 310 if (win < mbus->soc->num_remappable_wins) { 311 if (remap == MVEBU_MBUS_NO_REMAP) 312 remap_addr = base; 313 else 314 remap_addr = remap; 315 writel(remap_addr & WIN_REMAP_LOW, addr + WIN_REMAP_LO_OFF); 316 writel(0, addr + WIN_REMAP_HI_OFF); 317 } 318 319 return 0; 320 } 321 322 static int mvebu_mbus_alloc_window(struct mvebu_mbus_state *mbus, 323 phys_addr_t base, size_t size, 324 phys_addr_t remap, u8 target, 325 u8 attr) 326 { 327 int win; 328 329 if (remap == MVEBU_MBUS_NO_REMAP) { 330 for (win = mbus->soc->num_remappable_wins; 331 win < mbus->soc->num_wins; win++) 332 if (mvebu_mbus_window_is_free(mbus, win)) 333 return mvebu_mbus_setup_window(mbus, win, base, 334 size, remap, 335 target, attr); 336 } 337 338 339 for (win = 0; win < mbus->soc->num_wins; win++) 340 if (mvebu_mbus_window_is_free(mbus, win)) 341 return mvebu_mbus_setup_window(mbus, win, base, size, 342 remap, target, attr); 343 344 return -ENOMEM; 345 } 346 347 /* 348 * Debugfs debugging 349 */ 350 351 /* Common function used for Dove, Kirkwood, Armada 370/XP and Orion 5x */ 352 static int mvebu_sdram_debug_show_orion(struct mvebu_mbus_state *mbus, 353 struct seq_file *seq, void *v) 354 { 355 int i; 356 357 for (i = 0; i < 4; i++) { 358 u32 basereg = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i)); 359 u32 sizereg = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i)); 360 u64 base; 361 u32 size; 362 363 if (!(sizereg & DDR_SIZE_ENABLED)) { 364 seq_printf(seq, "[%d] disabled\n", i); 365 continue; 366 } 367 368 base = ((u64)basereg & DDR_BASE_CS_HIGH_MASK) << 32; 369 base |= basereg & DDR_BASE_CS_LOW_MASK; 370 size = (sizereg | ~DDR_SIZE_MASK); 371 372 seq_printf(seq, "[%d] %016llx - %016llx : cs%d\n", 373 i, (unsigned long long)base, 374 (unsigned long long)base + size + 1, 375 (sizereg & DDR_SIZE_CS_MASK) >> DDR_SIZE_CS_SHIFT); 376 } 377 378 return 0; 379 } 380 381 /* Special function for Dove */ 382 static int mvebu_sdram_debug_show_dove(struct mvebu_mbus_state *mbus, 383 struct seq_file *seq, void *v) 384 { 385 int i; 386 387 for (i = 0; i < 2; i++) { 388 u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i)); 389 u64 base; 390 u32 size; 391 392 if (!(map & 1)) { 393 seq_printf(seq, "[%d] disabled\n", i); 394 continue; 395 } 396 397 base = map & 0xff800000; 398 size = 0x100000 << (((map & 0x000f0000) >> 16) - 4); 399 400 seq_printf(seq, "[%d] %016llx - %016llx : cs%d\n", 401 i, (unsigned long long)base, 402 (unsigned long long)base + size, i); 403 } 404 405 return 0; 406 } 407 408 static int mvebu_sdram_debug_show(struct seq_file *seq, void *v) 409 { 410 struct mvebu_mbus_state *mbus = &mbus_state; 411 return mbus->soc->show_cpu_target(mbus, seq, v); 412 } 413 414 static int mvebu_sdram_debug_open(struct inode *inode, struct file *file) 415 { 416 return single_open(file, mvebu_sdram_debug_show, inode->i_private); 417 } 418 419 static const struct file_operations mvebu_sdram_debug_fops = { 420 .open = mvebu_sdram_debug_open, 421 .read = seq_read, 422 .llseek = seq_lseek, 423 .release = single_release, 424 }; 425 426 static int mvebu_devs_debug_show(struct seq_file *seq, void *v) 427 { 428 struct mvebu_mbus_state *mbus = &mbus_state; 429 int win; 430 431 for (win = 0; win < mbus->soc->num_wins; win++) { 432 u64 wbase, wremap; 433 u32 wsize; 434 u8 wtarget, wattr; 435 int enabled; 436 437 mvebu_mbus_read_window(mbus, win, 438 &enabled, &wbase, &wsize, 439 &wtarget, &wattr, &wremap); 440 441 if (!enabled) { 442 seq_printf(seq, "[%02d] disabled\n", win); 443 continue; 444 } 445 446 seq_printf(seq, "[%02d] %016llx - %016llx : %04x:%04x", 447 win, (unsigned long long)wbase, 448 (unsigned long long)(wbase + wsize), wtarget, wattr); 449 450 if (!is_power_of_2(wsize) || 451 ((wbase & (u64)(wsize - 1)) != 0)) 452 seq_puts(seq, " (Invalid base/size!!)"); 453 454 if (win < mbus->soc->num_remappable_wins) { 455 seq_printf(seq, " (remap %016llx)\n", 456 (unsigned long long)wremap); 457 } else 458 seq_printf(seq, "\n"); 459 } 460 461 return 0; 462 } 463 464 static int mvebu_devs_debug_open(struct inode *inode, struct file *file) 465 { 466 return single_open(file, mvebu_devs_debug_show, inode->i_private); 467 } 468 469 static const struct file_operations mvebu_devs_debug_fops = { 470 .open = mvebu_devs_debug_open, 471 .read = seq_read, 472 .llseek = seq_lseek, 473 .release = single_release, 474 }; 475 476 /* 477 * SoC-specific functions and definitions 478 */ 479 480 static unsigned int orion_mbus_win_offset(int win) 481 { 482 return win << 4; 483 } 484 485 static unsigned int armada_370_xp_mbus_win_offset(int win) 486 { 487 /* The register layout is a bit annoying and the below code 488 * tries to cope with it. 489 * - At offset 0x0, there are the registers for the first 8 490 * windows, with 4 registers of 32 bits per window (ctrl, 491 * base, remap low, remap high) 492 * - Then at offset 0x80, there is a hole of 0x10 bytes for 493 * the internal registers base address and internal units 494 * sync barrier register. 495 * - Then at offset 0x90, there the registers for 12 496 * windows, with only 2 registers of 32 bits per window 497 * (ctrl, base). 498 */ 499 if (win < 8) 500 return win << 4; 501 else 502 return 0x90 + ((win - 8) << 3); 503 } 504 505 static unsigned int mv78xx0_mbus_win_offset(int win) 506 { 507 if (win < 8) 508 return win << 4; 509 else 510 return 0x900 + ((win - 8) << 4); 511 } 512 513 static void __init 514 mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus) 515 { 516 int i; 517 int cs; 518 519 mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; 520 521 for (i = 0, cs = 0; i < 4; i++) { 522 u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i)); 523 u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i)); 524 525 /* 526 * We only take care of entries for which the chip 527 * select is enabled, and that don't have high base 528 * address bits set (devices can only access the first 529 * 32 bits of the memory). 530 */ 531 if ((size & DDR_SIZE_ENABLED) && 532 !(base & DDR_BASE_CS_HIGH_MASK)) { 533 struct mbus_dram_window *w; 534 535 w = &mvebu_mbus_dram_info.cs[cs++]; 536 w->cs_index = i; 537 w->mbus_attr = 0xf & ~(1 << i); 538 if (mbus->hw_io_coherency) 539 w->mbus_attr |= ATTR_HW_COHERENCY; 540 w->base = base & DDR_BASE_CS_LOW_MASK; 541 w->size = (size | ~DDR_SIZE_MASK) + 1; 542 } 543 } 544 mvebu_mbus_dram_info.num_cs = cs; 545 } 546 547 static int 548 mvebu_mbus_default_save_cpu_target(struct mvebu_mbus_state *mbus, 549 u32 *store_addr) 550 { 551 int i; 552 553 for (i = 0; i < 4; i++) { 554 u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i)); 555 u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i)); 556 557 writel(mbus->sdramwins_phys_base + DDR_BASE_CS_OFF(i), 558 store_addr++); 559 writel(base, store_addr++); 560 writel(mbus->sdramwins_phys_base + DDR_SIZE_CS_OFF(i), 561 store_addr++); 562 writel(size, store_addr++); 563 } 564 565 /* We've written 16 words to the store address */ 566 return 16; 567 } 568 569 static void __init 570 mvebu_mbus_dove_setup_cpu_target(struct mvebu_mbus_state *mbus) 571 { 572 int i; 573 int cs; 574 575 mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; 576 577 for (i = 0, cs = 0; i < 2; i++) { 578 u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i)); 579 580 /* 581 * Chip select enabled? 582 */ 583 if (map & 1) { 584 struct mbus_dram_window *w; 585 586 w = &mvebu_mbus_dram_info.cs[cs++]; 587 w->cs_index = i; 588 w->mbus_attr = 0; /* CS address decoding done inside */ 589 /* the DDR controller, no need to */ 590 /* provide attributes */ 591 w->base = map & 0xff800000; 592 w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4); 593 } 594 } 595 596 mvebu_mbus_dram_info.num_cs = cs; 597 } 598 599 static int 600 mvebu_mbus_dove_save_cpu_target(struct mvebu_mbus_state *mbus, 601 u32 *store_addr) 602 { 603 int i; 604 605 for (i = 0; i < 2; i++) { 606 u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i)); 607 608 writel(mbus->sdramwins_phys_base + DOVE_DDR_BASE_CS_OFF(i), 609 store_addr++); 610 writel(map, store_addr++); 611 } 612 613 /* We've written 4 words to the store address */ 614 return 4; 615 } 616 617 int mvebu_mbus_save_cpu_target(u32 *store_addr) 618 { 619 return mbus_state.soc->save_cpu_target(&mbus_state, store_addr); 620 } 621 622 static const struct mvebu_mbus_soc_data armada_370_xp_mbus_data = { 623 .num_wins = 20, 624 .num_remappable_wins = 8, 625 .has_mbus_bridge = true, 626 .win_cfg_offset = armada_370_xp_mbus_win_offset, 627 .save_cpu_target = mvebu_mbus_default_save_cpu_target, 628 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 629 .show_cpu_target = mvebu_sdram_debug_show_orion, 630 }; 631 632 static const struct mvebu_mbus_soc_data kirkwood_mbus_data = { 633 .num_wins = 8, 634 .num_remappable_wins = 4, 635 .win_cfg_offset = orion_mbus_win_offset, 636 .save_cpu_target = mvebu_mbus_default_save_cpu_target, 637 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 638 .show_cpu_target = mvebu_sdram_debug_show_orion, 639 }; 640 641 static const struct mvebu_mbus_soc_data dove_mbus_data = { 642 .num_wins = 8, 643 .num_remappable_wins = 4, 644 .win_cfg_offset = orion_mbus_win_offset, 645 .save_cpu_target = mvebu_mbus_dove_save_cpu_target, 646 .setup_cpu_target = mvebu_mbus_dove_setup_cpu_target, 647 .show_cpu_target = mvebu_sdram_debug_show_dove, 648 }; 649 650 /* 651 * Some variants of Orion5x have 4 remappable windows, some other have 652 * only two of them. 653 */ 654 static const struct mvebu_mbus_soc_data orion5x_4win_mbus_data = { 655 .num_wins = 8, 656 .num_remappable_wins = 4, 657 .win_cfg_offset = orion_mbus_win_offset, 658 .save_cpu_target = mvebu_mbus_default_save_cpu_target, 659 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 660 .show_cpu_target = mvebu_sdram_debug_show_orion, 661 }; 662 663 static const struct mvebu_mbus_soc_data orion5x_2win_mbus_data = { 664 .num_wins = 8, 665 .num_remappable_wins = 2, 666 .win_cfg_offset = orion_mbus_win_offset, 667 .save_cpu_target = mvebu_mbus_default_save_cpu_target, 668 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 669 .show_cpu_target = mvebu_sdram_debug_show_orion, 670 }; 671 672 static const struct mvebu_mbus_soc_data mv78xx0_mbus_data = { 673 .num_wins = 14, 674 .num_remappable_wins = 8, 675 .win_cfg_offset = mv78xx0_mbus_win_offset, 676 .save_cpu_target = mvebu_mbus_default_save_cpu_target, 677 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 678 .show_cpu_target = mvebu_sdram_debug_show_orion, 679 }; 680 681 static const struct of_device_id of_mvebu_mbus_ids[] = { 682 { .compatible = "marvell,armada370-mbus", 683 .data = &armada_370_xp_mbus_data, }, 684 { .compatible = "marvell,armadaxp-mbus", 685 .data = &armada_370_xp_mbus_data, }, 686 { .compatible = "marvell,kirkwood-mbus", 687 .data = &kirkwood_mbus_data, }, 688 { .compatible = "marvell,dove-mbus", 689 .data = &dove_mbus_data, }, 690 { .compatible = "marvell,orion5x-88f5281-mbus", 691 .data = &orion5x_4win_mbus_data, }, 692 { .compatible = "marvell,orion5x-88f5182-mbus", 693 .data = &orion5x_2win_mbus_data, }, 694 { .compatible = "marvell,orion5x-88f5181-mbus", 695 .data = &orion5x_2win_mbus_data, }, 696 { .compatible = "marvell,orion5x-88f6183-mbus", 697 .data = &orion5x_4win_mbus_data, }, 698 { .compatible = "marvell,mv78xx0-mbus", 699 .data = &mv78xx0_mbus_data, }, 700 { }, 701 }; 702 703 /* 704 * Public API of the driver 705 */ 706 int mvebu_mbus_add_window_remap_by_id(unsigned int target, 707 unsigned int attribute, 708 phys_addr_t base, size_t size, 709 phys_addr_t remap) 710 { 711 struct mvebu_mbus_state *s = &mbus_state; 712 713 if (!mvebu_mbus_window_conflicts(s, base, size, target, attribute)) { 714 pr_err("cannot add window '%x:%x', conflicts with another window\n", 715 target, attribute); 716 return -EINVAL; 717 } 718 719 return mvebu_mbus_alloc_window(s, base, size, remap, target, attribute); 720 } 721 722 int mvebu_mbus_add_window_by_id(unsigned int target, unsigned int attribute, 723 phys_addr_t base, size_t size) 724 { 725 return mvebu_mbus_add_window_remap_by_id(target, attribute, base, 726 size, MVEBU_MBUS_NO_REMAP); 727 } 728 729 int mvebu_mbus_del_window(phys_addr_t base, size_t size) 730 { 731 int win; 732 733 win = mvebu_mbus_find_window(&mbus_state, base, size); 734 if (win < 0) 735 return win; 736 737 mvebu_mbus_disable_window(&mbus_state, win); 738 return 0; 739 } 740 741 void mvebu_mbus_get_pcie_mem_aperture(struct resource *res) 742 { 743 if (!res) 744 return; 745 *res = mbus_state.pcie_mem_aperture; 746 } 747 748 void mvebu_mbus_get_pcie_io_aperture(struct resource *res) 749 { 750 if (!res) 751 return; 752 *res = mbus_state.pcie_io_aperture; 753 } 754 755 static __init int mvebu_mbus_debugfs_init(void) 756 { 757 struct mvebu_mbus_state *s = &mbus_state; 758 759 /* 760 * If no base has been initialized, doesn't make sense to 761 * register the debugfs entries. We may be on a multiplatform 762 * kernel that isn't running a Marvell EBU SoC. 763 */ 764 if (!s->mbuswins_base) 765 return 0; 766 767 s->debugfs_root = debugfs_create_dir("mvebu-mbus", NULL); 768 if (s->debugfs_root) { 769 s->debugfs_sdram = debugfs_create_file("sdram", S_IRUGO, 770 s->debugfs_root, NULL, 771 &mvebu_sdram_debug_fops); 772 s->debugfs_devs = debugfs_create_file("devices", S_IRUGO, 773 s->debugfs_root, NULL, 774 &mvebu_devs_debug_fops); 775 } 776 777 return 0; 778 } 779 fs_initcall(mvebu_mbus_debugfs_init); 780 781 static int mvebu_mbus_suspend(void) 782 { 783 struct mvebu_mbus_state *s = &mbus_state; 784 int win; 785 786 if (!s->mbusbridge_base) 787 return -ENODEV; 788 789 for (win = 0; win < s->soc->num_wins; win++) { 790 void __iomem *addr = s->mbuswins_base + 791 s->soc->win_cfg_offset(win); 792 793 s->wins[win].base = readl(addr + WIN_BASE_OFF); 794 s->wins[win].ctrl = readl(addr + WIN_CTRL_OFF); 795 796 if (win >= s->soc->num_remappable_wins) 797 continue; 798 799 s->wins[win].remap_lo = readl(addr + WIN_REMAP_LO_OFF); 800 s->wins[win].remap_hi = readl(addr + WIN_REMAP_HI_OFF); 801 } 802 803 s->mbus_bridge_ctrl = readl(s->mbusbridge_base + 804 MBUS_BRIDGE_CTRL_OFF); 805 s->mbus_bridge_base = readl(s->mbusbridge_base + 806 MBUS_BRIDGE_BASE_OFF); 807 808 return 0; 809 } 810 811 static void mvebu_mbus_resume(void) 812 { 813 struct mvebu_mbus_state *s = &mbus_state; 814 int win; 815 816 writel(s->mbus_bridge_ctrl, 817 s->mbusbridge_base + MBUS_BRIDGE_CTRL_OFF); 818 writel(s->mbus_bridge_base, 819 s->mbusbridge_base + MBUS_BRIDGE_BASE_OFF); 820 821 for (win = 0; win < s->soc->num_wins; win++) { 822 void __iomem *addr = s->mbuswins_base + 823 s->soc->win_cfg_offset(win); 824 825 writel(s->wins[win].base, addr + WIN_BASE_OFF); 826 writel(s->wins[win].ctrl, addr + WIN_CTRL_OFF); 827 828 if (win >= s->soc->num_remappable_wins) 829 continue; 830 831 writel(s->wins[win].remap_lo, addr + WIN_REMAP_LO_OFF); 832 writel(s->wins[win].remap_hi, addr + WIN_REMAP_HI_OFF); 833 } 834 } 835 836 struct syscore_ops mvebu_mbus_syscore_ops = { 837 .suspend = mvebu_mbus_suspend, 838 .resume = mvebu_mbus_resume, 839 }; 840 841 static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, 842 phys_addr_t mbuswins_phys_base, 843 size_t mbuswins_size, 844 phys_addr_t sdramwins_phys_base, 845 size_t sdramwins_size, 846 phys_addr_t mbusbridge_phys_base, 847 size_t mbusbridge_size) 848 { 849 int win; 850 851 mbus->mbuswins_base = ioremap(mbuswins_phys_base, mbuswins_size); 852 if (!mbus->mbuswins_base) 853 return -ENOMEM; 854 855 mbus->sdramwins_base = ioremap(sdramwins_phys_base, sdramwins_size); 856 if (!mbus->sdramwins_base) { 857 iounmap(mbus_state.mbuswins_base); 858 return -ENOMEM; 859 } 860 861 mbus->sdramwins_phys_base = sdramwins_phys_base; 862 863 if (mbusbridge_phys_base) { 864 mbus->mbusbridge_base = ioremap(mbusbridge_phys_base, 865 mbusbridge_size); 866 if (!mbus->mbusbridge_base) { 867 iounmap(mbus->sdramwins_base); 868 iounmap(mbus->mbuswins_base); 869 return -ENOMEM; 870 } 871 } else 872 mbus->mbusbridge_base = NULL; 873 874 for (win = 0; win < mbus->soc->num_wins; win++) 875 mvebu_mbus_disable_window(mbus, win); 876 877 mbus->soc->setup_cpu_target(mbus); 878 879 register_syscore_ops(&mvebu_mbus_syscore_ops); 880 881 return 0; 882 } 883 884 int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base, 885 size_t mbuswins_size, 886 phys_addr_t sdramwins_phys_base, 887 size_t sdramwins_size) 888 { 889 const struct of_device_id *of_id; 890 891 for (of_id = of_mvebu_mbus_ids; of_id->compatible[0]; of_id++) 892 if (!strcmp(of_id->compatible, soc)) 893 break; 894 895 if (!of_id->compatible[0]) { 896 pr_err("could not find a matching SoC family\n"); 897 return -ENODEV; 898 } 899 900 mbus_state.soc = of_id->data; 901 902 return mvebu_mbus_common_init(&mbus_state, 903 mbuswins_phys_base, 904 mbuswins_size, 905 sdramwins_phys_base, 906 sdramwins_size, 0, 0); 907 } 908 909 #ifdef CONFIG_OF 910 /* 911 * The window IDs in the ranges DT property have the following format: 912 * - bits 28 to 31: MBus custom field 913 * - bits 24 to 27: window target ID 914 * - bits 16 to 23: window attribute ID 915 * - bits 0 to 15: unused 916 */ 917 #define CUSTOM(id) (((id) & 0xF0000000) >> 24) 918 #define TARGET(id) (((id) & 0x0F000000) >> 24) 919 #define ATTR(id) (((id) & 0x00FF0000) >> 16) 920 921 static int __init mbus_dt_setup_win(struct mvebu_mbus_state *mbus, 922 u32 base, u32 size, 923 u8 target, u8 attr) 924 { 925 if (!mvebu_mbus_window_conflicts(mbus, base, size, target, attr)) { 926 pr_err("cannot add window '%04x:%04x', conflicts with another window\n", 927 target, attr); 928 return -EBUSY; 929 } 930 931 if (mvebu_mbus_alloc_window(mbus, base, size, MVEBU_MBUS_NO_REMAP, 932 target, attr)) { 933 pr_err("cannot add window '%04x:%04x', too many windows\n", 934 target, attr); 935 return -ENOMEM; 936 } 937 return 0; 938 } 939 940 static int __init 941 mbus_parse_ranges(struct device_node *node, 942 int *addr_cells, int *c_addr_cells, int *c_size_cells, 943 int *cell_count, const __be32 **ranges_start, 944 const __be32 **ranges_end) 945 { 946 const __be32 *prop; 947 int ranges_len, tuple_len; 948 949 /* Allow a node with no 'ranges' property */ 950 *ranges_start = of_get_property(node, "ranges", &ranges_len); 951 if (*ranges_start == NULL) { 952 *addr_cells = *c_addr_cells = *c_size_cells = *cell_count = 0; 953 *ranges_start = *ranges_end = NULL; 954 return 0; 955 } 956 *ranges_end = *ranges_start + ranges_len / sizeof(__be32); 957 958 *addr_cells = of_n_addr_cells(node); 959 960 prop = of_get_property(node, "#address-cells", NULL); 961 *c_addr_cells = be32_to_cpup(prop); 962 963 prop = of_get_property(node, "#size-cells", NULL); 964 *c_size_cells = be32_to_cpup(prop); 965 966 *cell_count = *addr_cells + *c_addr_cells + *c_size_cells; 967 tuple_len = (*cell_count) * sizeof(__be32); 968 969 if (ranges_len % tuple_len) { 970 pr_warn("malformed ranges entry '%s'\n", node->name); 971 return -EINVAL; 972 } 973 return 0; 974 } 975 976 static int __init mbus_dt_setup(struct mvebu_mbus_state *mbus, 977 struct device_node *np) 978 { 979 int addr_cells, c_addr_cells, c_size_cells; 980 int i, ret, cell_count; 981 const __be32 *r, *ranges_start, *ranges_end; 982 983 ret = mbus_parse_ranges(np, &addr_cells, &c_addr_cells, 984 &c_size_cells, &cell_count, 985 &ranges_start, &ranges_end); 986 if (ret < 0) 987 return ret; 988 989 for (i = 0, r = ranges_start; r < ranges_end; r += cell_count, i++) { 990 u32 windowid, base, size; 991 u8 target, attr; 992 993 /* 994 * An entry with a non-zero custom field do not 995 * correspond to a static window, so skip it. 996 */ 997 windowid = of_read_number(r, 1); 998 if (CUSTOM(windowid)) 999 continue; 1000 1001 target = TARGET(windowid); 1002 attr = ATTR(windowid); 1003 1004 base = of_read_number(r + c_addr_cells, addr_cells); 1005 size = of_read_number(r + c_addr_cells + addr_cells, 1006 c_size_cells); 1007 ret = mbus_dt_setup_win(mbus, base, size, target, attr); 1008 if (ret < 0) 1009 return ret; 1010 } 1011 return 0; 1012 } 1013 1014 static void __init mvebu_mbus_get_pcie_resources(struct device_node *np, 1015 struct resource *mem, 1016 struct resource *io) 1017 { 1018 u32 reg[2]; 1019 int ret; 1020 1021 /* 1022 * These are optional, so we make sure that resource_size(x) will 1023 * return 0. 1024 */ 1025 memset(mem, 0, sizeof(struct resource)); 1026 mem->end = -1; 1027 memset(io, 0, sizeof(struct resource)); 1028 io->end = -1; 1029 1030 ret = of_property_read_u32_array(np, "pcie-mem-aperture", reg, ARRAY_SIZE(reg)); 1031 if (!ret) { 1032 mem->start = reg[0]; 1033 mem->end = mem->start + reg[1] - 1; 1034 mem->flags = IORESOURCE_MEM; 1035 } 1036 1037 ret = of_property_read_u32_array(np, "pcie-io-aperture", reg, ARRAY_SIZE(reg)); 1038 if (!ret) { 1039 io->start = reg[0]; 1040 io->end = io->start + reg[1] - 1; 1041 io->flags = IORESOURCE_IO; 1042 } 1043 } 1044 1045 int __init mvebu_mbus_dt_init(bool is_coherent) 1046 { 1047 struct resource mbuswins_res, sdramwins_res, mbusbridge_res; 1048 struct device_node *np, *controller; 1049 const struct of_device_id *of_id; 1050 const __be32 *prop; 1051 int ret; 1052 1053 np = of_find_matching_node_and_match(NULL, of_mvebu_mbus_ids, &of_id); 1054 if (!np) { 1055 pr_err("could not find a matching SoC family\n"); 1056 return -ENODEV; 1057 } 1058 1059 mbus_state.soc = of_id->data; 1060 1061 prop = of_get_property(np, "controller", NULL); 1062 if (!prop) { 1063 pr_err("required 'controller' property missing\n"); 1064 return -EINVAL; 1065 } 1066 1067 controller = of_find_node_by_phandle(be32_to_cpup(prop)); 1068 if (!controller) { 1069 pr_err("could not find an 'mbus-controller' node\n"); 1070 return -ENODEV; 1071 } 1072 1073 if (of_address_to_resource(controller, 0, &mbuswins_res)) { 1074 pr_err("cannot get MBUS register address\n"); 1075 return -EINVAL; 1076 } 1077 1078 if (of_address_to_resource(controller, 1, &sdramwins_res)) { 1079 pr_err("cannot get SDRAM register address\n"); 1080 return -EINVAL; 1081 } 1082 1083 /* 1084 * Set the resource to 0 so that it can be left unmapped by 1085 * mvebu_mbus_common_init() if the DT doesn't carry the 1086 * necessary information. This is needed to preserve backward 1087 * compatibility. 1088 */ 1089 memset(&mbusbridge_res, 0, sizeof(mbusbridge_res)); 1090 1091 if (mbus_state.soc->has_mbus_bridge) { 1092 if (of_address_to_resource(controller, 2, &mbusbridge_res)) 1093 pr_warn(FW_WARN "deprecated mbus-mvebu Device Tree, suspend/resume will not work\n"); 1094 } 1095 1096 mbus_state.hw_io_coherency = is_coherent; 1097 1098 /* Get optional pcie-{mem,io}-aperture properties */ 1099 mvebu_mbus_get_pcie_resources(np, &mbus_state.pcie_mem_aperture, 1100 &mbus_state.pcie_io_aperture); 1101 1102 ret = mvebu_mbus_common_init(&mbus_state, 1103 mbuswins_res.start, 1104 resource_size(&mbuswins_res), 1105 sdramwins_res.start, 1106 resource_size(&sdramwins_res), 1107 mbusbridge_res.start, 1108 resource_size(&mbusbridge_res)); 1109 if (ret) 1110 return ret; 1111 1112 /* Setup statically declared windows in the DT */ 1113 return mbus_dt_setup(&mbus_state, np); 1114 } 1115 #endif 1116