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 214 /* On Armada XP, 375 and 38x the MBus window 13 has the remap 215 * capability, like windows 0 to 7. However, the mvebu-mbus driver 216 * isn't currently taking into account this special case, which means 217 * that when window 13 is actually used, the remap registers are left 218 * to 0, making the device using this MBus window unavailable. The 219 * quick fix for stable is to not use window 13. A follow up patch 220 * will correctly handle this window. 221 */ 222 static int mvebu_mbus_window_is_free(struct mvebu_mbus_state *mbus, 223 const int win) 224 { 225 void __iomem *addr = mbus->mbuswins_base + 226 mbus->soc->win_cfg_offset(win); 227 u32 ctrl = readl(addr + WIN_CTRL_OFF); 228 229 if (win == 13) 230 return false; 231 232 return !(ctrl & WIN_CTRL_ENABLE); 233 } 234 235 /* 236 * Checks whether the given (base, base+size) area doesn't overlap an 237 * existing region 238 */ 239 static int mvebu_mbus_window_conflicts(struct mvebu_mbus_state *mbus, 240 phys_addr_t base, size_t size, 241 u8 target, u8 attr) 242 { 243 u64 end = (u64)base + size; 244 int win; 245 246 for (win = 0; win < mbus->soc->num_wins; win++) { 247 u64 wbase, wend; 248 u32 wsize; 249 u8 wtarget, wattr; 250 int enabled; 251 252 mvebu_mbus_read_window(mbus, win, 253 &enabled, &wbase, &wsize, 254 &wtarget, &wattr, NULL); 255 256 if (!enabled) 257 continue; 258 259 wend = wbase + wsize; 260 261 /* 262 * Check if the current window overlaps with the 263 * proposed physical range 264 */ 265 if ((u64)base < wend && end > wbase) 266 return 0; 267 } 268 269 return 1; 270 } 271 272 static int mvebu_mbus_find_window(struct mvebu_mbus_state *mbus, 273 phys_addr_t base, size_t size) 274 { 275 int win; 276 277 for (win = 0; win < mbus->soc->num_wins; win++) { 278 u64 wbase; 279 u32 wsize; 280 int enabled; 281 282 mvebu_mbus_read_window(mbus, win, 283 &enabled, &wbase, &wsize, 284 NULL, NULL, NULL); 285 286 if (!enabled) 287 continue; 288 289 if (base == wbase && size == wsize) 290 return win; 291 } 292 293 return -ENODEV; 294 } 295 296 static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus, 297 int win, phys_addr_t base, size_t size, 298 phys_addr_t remap, u8 target, 299 u8 attr) 300 { 301 void __iomem *addr = mbus->mbuswins_base + 302 mbus->soc->win_cfg_offset(win); 303 u32 ctrl, remap_addr; 304 305 if (!is_power_of_2(size)) { 306 WARN(true, "Invalid MBus window size: 0x%zx\n", size); 307 return -EINVAL; 308 } 309 310 if ((base & (phys_addr_t)(size - 1)) != 0) { 311 WARN(true, "Invalid MBus base/size: %pa len 0x%zx\n", &base, 312 size); 313 return -EINVAL; 314 } 315 316 ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) | 317 (attr << WIN_CTRL_ATTR_SHIFT) | 318 (target << WIN_CTRL_TGT_SHIFT) | 319 WIN_CTRL_ENABLE; 320 321 writel(base & WIN_BASE_LOW, addr + WIN_BASE_OFF); 322 writel(ctrl, addr + WIN_CTRL_OFF); 323 if (win < mbus->soc->num_remappable_wins) { 324 if (remap == MVEBU_MBUS_NO_REMAP) 325 remap_addr = base; 326 else 327 remap_addr = remap; 328 writel(remap_addr & WIN_REMAP_LOW, addr + WIN_REMAP_LO_OFF); 329 writel(0, addr + WIN_REMAP_HI_OFF); 330 } 331 332 return 0; 333 } 334 335 static int mvebu_mbus_alloc_window(struct mvebu_mbus_state *mbus, 336 phys_addr_t base, size_t size, 337 phys_addr_t remap, u8 target, 338 u8 attr) 339 { 340 int win; 341 342 if (remap == MVEBU_MBUS_NO_REMAP) { 343 for (win = mbus->soc->num_remappable_wins; 344 win < mbus->soc->num_wins; win++) 345 if (mvebu_mbus_window_is_free(mbus, win)) 346 return mvebu_mbus_setup_window(mbus, win, base, 347 size, remap, 348 target, attr); 349 } 350 351 352 for (win = 0; win < mbus->soc->num_wins; win++) 353 if (mvebu_mbus_window_is_free(mbus, win)) 354 return mvebu_mbus_setup_window(mbus, win, base, size, 355 remap, target, attr); 356 357 return -ENOMEM; 358 } 359 360 /* 361 * Debugfs debugging 362 */ 363 364 /* Common function used for Dove, Kirkwood, Armada 370/XP and Orion 5x */ 365 static int mvebu_sdram_debug_show_orion(struct mvebu_mbus_state *mbus, 366 struct seq_file *seq, void *v) 367 { 368 int i; 369 370 for (i = 0; i < 4; i++) { 371 u32 basereg = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i)); 372 u32 sizereg = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i)); 373 u64 base; 374 u32 size; 375 376 if (!(sizereg & DDR_SIZE_ENABLED)) { 377 seq_printf(seq, "[%d] disabled\n", i); 378 continue; 379 } 380 381 base = ((u64)basereg & DDR_BASE_CS_HIGH_MASK) << 32; 382 base |= basereg & DDR_BASE_CS_LOW_MASK; 383 size = (sizereg | ~DDR_SIZE_MASK); 384 385 seq_printf(seq, "[%d] %016llx - %016llx : cs%d\n", 386 i, (unsigned long long)base, 387 (unsigned long long)base + size + 1, 388 (sizereg & DDR_SIZE_CS_MASK) >> DDR_SIZE_CS_SHIFT); 389 } 390 391 return 0; 392 } 393 394 /* Special function for Dove */ 395 static int mvebu_sdram_debug_show_dove(struct mvebu_mbus_state *mbus, 396 struct seq_file *seq, void *v) 397 { 398 int i; 399 400 for (i = 0; i < 2; i++) { 401 u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i)); 402 u64 base; 403 u32 size; 404 405 if (!(map & 1)) { 406 seq_printf(seq, "[%d] disabled\n", i); 407 continue; 408 } 409 410 base = map & 0xff800000; 411 size = 0x100000 << (((map & 0x000f0000) >> 16) - 4); 412 413 seq_printf(seq, "[%d] %016llx - %016llx : cs%d\n", 414 i, (unsigned long long)base, 415 (unsigned long long)base + size, i); 416 } 417 418 return 0; 419 } 420 421 static int mvebu_sdram_debug_show(struct seq_file *seq, void *v) 422 { 423 struct mvebu_mbus_state *mbus = &mbus_state; 424 return mbus->soc->show_cpu_target(mbus, seq, v); 425 } 426 427 static int mvebu_sdram_debug_open(struct inode *inode, struct file *file) 428 { 429 return single_open(file, mvebu_sdram_debug_show, inode->i_private); 430 } 431 432 static const struct file_operations mvebu_sdram_debug_fops = { 433 .open = mvebu_sdram_debug_open, 434 .read = seq_read, 435 .llseek = seq_lseek, 436 .release = single_release, 437 }; 438 439 static int mvebu_devs_debug_show(struct seq_file *seq, void *v) 440 { 441 struct mvebu_mbus_state *mbus = &mbus_state; 442 int win; 443 444 for (win = 0; win < mbus->soc->num_wins; win++) { 445 u64 wbase, wremap; 446 u32 wsize; 447 u8 wtarget, wattr; 448 int enabled; 449 450 mvebu_mbus_read_window(mbus, win, 451 &enabled, &wbase, &wsize, 452 &wtarget, &wattr, &wremap); 453 454 if (!enabled) { 455 seq_printf(seq, "[%02d] disabled\n", win); 456 continue; 457 } 458 459 seq_printf(seq, "[%02d] %016llx - %016llx : %04x:%04x", 460 win, (unsigned long long)wbase, 461 (unsigned long long)(wbase + wsize), wtarget, wattr); 462 463 if (!is_power_of_2(wsize) || 464 ((wbase & (u64)(wsize - 1)) != 0)) 465 seq_puts(seq, " (Invalid base/size!!)"); 466 467 if (win < mbus->soc->num_remappable_wins) { 468 seq_printf(seq, " (remap %016llx)\n", 469 (unsigned long long)wremap); 470 } else 471 seq_printf(seq, "\n"); 472 } 473 474 return 0; 475 } 476 477 static int mvebu_devs_debug_open(struct inode *inode, struct file *file) 478 { 479 return single_open(file, mvebu_devs_debug_show, inode->i_private); 480 } 481 482 static const struct file_operations mvebu_devs_debug_fops = { 483 .open = mvebu_devs_debug_open, 484 .read = seq_read, 485 .llseek = seq_lseek, 486 .release = single_release, 487 }; 488 489 /* 490 * SoC-specific functions and definitions 491 */ 492 493 static unsigned int orion_mbus_win_offset(int win) 494 { 495 return win << 4; 496 } 497 498 static unsigned int armada_370_xp_mbus_win_offset(int win) 499 { 500 /* The register layout is a bit annoying and the below code 501 * tries to cope with it. 502 * - At offset 0x0, there are the registers for the first 8 503 * windows, with 4 registers of 32 bits per window (ctrl, 504 * base, remap low, remap high) 505 * - Then at offset 0x80, there is a hole of 0x10 bytes for 506 * the internal registers base address and internal units 507 * sync barrier register. 508 * - Then at offset 0x90, there the registers for 12 509 * windows, with only 2 registers of 32 bits per window 510 * (ctrl, base). 511 */ 512 if (win < 8) 513 return win << 4; 514 else 515 return 0x90 + ((win - 8) << 3); 516 } 517 518 static unsigned int mv78xx0_mbus_win_offset(int win) 519 { 520 if (win < 8) 521 return win << 4; 522 else 523 return 0x900 + ((win - 8) << 4); 524 } 525 526 static void __init 527 mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus) 528 { 529 int i; 530 int cs; 531 532 mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; 533 534 for (i = 0, cs = 0; i < 4; i++) { 535 u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i)); 536 u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i)); 537 538 /* 539 * We only take care of entries for which the chip 540 * select is enabled, and that don't have high base 541 * address bits set (devices can only access the first 542 * 32 bits of the memory). 543 */ 544 if ((size & DDR_SIZE_ENABLED) && 545 !(base & DDR_BASE_CS_HIGH_MASK)) { 546 struct mbus_dram_window *w; 547 548 w = &mvebu_mbus_dram_info.cs[cs++]; 549 w->cs_index = i; 550 w->mbus_attr = 0xf & ~(1 << i); 551 if (mbus->hw_io_coherency) 552 w->mbus_attr |= ATTR_HW_COHERENCY; 553 w->base = base & DDR_BASE_CS_LOW_MASK; 554 w->size = (size | ~DDR_SIZE_MASK) + 1; 555 } 556 } 557 mvebu_mbus_dram_info.num_cs = cs; 558 } 559 560 static int 561 mvebu_mbus_default_save_cpu_target(struct mvebu_mbus_state *mbus, 562 u32 *store_addr) 563 { 564 int i; 565 566 for (i = 0; i < 4; i++) { 567 u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i)); 568 u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i)); 569 570 writel(mbus->sdramwins_phys_base + DDR_BASE_CS_OFF(i), 571 store_addr++); 572 writel(base, store_addr++); 573 writel(mbus->sdramwins_phys_base + DDR_SIZE_CS_OFF(i), 574 store_addr++); 575 writel(size, store_addr++); 576 } 577 578 /* We've written 16 words to the store address */ 579 return 16; 580 } 581 582 static void __init 583 mvebu_mbus_dove_setup_cpu_target(struct mvebu_mbus_state *mbus) 584 { 585 int i; 586 int cs; 587 588 mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; 589 590 for (i = 0, cs = 0; i < 2; i++) { 591 u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i)); 592 593 /* 594 * Chip select enabled? 595 */ 596 if (map & 1) { 597 struct mbus_dram_window *w; 598 599 w = &mvebu_mbus_dram_info.cs[cs++]; 600 w->cs_index = i; 601 w->mbus_attr = 0; /* CS address decoding done inside */ 602 /* the DDR controller, no need to */ 603 /* provide attributes */ 604 w->base = map & 0xff800000; 605 w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4); 606 } 607 } 608 609 mvebu_mbus_dram_info.num_cs = cs; 610 } 611 612 static int 613 mvebu_mbus_dove_save_cpu_target(struct mvebu_mbus_state *mbus, 614 u32 *store_addr) 615 { 616 int i; 617 618 for (i = 0; i < 2; i++) { 619 u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i)); 620 621 writel(mbus->sdramwins_phys_base + DOVE_DDR_BASE_CS_OFF(i), 622 store_addr++); 623 writel(map, store_addr++); 624 } 625 626 /* We've written 4 words to the store address */ 627 return 4; 628 } 629 630 int mvebu_mbus_save_cpu_target(u32 *store_addr) 631 { 632 return mbus_state.soc->save_cpu_target(&mbus_state, store_addr); 633 } 634 635 static const struct mvebu_mbus_soc_data armada_370_xp_mbus_data = { 636 .num_wins = 20, 637 .num_remappable_wins = 8, 638 .has_mbus_bridge = true, 639 .win_cfg_offset = armada_370_xp_mbus_win_offset, 640 .save_cpu_target = mvebu_mbus_default_save_cpu_target, 641 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 642 .show_cpu_target = mvebu_sdram_debug_show_orion, 643 }; 644 645 static const struct mvebu_mbus_soc_data kirkwood_mbus_data = { 646 .num_wins = 8, 647 .num_remappable_wins = 4, 648 .win_cfg_offset = orion_mbus_win_offset, 649 .save_cpu_target = mvebu_mbus_default_save_cpu_target, 650 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 651 .show_cpu_target = mvebu_sdram_debug_show_orion, 652 }; 653 654 static const struct mvebu_mbus_soc_data dove_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_dove_save_cpu_target, 659 .setup_cpu_target = mvebu_mbus_dove_setup_cpu_target, 660 .show_cpu_target = mvebu_sdram_debug_show_dove, 661 }; 662 663 /* 664 * Some variants of Orion5x have 4 remappable windows, some other have 665 * only two of them. 666 */ 667 static const struct mvebu_mbus_soc_data orion5x_4win_mbus_data = { 668 .num_wins = 8, 669 .num_remappable_wins = 4, 670 .win_cfg_offset = orion_mbus_win_offset, 671 .save_cpu_target = mvebu_mbus_default_save_cpu_target, 672 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 673 .show_cpu_target = mvebu_sdram_debug_show_orion, 674 }; 675 676 static const struct mvebu_mbus_soc_data orion5x_2win_mbus_data = { 677 .num_wins = 8, 678 .num_remappable_wins = 2, 679 .win_cfg_offset = orion_mbus_win_offset, 680 .save_cpu_target = mvebu_mbus_default_save_cpu_target, 681 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 682 .show_cpu_target = mvebu_sdram_debug_show_orion, 683 }; 684 685 static const struct mvebu_mbus_soc_data mv78xx0_mbus_data = { 686 .num_wins = 14, 687 .num_remappable_wins = 8, 688 .win_cfg_offset = mv78xx0_mbus_win_offset, 689 .save_cpu_target = mvebu_mbus_default_save_cpu_target, 690 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 691 .show_cpu_target = mvebu_sdram_debug_show_orion, 692 }; 693 694 static const struct of_device_id of_mvebu_mbus_ids[] = { 695 { .compatible = "marvell,armada370-mbus", 696 .data = &armada_370_xp_mbus_data, }, 697 { .compatible = "marvell,armadaxp-mbus", 698 .data = &armada_370_xp_mbus_data, }, 699 { .compatible = "marvell,kirkwood-mbus", 700 .data = &kirkwood_mbus_data, }, 701 { .compatible = "marvell,dove-mbus", 702 .data = &dove_mbus_data, }, 703 { .compatible = "marvell,orion5x-88f5281-mbus", 704 .data = &orion5x_4win_mbus_data, }, 705 { .compatible = "marvell,orion5x-88f5182-mbus", 706 .data = &orion5x_2win_mbus_data, }, 707 { .compatible = "marvell,orion5x-88f5181-mbus", 708 .data = &orion5x_2win_mbus_data, }, 709 { .compatible = "marvell,orion5x-88f6183-mbus", 710 .data = &orion5x_4win_mbus_data, }, 711 { .compatible = "marvell,mv78xx0-mbus", 712 .data = &mv78xx0_mbus_data, }, 713 { }, 714 }; 715 716 /* 717 * Public API of the driver 718 */ 719 int mvebu_mbus_add_window_remap_by_id(unsigned int target, 720 unsigned int attribute, 721 phys_addr_t base, size_t size, 722 phys_addr_t remap) 723 { 724 struct mvebu_mbus_state *s = &mbus_state; 725 726 if (!mvebu_mbus_window_conflicts(s, base, size, target, attribute)) { 727 pr_err("cannot add window '%x:%x', conflicts with another window\n", 728 target, attribute); 729 return -EINVAL; 730 } 731 732 return mvebu_mbus_alloc_window(s, base, size, remap, target, attribute); 733 } 734 735 int mvebu_mbus_add_window_by_id(unsigned int target, unsigned int attribute, 736 phys_addr_t base, size_t size) 737 { 738 return mvebu_mbus_add_window_remap_by_id(target, attribute, base, 739 size, MVEBU_MBUS_NO_REMAP); 740 } 741 742 int mvebu_mbus_del_window(phys_addr_t base, size_t size) 743 { 744 int win; 745 746 win = mvebu_mbus_find_window(&mbus_state, base, size); 747 if (win < 0) 748 return win; 749 750 mvebu_mbus_disable_window(&mbus_state, win); 751 return 0; 752 } 753 754 void mvebu_mbus_get_pcie_mem_aperture(struct resource *res) 755 { 756 if (!res) 757 return; 758 *res = mbus_state.pcie_mem_aperture; 759 } 760 761 void mvebu_mbus_get_pcie_io_aperture(struct resource *res) 762 { 763 if (!res) 764 return; 765 *res = mbus_state.pcie_io_aperture; 766 } 767 768 static __init int mvebu_mbus_debugfs_init(void) 769 { 770 struct mvebu_mbus_state *s = &mbus_state; 771 772 /* 773 * If no base has been initialized, doesn't make sense to 774 * register the debugfs entries. We may be on a multiplatform 775 * kernel that isn't running a Marvell EBU SoC. 776 */ 777 if (!s->mbuswins_base) 778 return 0; 779 780 s->debugfs_root = debugfs_create_dir("mvebu-mbus", NULL); 781 if (s->debugfs_root) { 782 s->debugfs_sdram = debugfs_create_file("sdram", S_IRUGO, 783 s->debugfs_root, NULL, 784 &mvebu_sdram_debug_fops); 785 s->debugfs_devs = debugfs_create_file("devices", S_IRUGO, 786 s->debugfs_root, NULL, 787 &mvebu_devs_debug_fops); 788 } 789 790 return 0; 791 } 792 fs_initcall(mvebu_mbus_debugfs_init); 793 794 static int mvebu_mbus_suspend(void) 795 { 796 struct mvebu_mbus_state *s = &mbus_state; 797 int win; 798 799 if (!s->mbusbridge_base) 800 return -ENODEV; 801 802 for (win = 0; win < s->soc->num_wins; win++) { 803 void __iomem *addr = s->mbuswins_base + 804 s->soc->win_cfg_offset(win); 805 806 s->wins[win].base = readl(addr + WIN_BASE_OFF); 807 s->wins[win].ctrl = readl(addr + WIN_CTRL_OFF); 808 809 if (win >= s->soc->num_remappable_wins) 810 continue; 811 812 s->wins[win].remap_lo = readl(addr + WIN_REMAP_LO_OFF); 813 s->wins[win].remap_hi = readl(addr + WIN_REMAP_HI_OFF); 814 } 815 816 s->mbus_bridge_ctrl = readl(s->mbusbridge_base + 817 MBUS_BRIDGE_CTRL_OFF); 818 s->mbus_bridge_base = readl(s->mbusbridge_base + 819 MBUS_BRIDGE_BASE_OFF); 820 821 return 0; 822 } 823 824 static void mvebu_mbus_resume(void) 825 { 826 struct mvebu_mbus_state *s = &mbus_state; 827 int win; 828 829 writel(s->mbus_bridge_ctrl, 830 s->mbusbridge_base + MBUS_BRIDGE_CTRL_OFF); 831 writel(s->mbus_bridge_base, 832 s->mbusbridge_base + MBUS_BRIDGE_BASE_OFF); 833 834 for (win = 0; win < s->soc->num_wins; win++) { 835 void __iomem *addr = s->mbuswins_base + 836 s->soc->win_cfg_offset(win); 837 838 writel(s->wins[win].base, addr + WIN_BASE_OFF); 839 writel(s->wins[win].ctrl, addr + WIN_CTRL_OFF); 840 841 if (win >= s->soc->num_remappable_wins) 842 continue; 843 844 writel(s->wins[win].remap_lo, addr + WIN_REMAP_LO_OFF); 845 writel(s->wins[win].remap_hi, addr + WIN_REMAP_HI_OFF); 846 } 847 } 848 849 struct syscore_ops mvebu_mbus_syscore_ops = { 850 .suspend = mvebu_mbus_suspend, 851 .resume = mvebu_mbus_resume, 852 }; 853 854 static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, 855 phys_addr_t mbuswins_phys_base, 856 size_t mbuswins_size, 857 phys_addr_t sdramwins_phys_base, 858 size_t sdramwins_size, 859 phys_addr_t mbusbridge_phys_base, 860 size_t mbusbridge_size) 861 { 862 int win; 863 864 mbus->mbuswins_base = ioremap(mbuswins_phys_base, mbuswins_size); 865 if (!mbus->mbuswins_base) 866 return -ENOMEM; 867 868 mbus->sdramwins_base = ioremap(sdramwins_phys_base, sdramwins_size); 869 if (!mbus->sdramwins_base) { 870 iounmap(mbus_state.mbuswins_base); 871 return -ENOMEM; 872 } 873 874 mbus->sdramwins_phys_base = sdramwins_phys_base; 875 876 if (mbusbridge_phys_base) { 877 mbus->mbusbridge_base = ioremap(mbusbridge_phys_base, 878 mbusbridge_size); 879 if (!mbus->mbusbridge_base) { 880 iounmap(mbus->sdramwins_base); 881 iounmap(mbus->mbuswins_base); 882 return -ENOMEM; 883 } 884 } else 885 mbus->mbusbridge_base = NULL; 886 887 for (win = 0; win < mbus->soc->num_wins; win++) 888 mvebu_mbus_disable_window(mbus, win); 889 890 mbus->soc->setup_cpu_target(mbus); 891 892 register_syscore_ops(&mvebu_mbus_syscore_ops); 893 894 return 0; 895 } 896 897 int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base, 898 size_t mbuswins_size, 899 phys_addr_t sdramwins_phys_base, 900 size_t sdramwins_size) 901 { 902 const struct of_device_id *of_id; 903 904 for (of_id = of_mvebu_mbus_ids; of_id->compatible[0]; of_id++) 905 if (!strcmp(of_id->compatible, soc)) 906 break; 907 908 if (!of_id->compatible[0]) { 909 pr_err("could not find a matching SoC family\n"); 910 return -ENODEV; 911 } 912 913 mbus_state.soc = of_id->data; 914 915 return mvebu_mbus_common_init(&mbus_state, 916 mbuswins_phys_base, 917 mbuswins_size, 918 sdramwins_phys_base, 919 sdramwins_size, 0, 0); 920 } 921 922 #ifdef CONFIG_OF 923 /* 924 * The window IDs in the ranges DT property have the following format: 925 * - bits 28 to 31: MBus custom field 926 * - bits 24 to 27: window target ID 927 * - bits 16 to 23: window attribute ID 928 * - bits 0 to 15: unused 929 */ 930 #define CUSTOM(id) (((id) & 0xF0000000) >> 24) 931 #define TARGET(id) (((id) & 0x0F000000) >> 24) 932 #define ATTR(id) (((id) & 0x00FF0000) >> 16) 933 934 static int __init mbus_dt_setup_win(struct mvebu_mbus_state *mbus, 935 u32 base, u32 size, 936 u8 target, u8 attr) 937 { 938 if (!mvebu_mbus_window_conflicts(mbus, base, size, target, attr)) { 939 pr_err("cannot add window '%04x:%04x', conflicts with another window\n", 940 target, attr); 941 return -EBUSY; 942 } 943 944 if (mvebu_mbus_alloc_window(mbus, base, size, MVEBU_MBUS_NO_REMAP, 945 target, attr)) { 946 pr_err("cannot add window '%04x:%04x', too many windows\n", 947 target, attr); 948 return -ENOMEM; 949 } 950 return 0; 951 } 952 953 static int __init 954 mbus_parse_ranges(struct device_node *node, 955 int *addr_cells, int *c_addr_cells, int *c_size_cells, 956 int *cell_count, const __be32 **ranges_start, 957 const __be32 **ranges_end) 958 { 959 const __be32 *prop; 960 int ranges_len, tuple_len; 961 962 /* Allow a node with no 'ranges' property */ 963 *ranges_start = of_get_property(node, "ranges", &ranges_len); 964 if (*ranges_start == NULL) { 965 *addr_cells = *c_addr_cells = *c_size_cells = *cell_count = 0; 966 *ranges_start = *ranges_end = NULL; 967 return 0; 968 } 969 *ranges_end = *ranges_start + ranges_len / sizeof(__be32); 970 971 *addr_cells = of_n_addr_cells(node); 972 973 prop = of_get_property(node, "#address-cells", NULL); 974 *c_addr_cells = be32_to_cpup(prop); 975 976 prop = of_get_property(node, "#size-cells", NULL); 977 *c_size_cells = be32_to_cpup(prop); 978 979 *cell_count = *addr_cells + *c_addr_cells + *c_size_cells; 980 tuple_len = (*cell_count) * sizeof(__be32); 981 982 if (ranges_len % tuple_len) { 983 pr_warn("malformed ranges entry '%s'\n", node->name); 984 return -EINVAL; 985 } 986 return 0; 987 } 988 989 static int __init mbus_dt_setup(struct mvebu_mbus_state *mbus, 990 struct device_node *np) 991 { 992 int addr_cells, c_addr_cells, c_size_cells; 993 int i, ret, cell_count; 994 const __be32 *r, *ranges_start, *ranges_end; 995 996 ret = mbus_parse_ranges(np, &addr_cells, &c_addr_cells, 997 &c_size_cells, &cell_count, 998 &ranges_start, &ranges_end); 999 if (ret < 0) 1000 return ret; 1001 1002 for (i = 0, r = ranges_start; r < ranges_end; r += cell_count, i++) { 1003 u32 windowid, base, size; 1004 u8 target, attr; 1005 1006 /* 1007 * An entry with a non-zero custom field do not 1008 * correspond to a static window, so skip it. 1009 */ 1010 windowid = of_read_number(r, 1); 1011 if (CUSTOM(windowid)) 1012 continue; 1013 1014 target = TARGET(windowid); 1015 attr = ATTR(windowid); 1016 1017 base = of_read_number(r + c_addr_cells, addr_cells); 1018 size = of_read_number(r + c_addr_cells + addr_cells, 1019 c_size_cells); 1020 ret = mbus_dt_setup_win(mbus, base, size, target, attr); 1021 if (ret < 0) 1022 return ret; 1023 } 1024 return 0; 1025 } 1026 1027 static void __init mvebu_mbus_get_pcie_resources(struct device_node *np, 1028 struct resource *mem, 1029 struct resource *io) 1030 { 1031 u32 reg[2]; 1032 int ret; 1033 1034 /* 1035 * These are optional, so we make sure that resource_size(x) will 1036 * return 0. 1037 */ 1038 memset(mem, 0, sizeof(struct resource)); 1039 mem->end = -1; 1040 memset(io, 0, sizeof(struct resource)); 1041 io->end = -1; 1042 1043 ret = of_property_read_u32_array(np, "pcie-mem-aperture", reg, ARRAY_SIZE(reg)); 1044 if (!ret) { 1045 mem->start = reg[0]; 1046 mem->end = mem->start + reg[1] - 1; 1047 mem->flags = IORESOURCE_MEM; 1048 } 1049 1050 ret = of_property_read_u32_array(np, "pcie-io-aperture", reg, ARRAY_SIZE(reg)); 1051 if (!ret) { 1052 io->start = reg[0]; 1053 io->end = io->start + reg[1] - 1; 1054 io->flags = IORESOURCE_IO; 1055 } 1056 } 1057 1058 int __init mvebu_mbus_dt_init(bool is_coherent) 1059 { 1060 struct resource mbuswins_res, sdramwins_res, mbusbridge_res; 1061 struct device_node *np, *controller; 1062 const struct of_device_id *of_id; 1063 const __be32 *prop; 1064 int ret; 1065 1066 np = of_find_matching_node_and_match(NULL, of_mvebu_mbus_ids, &of_id); 1067 if (!np) { 1068 pr_err("could not find a matching SoC family\n"); 1069 return -ENODEV; 1070 } 1071 1072 mbus_state.soc = of_id->data; 1073 1074 prop = of_get_property(np, "controller", NULL); 1075 if (!prop) { 1076 pr_err("required 'controller' property missing\n"); 1077 return -EINVAL; 1078 } 1079 1080 controller = of_find_node_by_phandle(be32_to_cpup(prop)); 1081 if (!controller) { 1082 pr_err("could not find an 'mbus-controller' node\n"); 1083 return -ENODEV; 1084 } 1085 1086 if (of_address_to_resource(controller, 0, &mbuswins_res)) { 1087 pr_err("cannot get MBUS register address\n"); 1088 return -EINVAL; 1089 } 1090 1091 if (of_address_to_resource(controller, 1, &sdramwins_res)) { 1092 pr_err("cannot get SDRAM register address\n"); 1093 return -EINVAL; 1094 } 1095 1096 /* 1097 * Set the resource to 0 so that it can be left unmapped by 1098 * mvebu_mbus_common_init() if the DT doesn't carry the 1099 * necessary information. This is needed to preserve backward 1100 * compatibility. 1101 */ 1102 memset(&mbusbridge_res, 0, sizeof(mbusbridge_res)); 1103 1104 if (mbus_state.soc->has_mbus_bridge) { 1105 if (of_address_to_resource(controller, 2, &mbusbridge_res)) 1106 pr_warn(FW_WARN "deprecated mbus-mvebu Device Tree, suspend/resume will not work\n"); 1107 } 1108 1109 mbus_state.hw_io_coherency = is_coherent; 1110 1111 /* Get optional pcie-{mem,io}-aperture properties */ 1112 mvebu_mbus_get_pcie_resources(np, &mbus_state.pcie_mem_aperture, 1113 &mbus_state.pcie_io_aperture); 1114 1115 ret = mvebu_mbus_common_init(&mbus_state, 1116 mbuswins_res.start, 1117 resource_size(&mbuswins_res), 1118 sdramwins_res.start, 1119 resource_size(&sdramwins_res), 1120 mbusbridge_res.start, 1121 resource_size(&mbusbridge_res)); 1122 if (ret) 1123 return ret; 1124 1125 /* Setup statically declared windows in the DT */ 1126 return mbus_dt_setup(&mbus_state, np); 1127 } 1128 #endif 1129