Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.14-rc6 923 lines 23 kB view raw
1/* 2 * drivers/misc/spear13xx_pcie_gadget.c 3 * 4 * Copyright (C) 2010 ST Microelectronics 5 * Pratyush Anand<pratyush.anand@st.com> 6 * 7 * This file is licensed under the terms of the GNU General Public 8 * License version 2. This program is licensed "as is" without any 9 * warranty of any kind, whether express or implied. 10 */ 11 12#include <linux/clk.h> 13#include <linux/slab.h> 14#include <linux/delay.h> 15#include <linux/io.h> 16#include <linux/interrupt.h> 17#include <linux/irq.h> 18#include <linux/kernel.h> 19#include <linux/module.h> 20#include <linux/platform_device.h> 21#include <linux/pci_regs.h> 22#include <linux/configfs.h> 23#include <mach/pcie.h> 24#include <mach/misc_regs.h> 25 26#define IN0_MEM_SIZE (200 * 1024 * 1024 - 1) 27/* In current implementation address translation is done using IN0 only. 28 * So IN1 start address and IN0 end address has been kept same 29*/ 30#define IN1_MEM_SIZE (0 * 1024 * 1024 - 1) 31#define IN_IO_SIZE (20 * 1024 * 1024 - 1) 32#define IN_CFG0_SIZE (12 * 1024 * 1024 - 1) 33#define IN_CFG1_SIZE (12 * 1024 * 1024 - 1) 34#define IN_MSG_SIZE (12 * 1024 * 1024 - 1) 35/* Keep default BAR size as 4K*/ 36/* AORAM would be mapped by default*/ 37#define INBOUND_ADDR_MASK (SPEAR13XX_SYSRAM1_SIZE - 1) 38 39#define INT_TYPE_NO_INT 0 40#define INT_TYPE_INTX 1 41#define INT_TYPE_MSI 2 42struct spear_pcie_gadget_config { 43 void __iomem *base; 44 void __iomem *va_app_base; 45 void __iomem *va_dbi_base; 46 char int_type[10]; 47 ulong requested_msi; 48 ulong configured_msi; 49 ulong bar0_size; 50 ulong bar0_rw_offset; 51 void __iomem *va_bar0_address; 52}; 53 54struct pcie_gadget_target { 55 struct configfs_subsystem subsys; 56 struct spear_pcie_gadget_config config; 57}; 58 59struct pcie_gadget_target_attr { 60 struct configfs_attribute attr; 61 ssize_t (*show)(struct spear_pcie_gadget_config *config, 62 char *buf); 63 ssize_t (*store)(struct spear_pcie_gadget_config *config, 64 const char *buf, 65 size_t count); 66}; 67 68static void enable_dbi_access(struct pcie_app_reg __iomem *app_reg) 69{ 70 /* Enable DBI access */ 71 writel(readl(&app_reg->slv_armisc) | (1 << AXI_OP_DBI_ACCESS_ID), 72 &app_reg->slv_armisc); 73 writel(readl(&app_reg->slv_awmisc) | (1 << AXI_OP_DBI_ACCESS_ID), 74 &app_reg->slv_awmisc); 75 76} 77 78static void disable_dbi_access(struct pcie_app_reg __iomem *app_reg) 79{ 80 /* disable DBI access */ 81 writel(readl(&app_reg->slv_armisc) & ~(1 << AXI_OP_DBI_ACCESS_ID), 82 &app_reg->slv_armisc); 83 writel(readl(&app_reg->slv_awmisc) & ~(1 << AXI_OP_DBI_ACCESS_ID), 84 &app_reg->slv_awmisc); 85 86} 87 88static void spear_dbi_read_reg(struct spear_pcie_gadget_config *config, 89 int where, int size, u32 *val) 90{ 91 struct pcie_app_reg __iomem *app_reg = config->va_app_base; 92 ulong va_address; 93 94 /* Enable DBI access */ 95 enable_dbi_access(app_reg); 96 97 va_address = (ulong)config->va_dbi_base + (where & ~0x3); 98 99 *val = readl(va_address); 100 101 if (size == 1) 102 *val = (*val >> (8 * (where & 3))) & 0xff; 103 else if (size == 2) 104 *val = (*val >> (8 * (where & 3))) & 0xffff; 105 106 /* Disable DBI access */ 107 disable_dbi_access(app_reg); 108} 109 110static void spear_dbi_write_reg(struct spear_pcie_gadget_config *config, 111 int where, int size, u32 val) 112{ 113 struct pcie_app_reg __iomem *app_reg = config->va_app_base; 114 ulong va_address; 115 116 /* Enable DBI access */ 117 enable_dbi_access(app_reg); 118 119 va_address = (ulong)config->va_dbi_base + (where & ~0x3); 120 121 if (size == 4) 122 writel(val, va_address); 123 else if (size == 2) 124 writew(val, va_address + (where & 2)); 125 else if (size == 1) 126 writeb(val, va_address + (where & 3)); 127 128 /* Disable DBI access */ 129 disable_dbi_access(app_reg); 130} 131 132#define PCI_FIND_CAP_TTL 48 133 134static int pci_find_own_next_cap_ttl(struct spear_pcie_gadget_config *config, 135 u32 pos, int cap, int *ttl) 136{ 137 u32 id; 138 139 while ((*ttl)--) { 140 spear_dbi_read_reg(config, pos, 1, &pos); 141 if (pos < 0x40) 142 break; 143 pos &= ~3; 144 spear_dbi_read_reg(config, pos + PCI_CAP_LIST_ID, 1, &id); 145 if (id == 0xff) 146 break; 147 if (id == cap) 148 return pos; 149 pos += PCI_CAP_LIST_NEXT; 150 } 151 return 0; 152} 153 154static int pci_find_own_next_cap(struct spear_pcie_gadget_config *config, 155 u32 pos, int cap) 156{ 157 int ttl = PCI_FIND_CAP_TTL; 158 159 return pci_find_own_next_cap_ttl(config, pos, cap, &ttl); 160} 161 162static int pci_find_own_cap_start(struct spear_pcie_gadget_config *config, 163 u8 hdr_type) 164{ 165 u32 status; 166 167 spear_dbi_read_reg(config, PCI_STATUS, 2, &status); 168 if (!(status & PCI_STATUS_CAP_LIST)) 169 return 0; 170 171 switch (hdr_type) { 172 case PCI_HEADER_TYPE_NORMAL: 173 case PCI_HEADER_TYPE_BRIDGE: 174 return PCI_CAPABILITY_LIST; 175 case PCI_HEADER_TYPE_CARDBUS: 176 return PCI_CB_CAPABILITY_LIST; 177 default: 178 return 0; 179 } 180 181 return 0; 182} 183 184/* 185 * Tell if a device supports a given PCI capability. 186 * Returns the address of the requested capability structure within the 187 * device's PCI configuration space or 0 in case the device does not 188 * support it. Possible values for @cap: 189 * 190 * %PCI_CAP_ID_PM Power Management 191 * %PCI_CAP_ID_AGP Accelerated Graphics Port 192 * %PCI_CAP_ID_VPD Vital Product Data 193 * %PCI_CAP_ID_SLOTID Slot Identification 194 * %PCI_CAP_ID_MSI Message Signalled Interrupts 195 * %PCI_CAP_ID_CHSWP CompactPCI HotSwap 196 * %PCI_CAP_ID_PCIX PCI-X 197 * %PCI_CAP_ID_EXP PCI Express 198 */ 199static int pci_find_own_capability(struct spear_pcie_gadget_config *config, 200 int cap) 201{ 202 u32 pos; 203 u32 hdr_type; 204 205 spear_dbi_read_reg(config, PCI_HEADER_TYPE, 1, &hdr_type); 206 207 pos = pci_find_own_cap_start(config, hdr_type); 208 if (pos) 209 pos = pci_find_own_next_cap(config, pos, cap); 210 211 return pos; 212} 213 214static irqreturn_t spear_pcie_gadget_irq(int irq, void *dev_id) 215{ 216 return 0; 217} 218 219/* 220 * configfs interfaces show/store functions 221 */ 222static ssize_t pcie_gadget_show_link( 223 struct spear_pcie_gadget_config *config, 224 char *buf) 225{ 226 struct pcie_app_reg __iomem *app_reg = config->va_app_base; 227 228 if (readl(&app_reg->app_status_1) & ((u32)1 << XMLH_LINK_UP_ID)) 229 return sprintf(buf, "UP"); 230 else 231 return sprintf(buf, "DOWN"); 232} 233 234static ssize_t pcie_gadget_store_link( 235 struct spear_pcie_gadget_config *config, 236 const char *buf, size_t count) 237{ 238 struct pcie_app_reg __iomem *app_reg = config->va_app_base; 239 240 if (sysfs_streq(buf, "UP")) 241 writel(readl(&app_reg->app_ctrl_0) | (1 << APP_LTSSM_ENABLE_ID), 242 &app_reg->app_ctrl_0); 243 else if (sysfs_streq(buf, "DOWN")) 244 writel(readl(&app_reg->app_ctrl_0) 245 & ~(1 << APP_LTSSM_ENABLE_ID), 246 &app_reg->app_ctrl_0); 247 else 248 return -EINVAL; 249 return count; 250} 251 252static ssize_t pcie_gadget_show_int_type( 253 struct spear_pcie_gadget_config *config, 254 char *buf) 255{ 256 return sprintf(buf, "%s", config->int_type); 257} 258 259static ssize_t pcie_gadget_store_int_type( 260 struct spear_pcie_gadget_config *config, 261 const char *buf, size_t count) 262{ 263 u32 cap, vec, flags; 264 ulong vector; 265 266 if (sysfs_streq(buf, "INTA")) 267 spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1); 268 269 else if (sysfs_streq(buf, "MSI")) { 270 vector = config->requested_msi; 271 vec = 0; 272 while (vector > 1) { 273 vector /= 2; 274 vec++; 275 } 276 spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 0); 277 cap = pci_find_own_capability(config, PCI_CAP_ID_MSI); 278 spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags); 279 flags &= ~PCI_MSI_FLAGS_QMASK; 280 flags |= vec << 1; 281 spear_dbi_write_reg(config, cap + PCI_MSI_FLAGS, 1, flags); 282 } else 283 return -EINVAL; 284 285 strcpy(config->int_type, buf); 286 287 return count; 288} 289 290static ssize_t pcie_gadget_show_no_of_msi( 291 struct spear_pcie_gadget_config *config, 292 char *buf) 293{ 294 struct pcie_app_reg __iomem *app_reg = config->va_app_base; 295 u32 cap, vec, flags; 296 ulong vector; 297 298 if ((readl(&app_reg->msg_status) & (1 << CFG_MSI_EN_ID)) 299 != (1 << CFG_MSI_EN_ID)) 300 vector = 0; 301 else { 302 cap = pci_find_own_capability(config, PCI_CAP_ID_MSI); 303 spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags); 304 flags &= ~PCI_MSI_FLAGS_QSIZE; 305 vec = flags >> 4; 306 vector = 1; 307 while (vec--) 308 vector *= 2; 309 } 310 config->configured_msi = vector; 311 312 return sprintf(buf, "%lu", vector); 313} 314 315static ssize_t pcie_gadget_store_no_of_msi( 316 struct spear_pcie_gadget_config *config, 317 const char *buf, size_t count) 318{ 319 int ret; 320 321 ret = kstrtoul(buf, 0, &config->requested_msi); 322 if (ret) 323 return ret; 324 325 if (config->requested_msi > 32) 326 config->requested_msi = 32; 327 328 return count; 329} 330 331static ssize_t pcie_gadget_store_inta( 332 struct spear_pcie_gadget_config *config, 333 const char *buf, size_t count) 334{ 335 struct pcie_app_reg __iomem *app_reg = config->va_app_base; 336 ulong en; 337 int ret; 338 339 ret = kstrtoul(buf, 0, &en); 340 if (ret) 341 return ret; 342 343 if (en) 344 writel(readl(&app_reg->app_ctrl_0) | (1 << SYS_INT_ID), 345 &app_reg->app_ctrl_0); 346 else 347 writel(readl(&app_reg->app_ctrl_0) & ~(1 << SYS_INT_ID), 348 &app_reg->app_ctrl_0); 349 350 return count; 351} 352 353static ssize_t pcie_gadget_store_send_msi( 354 struct spear_pcie_gadget_config *config, 355 const char *buf, size_t count) 356{ 357 struct pcie_app_reg __iomem *app_reg = config->va_app_base; 358 ulong vector; 359 u32 ven_msi; 360 int ret; 361 362 ret = kstrtoul(buf, 0, &vector); 363 if (ret) 364 return ret; 365 366 if (!config->configured_msi) 367 return -EINVAL; 368 369 if (vector >= config->configured_msi) 370 return -EINVAL; 371 372 ven_msi = readl(&app_reg->ven_msi_1); 373 ven_msi &= ~VEN_MSI_FUN_NUM_MASK; 374 ven_msi |= 0 << VEN_MSI_FUN_NUM_ID; 375 ven_msi &= ~VEN_MSI_TC_MASK; 376 ven_msi |= 0 << VEN_MSI_TC_ID; 377 ven_msi &= ~VEN_MSI_VECTOR_MASK; 378 ven_msi |= vector << VEN_MSI_VECTOR_ID; 379 380 /* generating interrupt for msi vector */ 381 ven_msi |= VEN_MSI_REQ_EN; 382 writel(ven_msi, &app_reg->ven_msi_1); 383 udelay(1); 384 ven_msi &= ~VEN_MSI_REQ_EN; 385 writel(ven_msi, &app_reg->ven_msi_1); 386 387 return count; 388} 389 390static ssize_t pcie_gadget_show_vendor_id( 391 struct spear_pcie_gadget_config *config, 392 char *buf) 393{ 394 u32 id; 395 396 spear_dbi_read_reg(config, PCI_VENDOR_ID, 2, &id); 397 398 return sprintf(buf, "%x", id); 399} 400 401static ssize_t pcie_gadget_store_vendor_id( 402 struct spear_pcie_gadget_config *config, 403 const char *buf, size_t count) 404{ 405 ulong id; 406 int ret; 407 408 ret = kstrtoul(buf, 0, &id); 409 if (ret) 410 return ret; 411 412 spear_dbi_write_reg(config, PCI_VENDOR_ID, 2, id); 413 414 return count; 415} 416 417static ssize_t pcie_gadget_show_device_id( 418 struct spear_pcie_gadget_config *config, 419 char *buf) 420{ 421 u32 id; 422 423 spear_dbi_read_reg(config, PCI_DEVICE_ID, 2, &id); 424 425 return sprintf(buf, "%x", id); 426} 427 428static ssize_t pcie_gadget_store_device_id( 429 struct spear_pcie_gadget_config *config, 430 const char *buf, size_t count) 431{ 432 ulong id; 433 int ret; 434 435 ret = kstrtoul(buf, 0, &id); 436 if (ret) 437 return ret; 438 439 spear_dbi_write_reg(config, PCI_DEVICE_ID, 2, id); 440 441 return count; 442} 443 444static ssize_t pcie_gadget_show_bar0_size( 445 struct spear_pcie_gadget_config *config, 446 char *buf) 447{ 448 return sprintf(buf, "%lx", config->bar0_size); 449} 450 451static ssize_t pcie_gadget_store_bar0_size( 452 struct spear_pcie_gadget_config *config, 453 const char *buf, size_t count) 454{ 455 ulong size; 456 u32 pos, pos1; 457 u32 no_of_bit = 0; 458 int ret; 459 460 ret = kstrtoul(buf, 0, &size); 461 if (ret) 462 return ret; 463 464 /* min bar size is 256 */ 465 if (size <= 0x100) 466 size = 0x100; 467 /* max bar size is 1MB*/ 468 else if (size >= 0x100000) 469 size = 0x100000; 470 else { 471 pos = 0; 472 pos1 = 0; 473 while (pos < 21) { 474 pos = find_next_bit((ulong *)&size, 21, pos); 475 if (pos != 21) 476 pos1 = pos + 1; 477 pos++; 478 no_of_bit++; 479 } 480 if (no_of_bit == 2) 481 pos1--; 482 483 size = 1 << pos1; 484 } 485 config->bar0_size = size; 486 spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, size - 1); 487 488 return count; 489} 490 491static ssize_t pcie_gadget_show_bar0_address( 492 struct spear_pcie_gadget_config *config, 493 char *buf) 494{ 495 struct pcie_app_reg __iomem *app_reg = config->va_app_base; 496 497 u32 address = readl(&app_reg->pim0_mem_addr_start); 498 499 return sprintf(buf, "%x", address); 500} 501 502static ssize_t pcie_gadget_store_bar0_address( 503 struct spear_pcie_gadget_config *config, 504 const char *buf, size_t count) 505{ 506 struct pcie_app_reg __iomem *app_reg = config->va_app_base; 507 ulong address; 508 int ret; 509 510 ret = kstrtoul(buf, 0, &address); 511 if (ret) 512 return ret; 513 514 address &= ~(config->bar0_size - 1); 515 if (config->va_bar0_address) 516 iounmap(config->va_bar0_address); 517 config->va_bar0_address = ioremap(address, config->bar0_size); 518 if (!config->va_bar0_address) 519 return -ENOMEM; 520 521 writel(address, &app_reg->pim0_mem_addr_start); 522 523 return count; 524} 525 526static ssize_t pcie_gadget_show_bar0_rw_offset( 527 struct spear_pcie_gadget_config *config, 528 char *buf) 529{ 530 return sprintf(buf, "%lx", config->bar0_rw_offset); 531} 532 533static ssize_t pcie_gadget_store_bar0_rw_offset( 534 struct spear_pcie_gadget_config *config, 535 const char *buf, size_t count) 536{ 537 ulong offset; 538 int ret; 539 540 ret = kstrtoul(buf, 0, &offset); 541 if (ret) 542 return ret; 543 544 if (offset % 4) 545 return -EINVAL; 546 547 config->bar0_rw_offset = offset; 548 549 return count; 550} 551 552static ssize_t pcie_gadget_show_bar0_data( 553 struct spear_pcie_gadget_config *config, 554 char *buf) 555{ 556 ulong data; 557 558 if (!config->va_bar0_address) 559 return -ENOMEM; 560 561 data = readl((ulong)config->va_bar0_address + config->bar0_rw_offset); 562 563 return sprintf(buf, "%lx", data); 564} 565 566static ssize_t pcie_gadget_store_bar0_data( 567 struct spear_pcie_gadget_config *config, 568 const char *buf, size_t count) 569{ 570 ulong data; 571 int ret; 572 573 ret = kstrtoul(buf, 0, &data); 574 if (ret) 575 return ret; 576 577 if (!config->va_bar0_address) 578 return -ENOMEM; 579 580 writel(data, (ulong)config->va_bar0_address + config->bar0_rw_offset); 581 582 return count; 583} 584 585/* 586 * Attribute definitions. 587 */ 588 589#define PCIE_GADGET_TARGET_ATTR_RO(_name) \ 590static struct pcie_gadget_target_attr pcie_gadget_target_##_name = \ 591 __CONFIGFS_ATTR(_name, S_IRUGO, pcie_gadget_show_##_name, NULL) 592 593#define PCIE_GADGET_TARGET_ATTR_WO(_name) \ 594static struct pcie_gadget_target_attr pcie_gadget_target_##_name = \ 595 __CONFIGFS_ATTR(_name, S_IWUSR, NULL, pcie_gadget_store_##_name) 596 597#define PCIE_GADGET_TARGET_ATTR_RW(_name) \ 598static struct pcie_gadget_target_attr pcie_gadget_target_##_name = \ 599 __CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, pcie_gadget_show_##_name, \ 600 pcie_gadget_store_##_name) 601PCIE_GADGET_TARGET_ATTR_RW(link); 602PCIE_GADGET_TARGET_ATTR_RW(int_type); 603PCIE_GADGET_TARGET_ATTR_RW(no_of_msi); 604PCIE_GADGET_TARGET_ATTR_WO(inta); 605PCIE_GADGET_TARGET_ATTR_WO(send_msi); 606PCIE_GADGET_TARGET_ATTR_RW(vendor_id); 607PCIE_GADGET_TARGET_ATTR_RW(device_id); 608PCIE_GADGET_TARGET_ATTR_RW(bar0_size); 609PCIE_GADGET_TARGET_ATTR_RW(bar0_address); 610PCIE_GADGET_TARGET_ATTR_RW(bar0_rw_offset); 611PCIE_GADGET_TARGET_ATTR_RW(bar0_data); 612 613static struct configfs_attribute *pcie_gadget_target_attrs[] = { 614 &pcie_gadget_target_link.attr, 615 &pcie_gadget_target_int_type.attr, 616 &pcie_gadget_target_no_of_msi.attr, 617 &pcie_gadget_target_inta.attr, 618 &pcie_gadget_target_send_msi.attr, 619 &pcie_gadget_target_vendor_id.attr, 620 &pcie_gadget_target_device_id.attr, 621 &pcie_gadget_target_bar0_size.attr, 622 &pcie_gadget_target_bar0_address.attr, 623 &pcie_gadget_target_bar0_rw_offset.attr, 624 &pcie_gadget_target_bar0_data.attr, 625 NULL, 626}; 627 628static struct pcie_gadget_target *to_target(struct config_item *item) 629{ 630 return item ? 631 container_of(to_configfs_subsystem(to_config_group(item)), 632 struct pcie_gadget_target, subsys) : NULL; 633} 634 635/* 636 * Item operations and type for pcie_gadget_target. 637 */ 638 639static ssize_t pcie_gadget_target_attr_show(struct config_item *item, 640 struct configfs_attribute *attr, 641 char *buf) 642{ 643 ssize_t ret = -EINVAL; 644 struct pcie_gadget_target *target = to_target(item); 645 struct pcie_gadget_target_attr *t_attr = 646 container_of(attr, struct pcie_gadget_target_attr, attr); 647 648 if (t_attr->show) 649 ret = t_attr->show(&target->config, buf); 650 return ret; 651} 652 653static ssize_t pcie_gadget_target_attr_store(struct config_item *item, 654 struct configfs_attribute *attr, 655 const char *buf, 656 size_t count) 657{ 658 ssize_t ret = -EINVAL; 659 struct pcie_gadget_target *target = to_target(item); 660 struct pcie_gadget_target_attr *t_attr = 661 container_of(attr, struct pcie_gadget_target_attr, attr); 662 663 if (t_attr->store) 664 ret = t_attr->store(&target->config, buf, count); 665 return ret; 666} 667 668static struct configfs_item_operations pcie_gadget_target_item_ops = { 669 .show_attribute = pcie_gadget_target_attr_show, 670 .store_attribute = pcie_gadget_target_attr_store, 671}; 672 673static struct config_item_type pcie_gadget_target_type = { 674 .ct_attrs = pcie_gadget_target_attrs, 675 .ct_item_ops = &pcie_gadget_target_item_ops, 676 .ct_owner = THIS_MODULE, 677}; 678 679static void spear13xx_pcie_device_init(struct spear_pcie_gadget_config *config) 680{ 681 struct pcie_app_reg __iomem *app_reg = config->va_app_base; 682 683 /*setup registers for outbound translation */ 684 685 writel(config->base, &app_reg->in0_mem_addr_start); 686 writel(app_reg->in0_mem_addr_start + IN0_MEM_SIZE, 687 &app_reg->in0_mem_addr_limit); 688 writel(app_reg->in0_mem_addr_limit + 1, &app_reg->in1_mem_addr_start); 689 writel(app_reg->in1_mem_addr_start + IN1_MEM_SIZE, 690 &app_reg->in1_mem_addr_limit); 691 writel(app_reg->in1_mem_addr_limit + 1, &app_reg->in_io_addr_start); 692 writel(app_reg->in_io_addr_start + IN_IO_SIZE, 693 &app_reg->in_io_addr_limit); 694 writel(app_reg->in_io_addr_limit + 1, &app_reg->in_cfg0_addr_start); 695 writel(app_reg->in_cfg0_addr_start + IN_CFG0_SIZE, 696 &app_reg->in_cfg0_addr_limit); 697 writel(app_reg->in_cfg0_addr_limit + 1, &app_reg->in_cfg1_addr_start); 698 writel(app_reg->in_cfg1_addr_start + IN_CFG1_SIZE, 699 &app_reg->in_cfg1_addr_limit); 700 writel(app_reg->in_cfg1_addr_limit + 1, &app_reg->in_msg_addr_start); 701 writel(app_reg->in_msg_addr_start + IN_MSG_SIZE, 702 &app_reg->in_msg_addr_limit); 703 704 writel(app_reg->in0_mem_addr_start, &app_reg->pom0_mem_addr_start); 705 writel(app_reg->in1_mem_addr_start, &app_reg->pom1_mem_addr_start); 706 writel(app_reg->in_io_addr_start, &app_reg->pom_io_addr_start); 707 708 /*setup registers for inbound translation */ 709 710 /* Keep AORAM mapped at BAR0 as default */ 711 config->bar0_size = INBOUND_ADDR_MASK + 1; 712 spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, INBOUND_ADDR_MASK); 713 spear_dbi_write_reg(config, PCI_BASE_ADDRESS_0, 4, 0xC); 714 config->va_bar0_address = ioremap(SPEAR13XX_SYSRAM1_BASE, 715 config->bar0_size); 716 717 writel(SPEAR13XX_SYSRAM1_BASE, &app_reg->pim0_mem_addr_start); 718 writel(0, &app_reg->pim1_mem_addr_start); 719 writel(INBOUND_ADDR_MASK + 1, &app_reg->mem0_addr_offset_limit); 720 721 writel(0x0, &app_reg->pim_io_addr_start); 722 writel(0x0, &app_reg->pim_io_addr_start); 723 writel(0x0, &app_reg->pim_rom_addr_start); 724 725 writel(DEVICE_TYPE_EP | (1 << MISCTRL_EN_ID) 726 | ((u32)1 << REG_TRANSLATION_ENABLE), 727 &app_reg->app_ctrl_0); 728 /* disable all rx interrupts */ 729 writel(0, &app_reg->int_mask); 730 731 /* Select INTA as default*/ 732 spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1); 733} 734 735static int spear_pcie_gadget_probe(struct platform_device *pdev) 736{ 737 struct resource *res0, *res1; 738 unsigned int status = 0; 739 int irq; 740 struct clk *clk; 741 static struct pcie_gadget_target *target; 742 struct spear_pcie_gadget_config *config; 743 struct config_item *cg_item; 744 struct configfs_subsystem *subsys; 745 746 /* get resource for application registers*/ 747 748 res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); 749 if (!res0) { 750 dev_err(&pdev->dev, "no resource defined\n"); 751 return -EBUSY; 752 } 753 if (!request_mem_region(res0->start, resource_size(res0), 754 pdev->name)) { 755 dev_err(&pdev->dev, "pcie gadget region already claimed\n"); 756 return -EBUSY; 757 } 758 /* get resource for dbi registers*/ 759 760 res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); 761 if (!res1) { 762 dev_err(&pdev->dev, "no resource defined\n"); 763 goto err_rel_res0; 764 } 765 if (!request_mem_region(res1->start, resource_size(res1), 766 pdev->name)) { 767 dev_err(&pdev->dev, "pcie gadget region already claimed\n"); 768 goto err_rel_res0; 769 } 770 771 target = kzalloc(sizeof(*target), GFP_KERNEL); 772 if (!target) { 773 dev_err(&pdev->dev, "out of memory\n"); 774 status = -ENOMEM; 775 goto err_rel_res; 776 } 777 778 cg_item = &target->subsys.su_group.cg_item; 779 sprintf(cg_item->ci_namebuf, "pcie_gadget.%d", pdev->id); 780 cg_item->ci_type = &pcie_gadget_target_type; 781 config = &target->config; 782 config->va_app_base = (void __iomem *)ioremap(res0->start, 783 resource_size(res0)); 784 if (!config->va_app_base) { 785 dev_err(&pdev->dev, "ioremap fail\n"); 786 status = -ENOMEM; 787 goto err_kzalloc; 788 } 789 790 config->base = (void __iomem *)res1->start; 791 792 config->va_dbi_base = (void __iomem *)ioremap(res1->start, 793 resource_size(res1)); 794 if (!config->va_dbi_base) { 795 dev_err(&pdev->dev, "ioremap fail\n"); 796 status = -ENOMEM; 797 goto err_iounmap_app; 798 } 799 800 platform_set_drvdata(pdev, target); 801 802 irq = platform_get_irq(pdev, 0); 803 if (irq < 0) { 804 dev_err(&pdev->dev, "no update irq?\n"); 805 status = irq; 806 goto err_iounmap; 807 } 808 809 status = request_irq(irq, spear_pcie_gadget_irq, 0, pdev->name, NULL); 810 if (status) { 811 dev_err(&pdev->dev, 812 "pcie gadget interrupt IRQ%d already claimed\n", irq); 813 goto err_iounmap; 814 } 815 816 /* Register configfs hooks */ 817 subsys = &target->subsys; 818 config_group_init(&subsys->su_group); 819 mutex_init(&subsys->su_mutex); 820 status = configfs_register_subsystem(subsys); 821 if (status) 822 goto err_irq; 823 824 /* 825 * init basic pcie application registers 826 * do not enable clock if it is PCIE0.Ideally , all controller should 827 * have been independent from others with respect to clock. But PCIE1 828 * and 2 depends on PCIE0.So PCIE0 clk is provided during board init. 829 */ 830 if (pdev->id == 1) { 831 /* 832 * Ideally CFG Clock should have been also enabled here. But 833 * it is done currently during board init routne 834 */ 835 clk = clk_get_sys("pcie1", NULL); 836 if (IS_ERR(clk)) { 837 pr_err("%s:couldn't get clk for pcie1\n", __func__); 838 status = PTR_ERR(clk); 839 goto err_irq; 840 } 841 status = clk_enable(clk); 842 if (status) { 843 pr_err("%s:couldn't enable clk for pcie1\n", __func__); 844 goto err_irq; 845 } 846 } else if (pdev->id == 2) { 847 /* 848 * Ideally CFG Clock should have been also enabled here. But 849 * it is done currently during board init routne 850 */ 851 clk = clk_get_sys("pcie2", NULL); 852 if (IS_ERR(clk)) { 853 pr_err("%s:couldn't get clk for pcie2\n", __func__); 854 status = PTR_ERR(clk); 855 goto err_irq; 856 } 857 status = clk_enable(clk); 858 if (status) { 859 pr_err("%s:couldn't enable clk for pcie2\n", __func__); 860 goto err_irq; 861 } 862 } 863 spear13xx_pcie_device_init(config); 864 865 return 0; 866err_irq: 867 free_irq(irq, NULL); 868err_iounmap: 869 iounmap(config->va_dbi_base); 870err_iounmap_app: 871 iounmap(config->va_app_base); 872err_kzalloc: 873 kfree(target); 874err_rel_res: 875 release_mem_region(res1->start, resource_size(res1)); 876err_rel_res0: 877 release_mem_region(res0->start, resource_size(res0)); 878 return status; 879} 880 881static int spear_pcie_gadget_remove(struct platform_device *pdev) 882{ 883 struct resource *res0, *res1; 884 static struct pcie_gadget_target *target; 885 struct spear_pcie_gadget_config *config; 886 int irq; 887 888 res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); 889 res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); 890 irq = platform_get_irq(pdev, 0); 891 target = platform_get_drvdata(pdev); 892 config = &target->config; 893 894 free_irq(irq, NULL); 895 iounmap(config->va_dbi_base); 896 iounmap(config->va_app_base); 897 release_mem_region(res1->start, resource_size(res1)); 898 release_mem_region(res0->start, resource_size(res0)); 899 configfs_unregister_subsystem(&target->subsys); 900 kfree(target); 901 902 return 0; 903} 904 905static void spear_pcie_gadget_shutdown(struct platform_device *pdev) 906{ 907} 908 909static struct platform_driver spear_pcie_gadget_driver = { 910 .probe = spear_pcie_gadget_probe, 911 .remove = spear_pcie_gadget_remove, 912 .shutdown = spear_pcie_gadget_shutdown, 913 .driver = { 914 .name = "pcie-gadget-spear", 915 .bus = &platform_bus_type 916 }, 917}; 918 919module_platform_driver(spear_pcie_gadget_driver); 920 921MODULE_ALIAS("platform:pcie-gadget-spear"); 922MODULE_AUTHOR("Pratyush Anand"); 923MODULE_LICENSE("GPL");