From: Palani <palaniappan.ramanat...@intel.com> The SRIO mport driver is modified to support local and remote configuration register access, Direct IO and Messaging transactions for all the Axxia chipset (55xx and 56xx) variants.
Signed-off-by: Palani <palaniappan.ramanat...@intel.com> --- arch/arm/mach-axxia/include/mach/rio.h | 18 ----- arch/arm/mach-axxia/rapidio.c | 47 ------------- arch/arm64/Kconfig | 9 +++ arch/arm64/boot/dts/intel/axm5616-victoria.dts | 10 +++ arch/arm64/boot/dts/intel/axm56xx.dtsi | 32 +++++++++ drivers/rapidio/devices/lsi/axxia-rio-irq.c | 86 ++++++++++++++++++++---- drivers/rapidio/devices/lsi/axxia-rio-sysfs.c | 4 +- drivers/rapidio/devices/lsi/axxia-rio.c | 93 +++++++++++++++++++++++++- drivers/rapidio/devices/lsi/axxia-rio.h | 18 ++++- 9 files changed, 235 insertions(+), 82 deletions(-) diff --git a/arch/arm/mach-axxia/include/mach/rio.h b/arch/arm/mach-axxia/include/mach/rio.h index a004480..d4eef10 100644 --- a/arch/arm/mach-axxia/include/mach/rio.h +++ b/arch/arm/mach-axxia/include/mach/rio.h @@ -20,24 +20,6 @@ */ #ifndef __ASM__ARCH_AXXIA_RAPIDIO_H #define __ASM__ARCH_AXXIA_RAPIDIO_H -#include <linux/io.h> - -#define IN_SRIO8(a, v, ec) do { \ - v = ioread8(a); ec = 0; \ - } while (0) -#define IN_SRIO16(a, v, ec) do { \ - v = ioread16be(a); ec = 0; \ - } while (0) -#define IN_SRIO32(a, v, ec) do { \ - v = ioread32be(a); ec = 0; \ - } while (0) - -#define OUT_SRIO8(a, v) iowrite8(v, a) -#define OUT_SRIO16(a, v) iowrite16be(v, a) -#define OUT_SRIO32(a, v) iowrite32be(v, a) - -int axxia_rapidio_board_init(struct platform_device *dev, int devnum, - int *portndx); int axxia_rapidio_init(void); diff --git a/arch/arm/mach-axxia/rapidio.c b/arch/arm/mach-axxia/rapidio.c index 2cf7c7f..15106b9 100644 --- a/arch/arm/mach-axxia/rapidio.c +++ b/arch/arm/mach-axxia/rapidio.c @@ -36,53 +36,6 @@ #include <mach/rio.h> /** - * axxia_rapidio_board_init - - * Perform board-/controller-specific initialization to support - * use of RapidIO busses - * - * @dev: [IN] RIO platform device - * @ndx: [IN] Which instance of SRIOC driver needs support - * @port_ndx: [OUT] Which port to use for the specified controller - * - * Returns 0 on success or an error code. - */ - -int -axxia_rapidio_board_init(struct platform_device *dev, int dev_num, int *port_ndx) -{ - /* Reset the RIO port id to zero for this device */ - void __iomem *gpreg_base = ioremap(0x2010094000, 0x1000); - unsigned long reg = 0; - - if (gpreg_base == NULL) - return -EFAULT; - - reg = inl((unsigned long int)(gpreg_base + 0x60)); - - reg &= ~(0xf << (dev_num * 4)); - - outl_p(reg, (unsigned long int)(gpreg_base + 0x60)); - - (*port_ndx) = 0; - - /* Verify that this device is actually enabled */ - if (NULL != - of_find_compatible_node(NULL, NULL, "lsi,axm5500-amarillo")) { - ncr_read(NCP_REGION_ID(0x115, 0), 0x23c, 4, ®); - - if ((reg & (1 << (21+(dev_num*4)))) == 0) { - dev_dbg(&dev->dev, "%s: SRIO%d link not ready\n", - dev->dev.of_node->full_name, dev_num); - return -ENXIO; - } - } - - iounmap(gpreg_base); - - return 0; -} - -/** * axxia_rio_fault - * Intercept SRIO bus faults due to unimplemented register locations. * Return 0 to keep 'reads' alive. diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 28a059c..41e5311 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -290,6 +290,15 @@ source "drivers/pci/Kconfig" source "drivers/pci/pcie/Kconfig" source "drivers/pci/hotplug/Kconfig" +config RAPIDIO + bool "RapidIO support" + depends on PCI + help + If you say Y here, the kernel will include drivers and + infrastructure code to support RapidIO interconnect devices. + +source "drivers/rapidio/Kconfig" + endmenu menu "Kernel Features" diff --git a/arch/arm64/boot/dts/intel/axm5616-victoria.dts b/arch/arm64/boot/dts/intel/axm5616-victoria.dts index 0050290..1cebf7a 100644 --- a/arch/arm64/boot/dts/intel/axm5616-victoria.dts +++ b/arch/arm64/boot/dts/intel/axm5616-victoria.dts @@ -168,6 +168,16 @@ status = "okay"; }; +&rio0 { + + status = "okay"; +}; + +&rio1 { + + status = "okay"; +}; + &usb0 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/intel/axm56xx.dtsi b/arch/arm64/boot/dts/intel/axm56xx.dtsi index 413551d..ad6034d 100644 --- a/arch/arm64/boot/dts/intel/axm56xx.dtsi +++ b/arch/arm64/boot/dts/intel/axm56xx.dtsi @@ -335,6 +335,38 @@ status = "disabled"; }; + rio0: rapidio@0xb000000000 { + index = <0>; + compatible = "intel, axxia-rapidio"; + device_type = "rapidio"; + reg = <0xa0 0x00020000 0 0x00001000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x00b0 0x00000000 0x0 0x40000000>; + linkdown-reset = <0x0200 0x100 0x00a0 0x10000000 + 0x0 0x000010000>; + interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>; + outb-dmes = <2 0x00000003 1 0x00000000>; + enable_ds = <1>; + status = "disabled"; + }; + + rio1: rapidio@0xb800000000 { + index = <1>; + compatible = "intel, axxia-rapidio"; + device_type = "rapidio"; + reg = <0xa0 0x00030000 0 0x00001000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x00b8 0x00000000 0x0 0x40000000>; + linkdown-reset = <0x0200 0x100 0x00a0 0x10000000 + 0x0 0x000010000>; + interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>; + outb-dmes = <2 0x00000003 1 0x00000000>; + enable_ds = <1>; + status = "disabled"; + }; + amba { compatible = "arm,amba-bus"; #address-cells = <2>; diff --git a/drivers/rapidio/devices/lsi/axxia-rio-irq.c b/drivers/rapidio/devices/lsi/axxia-rio-irq.c index 624e090..d7c7880 100644 --- a/drivers/rapidio/devices/lsi/axxia-rio-irq.c +++ b/drivers/rapidio/devices/lsi/axxia-rio-irq.c @@ -1256,6 +1256,10 @@ static int alloc_ob_dme_shared(struct rio_priv *priv, dw0 = 0; if (!priv->intern_msg_desc) { dw1 = 0; + if (axxia_rio_is_x9()) { + dw0 = (u32)(desc->msg_phys >> 38) & 0x3; + dw0 = (u32)(dw0 << 12); + } dw2 = (u32)(desc->msg_phys >> 8) & 0x3fffffff; *((u32 *)DESC_TABLE_W0_MEM(me, i)) = dw0; *((u32 *)DESC_TABLE_W1_MEM(me, i)) = dw1; @@ -1288,8 +1292,17 @@ static int alloc_ob_dme_shared(struct rio_priv *priv, desc_chn_start = (uintptr_t)virt_to_phys(me->descriptors); + if (axxia_rio_is_x9()) { + dw0 = *((u32 *)DESC_TABLE_W0_MEM(me, i)); + dw0 |= DME_DESC_DW0_NXT_DESC_VALID; + dw3 = (u32)(desc_chn_start >> 38) & 0x3; + dw0 |= (dw3 << 14); + } dw2 = *((u32 *)DESC_TABLE_W2_MEM(me, i)); - dw2 |= (desc_chn_start >> 4) & 0xc0000000; + if (axxia_rio_is_x9()) + dw2 |= (desc_chn_start >> 6) & 0xc0000000; + else + dw2 |= (desc_chn_start >> 4) & 0xc0000000; dw3 = desc_chn_start >> 4; *((u32 *)DESC_TABLE_W0_MEM(me, i)) = dw0; *((u32 *)DESC_TABLE_W2_MEM(me, i)) = dw2; @@ -1804,7 +1817,13 @@ static int open_inb_mbox(struct rio_mport *mport, void *dev_id, /* Reference AXX5500 Peripheral Subsystem * Multicore Reference Manual, January 2013, * Chapter 5, p. 584 */ - dw1 |= 0; + if (axxia_rio_is_x9()) { + dw2 = (u32)(desc->msg_phys >> 8) & + 0xc0000000; + dw2 = (dw2 >> 9); + dw1 |= dw2; + } else + dw1 |= 0; dw2 = (u32)(desc->msg_phys >> 8) & 0x3fffffff; *((u32 *)DESC_TABLE_W0_MEM(me, i)) = dw0; @@ -1840,11 +1859,21 @@ static int open_inb_mbox(struct rio_mport *mport, void *dev_id, if (!priv->intern_msg_desc) { desc_chn_start = (uintptr_t)virt_to_phys(me->descriptors); - + if (axxia_rio_is_x9()) { + dw1 = *((u32 *)DESC_TABLE_W1_MEM(me, i)); + dw2 = (u32)(desc_chn_start >> 8) & 0xc0000000; + dw2 = (u32)(dw2 >> 11); + dw1 |= dw2; + } dw2 = *((u32 *)DESC_TABLE_W2_MEM(me, i)); - dw2 |= (desc_chn_start >> 4) & 0xc0000000; + if (axxia_rio_is_x9()) + dw2 |= (desc_chn_start >> 6) & 0xc0000000; + else + dw2 |= (desc_chn_start >> 4) & 0xc0000000; dw3 = desc_chn_start >> 4; *((u32 *)DESC_TABLE_W0_MEM(me, i)) = dw0; + if (axxia_rio_is_x9()) + *((u32 *)DESC_TABLE_W1_MEM(me, i)) = dw1; *((u32 *)DESC_TABLE_W2_MEM(me, i)) = dw2; *((u32 *)DESC_TABLE_W3_MEM(me, i)) = dw3; } else { @@ -1875,6 +1904,8 @@ static int open_inb_mbox(struct rio_mport *mport, void *dev_id, DME_WAKEUP | DME_ENABLE; dme_ctrl |= (u32)((desc_chn_start >> 6) & 0xc0000000); + if (axxia_rio_is_x9()) + dme_ctrl |= (u32)((desc_chn_start >> 12) & 0x0c000000); desc_addr = (u32)desc_chn_start >> 4; me->dme_ctrl = dme_ctrl; @@ -2290,7 +2321,7 @@ int axxia_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, struct rio_tx_mbox *mb = priv->ob_mbox[mbox_dest]; struct rio_msg_dme *me; struct rio_msg_desc *desc; - u32 dw2_r, dw2; + u32 dw2_r, dw2, dw0_r = 0, dw0_tmp; u32 idx; u32 seg; u32 lock = 0; @@ -2313,8 +2344,8 @@ int axxia_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, /* Copy and clear rest of buffer */ - if ((u32)buffer > PAGE_OFFSET) { - if ((u32)buffer & 0xFF) { + if ((uintptr_t)buffer > PAGE_OFFSET) { + if ((uintptr_t)buffer & 0xFF) { if (unlikely(desc->msg_virt == NULL)) { rc = -ENXIO; goto done; @@ -2351,12 +2382,25 @@ int axxia_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, DME_DESC_DW1_MBOX(mbox_dest) | DME_DESC_DW1_LETTER(letter); idx = me->write_idx; + if (axxia_rio_is_x9()) + dw0_r = *((u32 *)DESC_TABLE_W0_MEM(me, idx)); dw2_r = *((u32 *)DESC_TABLE_W2_MEM(me, idx)); - if (cp) + if (cp) { + if (axxia_rio_is_x9()) { + dw0_tmp = (u32)(desc->msg_phys >> 38) & 0x3; + dw0 |= (dw0_tmp << 12); + } dw2 = (u32)(desc->msg_phys >> 8) & 0x3fffffff; - else + } else { + if (axxia_rio_is_x9()) { + dw0_tmp = (u32)(virt_to_phys(buffer) >> 38) & 0x3; + dw0 |= (dw0_tmp << 12); + } dw2 = (u32)(virt_to_phys(buffer) >> 8) & 0x3fffffff; + } dw2 = (dw2_r & 0xc0000000) | dw2; + if (axxia_rio_is_x9()) + dw0 |= (dw0_r & 0x0000c000); me->write_idx = (me->write_idx+1) & (me->entries - 1); *((u32 *)DESC_TABLE_W2_MEM(me, idx)) = dw2; *((u32 *)DESC_TABLE_W1_MEM(me, idx)) = dw1; @@ -2490,7 +2534,7 @@ int axxia_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf) int rc = 0; struct rio_msg_dme *me; struct rio_msg_desc *desc; - u32 dw0, dw2, dw2_r; + u32 dw0, dw2, dw2_r, dw1 = 0, dw1_r; mb = (priv->ib_mbox[mbox]); if (!mb) @@ -2511,17 +2555,35 @@ int axxia_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf) goto busy; } mb->virt_buffer[0][me->write_idx] = buf; - if (!((u32)buf & 0xFF)) { + if (!((uintptr_t)buf & 0xFF)) { + if (axxia_rio_is_x9()) { + dw1_r = *((u32 *)DESC_TABLE_W1_MEM(me, me->write_idx)); + dw2 = (u32)(virt_to_phys(buf) >> 8) & 0xc0000000; + dw2 = (dw2 >> 9); + dw1 = dw1_r & 0xff9fffff; + dw1 |= dw2; + } dw2_r = *((u32 *)DESC_TABLE_W2_MEM(me, me->write_idx)); dw2 = (u32)(virt_to_phys(buf) >> 8) & 0x3fffffff; dw2 = (dw2_r & 0xc0000000) | dw2; *((u32 *)DESC_TABLE_W2_MEM(me, me->write_idx)) = dw2; + if (axxia_rio_is_x9()) + *((u32 *)DESC_TABLE_W1_MEM(me, me->write_idx)) = dw1; } else { desc = &me->desc[me->write_idx]; + if (axxia_rio_is_x9()) { + dw1_r = *((u32 *)DESC_TABLE_W1_MEM(me, me->write_idx)); + dw2 = (u32)(desc->msg_phys >> 8) & 0xc0000000; + dw2 = (dw2 >> 9); + dw1 = dw1_r & 0xff9fffff; + dw1 |= dw2; + } dw2_r = *((u32 *)DESC_TABLE_W2_MEM(me, me->write_idx)); dw2 = (u32)(desc->msg_phys >> 8) & 0x3fffffff; dw2 = (dw2_r & 0xc0000000) | dw2; *((u32 *)DESC_TABLE_W2_MEM(me, me->write_idx)) = dw2; + if (axxia_rio_is_x9()) + *((u32 *)DESC_TABLE_W1_MEM(me, me->write_idx)) = dw1; } AXXIA_RIO_SYSMEM_BARRIER(); @@ -2601,7 +2663,7 @@ void *axxia_get_inb_message(struct rio_mport *mport, int mbox, int letter, goto err; } - if ((u32)buf & 0xFF) { + if ((uintptr_t)buf & 0xFF) { AXXIA_RIO_SYSMEM_BARRIER(); memcpy(buf, desc->msg_virt, buf_sz); } diff --git a/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c b/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c index d2c178f..128eee68 100644 --- a/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c +++ b/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c @@ -255,8 +255,8 @@ static ssize_t axxia_rio_tmo_show(struct device *dev, str += sprintf(str, "RAB_APIO_STAT (%p)\t%8.8x\n", (void *)RAB_APIO_STAT, stat); axxia_local_config_read(priv, RIO_ESCSR(priv->port_ndx), &stat); - str += sprintf(str, "PNESCSR (%p)\t%8.8x\n", - (void *)RIO_ESCSR(priv->port_ndx), stat); + str += sprintf(str, "PNESCSR (%d)\t%8.8x\n", + RIO_ESCSR(priv->port_ndx), stat); return str - buf; } diff --git a/drivers/rapidio/devices/lsi/axxia-rio.c b/drivers/rapidio/devices/lsi/axxia-rio.c index f2fe4d4..70614e6 100644 --- a/drivers/rapidio/devices/lsi/axxia-rio.c +++ b/drivers/rapidio/devices/lsi/axxia-rio.c @@ -34,8 +34,8 @@ #include <linux/of_address.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/lsi-ncr.h> -#include <mach/rio.h> #include "axxia-rio.h" #include "axxia-rio-irq.h" @@ -61,6 +61,93 @@ static DEFINE_SPINLOCK(rio_io_lock); #define RIO_NWRITE 0x20 #define RIO_NWRITE_R 0x40 #define RIO_SWRITE 0x80 + +int +axxia_rio_is_x9(void) +{ + if (of_find_compatible_node(NULL, NULL, "lsi,axm5616")) + return 1; + + return 0; +} + +/** + * axxia_rapidio_board_init - + * Perform board-/controller-specific initialization to support + * use of RapidIO busses + * + * @dev: [IN] RIO platform device + * @ndx: [IN] Which instance of SRIOC driver needs support + * @port_ndx: [OUT] Which port to use for the specified controller + * + * Returns 0 on success or an error code. + */ +int +axxia_rapidio_board_init(struct platform_device *dev, int dev_num, + int *port_ndx) +{ + void __iomem *gpreg_base; + unsigned long reg0, reg1; + unsigned long reg = 0; + + if (!axxia_rio_is_x9()) { + /* Reset the RIO port id to zero for this device */ + gpreg_base = ioremap(0x2010094000, 0x1000); + if (gpreg_base == NULL) + return -EFAULT; + + reg = inl((unsigned long int)(gpreg_base + 0x60)); + + reg &= ~(0xf << (dev_num * 4)); + + outl_p(reg, (unsigned long int)(gpreg_base + 0x60)); + + (*port_ndx) = 0; + + /* Verify that this device is actually enabled */ + if (NULL != + of_find_compatible_node(NULL, NULL, "lsi,axm5500-amarillo")) { +#ifdef CONFIG_LSI_NCR + ncr_read(NCP_REGION_ID(0x115, 0), 0x23c, 4, ®); + + if ((reg & (1 << (21+(dev_num*4)))) == 0) { + dev_dbg(&dev->dev, "%s: SRIO%d link not ready\n", + dev->dev.of_node->full_name, dev_num); + return -ENXIO; + } +#endif + } + + iounmap(gpreg_base); + } else { + + ncr_read(NCP_REGION_ID(0x115, 0), 0x184, 4, ®0); + ncr_read(NCP_REGION_ID(0x115, 0), 0x18c, 4, ®1); + ncr_read(NCP_REGION_ID(0x115, 0), 0x0, 4, ®); + + dev_info(&dev->dev, "%s: 0x184 = %lx 0x18c = %lx 0x0 = %lx\n", + dev->dev.of_node->full_name, reg0, reg1, reg); + if (dev_num == 0) { + if ((reg & (1 << 3)) == 0) { + dev_emerg(&dev->dev, "%s: SRIO%d link not ready\n", + dev->dev.of_node->full_name, dev_num); + return -ENXIO; + } + return 0; + } + if (dev_num == 1) { + if ((reg & (1 << 10)) == 0) { + dev_emerg(&dev->dev, "%s: SRIO%d link not ready\n", + dev->dev.of_node->full_name, dev_num); + return -ENXIO; + } + return 0; + } + return -ENXIO; + } + return 0; +} + /** * NOTE: * @@ -629,7 +716,8 @@ static int axxia_rio_req_outb_region(struct rio_mport *mport, } /* Set base address for window on PIO side */ - wabar = AXI_BASE_HIGH(riores->start); + if (!axxia_rio_is_x9()) + wabar = AXI_BASE_HIGH(riores->start); wabar |= AXI_BASE(riores->start); __rio_local_write_config_32(mport, RAB_APIO_AMAP_ABAR(win), wabar); @@ -1772,6 +1860,7 @@ static int axxia_of_rio_rpn_probe(struct platform_device *dev) static const struct of_device_id axxia_of_rio_rpn_ids[] = { { .compatible = "axxia, rapidio-delta", }, + { .compatible = "intel, axxia-rapidio", }, { .compatible = "acp, rapidio-delta", }, {}, }; diff --git a/drivers/rapidio/devices/lsi/axxia-rio.h b/drivers/rapidio/devices/lsi/axxia-rio.h index 36c4cfa..5afd84f 100644 --- a/drivers/rapidio/devices/lsi/axxia-rio.h +++ b/drivers/rapidio/devices/lsi/axxia-rio.h @@ -23,7 +23,7 @@ #include <linux/rio_drv.h> #include <linux/interrupt.h> #include <linux/kfifo.h> - +#include <linux/io.h> #include "axxia-rio-irq.h" /* Constants, Macros, etc. */ @@ -31,6 +31,19 @@ /* Memory Barrier */ \ smp_mb() +#define IN_SRIO8(a, v, ec) do { \ + v = ioread8(a); ec = 0; \ + } while (0) +#define IN_SRIO16(a, v, ec) do { \ + v = ioread16be(a); ec = 0; \ + } while (0) +#define IN_SRIO32(a, v, ec) do { \ + v = ioread32be(a); ec = 0; \ + } while (0) + +#define OUT_SRIO8(a, v) iowrite8(v, a) +#define OUT_SRIO16(a, v) iowrite16be(v, a) +#define OUT_SRIO32(a, v) iowrite32be(v, a) /*****************************************/ /* *********** Byte Swapping *********** */ @@ -602,4 +615,7 @@ extern int axxia_rio_hotswap(struct rio_mport *mport, u8 flags); #endif /* CONFIG_RAPIDIO_HOTPLUG */ +int axxia_rio_is_x9(void); +int axxia_rapidio_board_init(struct platform_device *dev, int devnum, + int *portndx); #endif /* _AXXIA_RIO_H_ */ -- 2.7.4 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto