aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/sysdev/fsl_rio.c75
-rw-r--r--include/linux/rio.h6
2 files changed, 70 insertions, 11 deletions
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 14c106cf4aa2..935822a25030 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -21,6 +21,7 @@
21#include <linux/rio.h> 21#include <linux/rio.h>
22#include <linux/rio_drv.h> 22#include <linux/rio_drv.h>
23#include <linux/of_platform.h> 23#include <linux/of_platform.h>
24#include <linux/delay.h>
24 25
25#include <asm/io.h> 26#include <asm/io.h>
26 27
@@ -30,7 +31,12 @@
30#define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq) 31#define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq)
31 32
32#define RIO_ATMU_REGS_OFFSET 0x10c00 33#define RIO_ATMU_REGS_OFFSET 0x10c00
33#define RIO_MSG_REGS_OFFSET 0x11000 34#define RIO_P_MSG_REGS_OFFSET 0x11000
35#define RIO_S_MSG_REGS_OFFSET 0x13000
36#define RIO_ESCSR 0x158
37#define RIO_CCSR 0x15c
38#define RIO_ISR_AACR 0x10120
39#define RIO_ISR_AACR_AA 0x1 /* Accept All ID */
34#define RIO_MAINT_WIN_SIZE 0x400000 40#define RIO_MAINT_WIN_SIZE 0x400000
35#define RIO_DBELL_WIN_SIZE 0x1000 41#define RIO_DBELL_WIN_SIZE 0x1000
36 42
@@ -69,7 +75,7 @@
69 75
70struct rio_atmu_regs { 76struct rio_atmu_regs {
71 u32 rowtar; 77 u32 rowtar;
72 u32 pad1; 78 u32 rowtear;
73 u32 rowbar; 79 u32 rowbar;
74 u32 pad2; 80 u32 pad2;
75 u32 rowar; 81 u32 rowar;
@@ -95,7 +101,15 @@ struct rio_msg_regs {
95 u32 ifqdpar; 101 u32 ifqdpar;
96 u32 pad6; 102 u32 pad6;
97 u32 ifqepar; 103 u32 ifqepar;
98 u32 pad7[250]; 104 u32 pad7[226];
105 u32 odmr;
106 u32 odsr;
107 u32 res0[4];
108 u32 oddpr;
109 u32 oddatr;
110 u32 res1[3];
111 u32 odretcr;
112 u32 res2[12];
99 u32 dmr; 113 u32 dmr;
100 u32 dsr; 114 u32 dsr;
101 u32 pad8; 115 u32 pad8;
@@ -175,8 +189,22 @@ static int fsl_rio_doorbell_send(struct rio_mport *mport,
175 struct rio_priv *priv = mport->priv; 189 struct rio_priv *priv = mport->priv;
176 pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n", 190 pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n",
177 index, destid, data); 191 index, destid, data);
178 out_be32(&priv->dbell_atmu_regs->rowtar, destid << 22); 192 switch (mport->phy_type) {
179 out_be16(priv->dbell_win, data); 193 case RIO_PHY_PARALLEL:
194 out_be32(&priv->dbell_atmu_regs->rowtar, destid << 22);
195 out_be16(priv->dbell_win, data);
196 break;
197 case RIO_PHY_SERIAL:
198 /* In the serial version silicons, such as MPC8548, MPC8641,
199 * below operations is must be.
200 */
201 out_be32(&priv->msg_regs->odmr, 0x00000000);
202 out_be32(&priv->msg_regs->odretcr, 0x00000004);
203 out_be32(&priv->msg_regs->oddpr, destid << 16);
204 out_be32(&priv->msg_regs->oddatr, data);
205 out_be32(&priv->msg_regs->odmr, 0x00000001);
206 break;
207 }
180 208
181 return 0; 209 return 0;
182} 210}
@@ -342,11 +370,22 @@ rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
342 memset(priv->msg_tx_ring.virt_buffer[priv->msg_tx_ring.tx_slot] 370 memset(priv->msg_tx_ring.virt_buffer[priv->msg_tx_ring.tx_slot]
343 + len, 0, RIO_MAX_MSG_SIZE - len); 371 + len, 0, RIO_MAX_MSG_SIZE - len);
344 372
345 /* Set mbox field for message */ 373 switch (mport->phy_type) {
346 desc->dport = mbox & 0x3; 374 case RIO_PHY_PARALLEL:
375 /* Set mbox field for message */
376 desc->dport = mbox & 0x3;
347 377
348 /* Enable EOMI interrupt, set priority, and set destid */ 378 /* Enable EOMI interrupt, set priority, and set destid */
349 desc->dattr = 0x28000000 | (rdev->destid << 2); 379 desc->dattr = 0x28000000 | (rdev->destid << 2);
380 break;
381 case RIO_PHY_SERIAL:
382 /* Set mbox field for message, and set destid */
383 desc->dport = (rdev->destid << 16) | (mbox & 0x3);
384
385 /* Enable EOMI interrupt and priority */
386 desc->dattr = 0x28000000;
387 break;
388 }
350 389
351 /* Set transfer size aligned to next power of 2 (in double words) */ 390 /* Set transfer size aligned to next power of 2 (in double words) */
352 desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len); 391 desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len);
@@ -920,6 +959,7 @@ int fsl_rio_setup(struct of_device *dev)
920 const u32 *dt_range, *cell; 959 const u32 *dt_range, *cell;
921 struct resource regs; 960 struct resource regs;
922 int rlen; 961 int rlen;
962 u32 ccsr;
923 u64 law_start, law_size; 963 u64 law_start, law_size;
924 int paw, aw, sw; 964 int paw, aw, sw;
925 965
@@ -1008,6 +1048,14 @@ int fsl_rio_setup(struct of_device *dev)
1008 1048
1009 priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1); 1049 priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1);
1010 1050
1051 /* Probe the master port phy type */
1052 ccsr = in_be32(priv->regs_win + RIO_CCSR);
1053 port->phy_type = (ccsr & 1) ? RIO_PHY_SERIAL : RIO_PHY_PARALLEL;
1054 dev_info(&dev->dev, "RapidIO PHY type: %s\n",
1055 (port->phy_type == RIO_PHY_PARALLEL) ? "parallel" :
1056 ((port->phy_type == RIO_PHY_SERIAL) ? "serial" :
1057 "unknown"));
1058
1011 port->sys_size = (in_be32((priv->regs_win + RIO_PEF_CAR)) 1059 port->sys_size = (in_be32((priv->regs_win + RIO_PEF_CAR))
1012 & RIO_PEF_CTLS) >> 4; 1060 & RIO_PEF_CTLS) >> 4;
1013 dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n", 1061 dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n",
@@ -1017,8 +1065,13 @@ int fsl_rio_setup(struct of_device *dev)
1017 + RIO_ATMU_REGS_OFFSET); 1065 + RIO_ATMU_REGS_OFFSET);
1018 priv->maint_atmu_regs = priv->atmu_regs + 1; 1066 priv->maint_atmu_regs = priv->atmu_regs + 1;
1019 priv->dbell_atmu_regs = priv->atmu_regs + 2; 1067 priv->dbell_atmu_regs = priv->atmu_regs + 2;
1020 priv->msg_regs = (struct rio_msg_regs *)(priv->regs_win 1068 priv->msg_regs = (struct rio_msg_regs *)(priv->regs_win +
1021 + RIO_MSG_REGS_OFFSET); 1069 ((port->phy_type == RIO_PHY_SERIAL) ?
1070 RIO_S_MSG_REGS_OFFSET : RIO_P_MSG_REGS_OFFSET));
1071
1072 /* Set to receive any dist ID for serial RapidIO controller. */
1073 if (port->phy_type == RIO_PHY_SERIAL)
1074 out_be32((priv->regs_win + RIO_ISR_AACR), RIO_ISR_AACR_AA);
1022 1075
1023 /* Configure maintenance transaction window */ 1076 /* Configure maintenance transaction window */
1024 out_be32(&priv->maint_atmu_regs->rowbar, 0x000c0000); 1077 out_be32(&priv->maint_atmu_regs->rowbar, 0x000c0000);
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 4a064bcd7c0c..cfb66bbc0f27 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -145,6 +145,11 @@ struct rio_dbell {
145 void *dev_id; 145 void *dev_id;
146}; 146};
147 147
148enum rio_phy_type {
149 RIO_PHY_PARALLEL,
150 RIO_PHY_SERIAL,
151};
152
148/** 153/**
149 * struct rio_mport - RIO master port info 154 * struct rio_mport - RIO master port info
150 * @dbells: List of doorbell events 155 * @dbells: List of doorbell events
@@ -178,6 +183,7 @@ struct rio_mport {
178 * 0 - Small size. 256 devices. 183 * 0 - Small size. 256 devices.
179 * 1 - Large size, 65536 devices. 184 * 1 - Large size, 65536 devices.
180 */ 185 */
186 enum rio_phy_type phy_type; /* RapidIO phy type */
181 unsigned char name[40]; 187 unsigned char name[40];
182 void *priv; /* Master port private data */ 188 void *priv; /* Master port private data */
183}; 189};