diff options
| author | Zhang Wei <wei.zhang@freescale.com> | 2008-04-18 16:33:44 -0400 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2008-04-29 05:40:29 -0400 |
| commit | 61b269179df582bb363f871e88f732fe8af62a5e (patch) | |
| tree | 30781b72103c54b7a8535014f647bfefac0e606f | |
| parent | 182e143beeb3529208f805f1ac543606c1e2cc8c (diff) | |
[RAPIDIO] Add serial RapidIO controller support, which includes MPC8548, MPC8641
Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
| -rw-r--r-- | arch/powerpc/sysdev/fsl_rio.c | 75 | ||||
| -rw-r--r-- | include/linux/rio.h | 6 |
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 | ||
| 70 | struct rio_atmu_regs { | 76 | struct 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 | ||
| 148 | enum 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 | }; |
