aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rapidio/switches
diff options
context:
space:
mode:
authorAlexandre Bounine <alexandre.bounine@idt.com>2010-05-26 17:43:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-27 12:12:50 -0400
commit07590ff03935a2efbc03bc7861f20c059576a479 (patch)
tree2da1ee2032e1425a138bc2864066a2e10533ce64 /drivers/rapidio/switches
parentf67231f80126f4e08c79c7b2056989c5c89ad4c6 (diff)
rapidio: add IDT CPS/TSI switches
Extentions to RapidIO switch support: 1. modify switch route operation declarations to allow using single switch-specific file for family of switches that share the same route table operations. 2. add standard route table operations for switches that that support route table manipulation registers as defined in the Rev.1.3 of RapidIO specification. 3. add clear-route-table operation for switches 4. add CPSxx and TSIxxx families of RapidIO switches Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com> Tested-by: Thomas Moll <thomas.moll@sysgo.com> Cc: Matt Porter <mporter@kernel.crashing.org> Cc: Li Yang <leoli@freescale.com> Cc: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rapidio/switches')
-rw-r--r--drivers/rapidio/switches/Kconfig28
-rw-r--r--drivers/rapidio/switches/Makefile5
-rw-r--r--drivers/rapidio/switches/idtcps.c89
-rw-r--r--drivers/rapidio/switches/tsi500.c2
-rw-r--r--drivers/rapidio/switches/tsi568.c106
-rw-r--r--drivers/rapidio/switches/tsi57x.c106
6 files changed, 334 insertions, 2 deletions
diff --git a/drivers/rapidio/switches/Kconfig b/drivers/rapidio/switches/Kconfig
new file mode 100644
index 000000000000..6969f398bc26
--- /dev/null
+++ b/drivers/rapidio/switches/Kconfig
@@ -0,0 +1,28 @@
1#
2# RapidIO switches configuration
3#
4config RAPIDIO_TSI57X
5 bool "IDT Tsi57x SRIO switches support"
6 depends on RAPIDIO
7 ---help---
8 Includes support for ITD Tsi57x family of serial RapidIO switches.
9
10config RAPIDIO_CPS_XX
11 bool "IDT CPS-xx SRIO switches support"
12 depends on RAPIDIO
13 ---help---
14 Includes support for ITD CPS-16/12/10/8 serial RapidIO switches.
15
16config RAPIDIO_TSI568
17 bool "Tsi568 SRIO switch support"
18 depends on RAPIDIO
19 default n
20 ---help---
21 Includes support for ITD Tsi568 serial RapidIO switch.
22
23config RAPIDIO_TSI500
24 bool "Tsi500 Parallel RapidIO switch support"
25 depends on RAPIDIO
26 default n
27 ---help---
28 Includes support for ITD Tsi500 parallel RapidIO switch.
diff --git a/drivers/rapidio/switches/Makefile b/drivers/rapidio/switches/Makefile
index b924f8301761..0fece0e6aa89 100644
--- a/drivers/rapidio/switches/Makefile
+++ b/drivers/rapidio/switches/Makefile
@@ -2,4 +2,7 @@
2# Makefile for RIO switches 2# Makefile for RIO switches
3# 3#
4 4
5obj-$(CONFIG_RAPIDIO) += tsi500.o 5obj-$(CONFIG_RAPIDIO_TSI57X) += tsi57x.o
6obj-$(CONFIG_RAPIDIO_CPS_XX) += idtcps.o
7obj-$(CONFIG_RAPIDIO_TSI568) += tsi568.o
8obj-$(CONFIG_RAPIDIO_TSI500) += tsi500.o
diff --git a/drivers/rapidio/switches/idtcps.c b/drivers/rapidio/switches/idtcps.c
new file mode 100644
index 000000000000..7e3d03283dec
--- /dev/null
+++ b/drivers/rapidio/switches/idtcps.c
@@ -0,0 +1,89 @@
1/*
2 * IDT CPS RapidIO switches support
3 *
4 * Copyright 2009 Integrated Device Technology, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <linux/rio.h>
13#include <linux/rio_drv.h>
14#include <linux/rio_ids.h>
15#include "../rio.h"
16
17#define CPS_NO_ROUTE 0xdf
18
19static int
20idtcps_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
21 u16 table, u16 route_destid, u8 route_port)
22{
23 u32 result;
24
25 if (table == RIO_GLOBAL_TABLE) {
26 rio_mport_write_config_32(mport, destid, hopcount,
27 RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
28
29 rio_mport_read_config_32(mport, destid, hopcount,
30 RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
31
32 result = (0xffffff00 & result) | (u32)route_port;
33 rio_mport_write_config_32(mport, destid, hopcount,
34 RIO_STD_RTE_CONF_PORT_SEL_CSR, result);
35 }
36
37 return 0;
38}
39
40static int
41idtcps_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
42 u16 table, u16 route_destid, u8 *route_port)
43{
44 u32 result;
45
46 if (table == RIO_GLOBAL_TABLE) {
47 rio_mport_write_config_32(mport, destid, hopcount,
48 RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
49
50 rio_mport_read_config_32(mport, destid, hopcount,
51 RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
52
53 if (CPS_NO_ROUTE == (u8)result)
54 result = RIO_INVALID_ROUTE;
55
56 *route_port = (u8)result;
57 }
58
59 return 0;
60}
61
62static int
63idtcps_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
64 u16 table)
65{
66 u32 i;
67
68 if (table == RIO_GLOBAL_TABLE) {
69 for (i = 0x80000000; i <= 0x800000ff;) {
70 rio_mport_write_config_32(mport, destid, hopcount,
71 RIO_STD_RTE_CONF_DESTID_SEL_CSR, i);
72 rio_mport_write_config_32(mport, destid, hopcount,
73 RIO_STD_RTE_CONF_PORT_SEL_CSR,
74 (RIO_INVALID_ROUTE << 24) |
75 (RIO_INVALID_ROUTE << 16) |
76 (RIO_INVALID_ROUTE << 8) | RIO_INVALID_ROUTE);
77 i += 4;
78 }
79 }
80
81 return 0;
82}
83
84DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS6Q, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
85DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS8, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
86DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS10Q, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
87DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS12, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
88DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS16, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
89DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDT70K200, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
diff --git a/drivers/rapidio/switches/tsi500.c b/drivers/rapidio/switches/tsi500.c
index c77c23bd9840..ae553bb41089 100644
--- a/drivers/rapidio/switches/tsi500.c
+++ b/drivers/rapidio/switches/tsi500.c
@@ -57,4 +57,4 @@ tsi500_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 tab
57 return ret; 57 return ret;
58} 58}
59 59
60DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_route_add_entry, tsi500_route_get_entry); 60DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_route_add_entry, tsi500_route_get_entry, NULL);
diff --git a/drivers/rapidio/switches/tsi568.c b/drivers/rapidio/switches/tsi568.c
new file mode 100644
index 000000000000..bce9112ff0d9
--- /dev/null
+++ b/drivers/rapidio/switches/tsi568.c
@@ -0,0 +1,106 @@
1/*
2 * RapidIO Tsi568 switch support
3 *
4 * Copyright 2009-2010 Integrated Device Technology, Inc.
5 * Copyright 2005 MontaVista Software, Inc.
6 * Matt Porter <mporter@kernel.crashing.org>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/rio.h>
15#include <linux/rio_drv.h>
16#include <linux/rio_ids.h>
17#include <linux/delay.h>
18#include "../rio.h"
19
20/* Global (broadcast) route registers */
21#define SPBC_ROUTE_CFG_DESTID 0x10070
22#define SPBC_ROUTE_CFG_PORT 0x10074
23
24/* Per port route registers */
25#define SPP_ROUTE_CFG_DESTID(n) (0x11070 + 0x100*n)
26#define SPP_ROUTE_CFG_PORT(n) (0x11074 + 0x100*n)
27
28static int
29tsi568_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
30 u16 table, u16 route_destid, u8 route_port)
31{
32 if (table == RIO_GLOBAL_TABLE) {
33 rio_mport_write_config_32(mport, destid, hopcount,
34 SPBC_ROUTE_CFG_DESTID, route_destid);
35 rio_mport_write_config_32(mport, destid, hopcount,
36 SPBC_ROUTE_CFG_PORT, route_port);
37 } else {
38 rio_mport_write_config_32(mport, destid, hopcount,
39 SPP_ROUTE_CFG_DESTID(table),
40 route_destid);
41 rio_mport_write_config_32(mport, destid, hopcount,
42 SPP_ROUTE_CFG_PORT(table), route_port);
43 }
44
45 udelay(10);
46
47 return 0;
48}
49
50static int
51tsi568_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
52 u16 table, u16 route_destid, u8 *route_port)
53{
54 int ret = 0;
55 u32 result;
56
57 if (table == RIO_GLOBAL_TABLE) {
58 rio_mport_write_config_32(mport, destid, hopcount,
59 SPBC_ROUTE_CFG_DESTID, route_destid);
60 rio_mport_read_config_32(mport, destid, hopcount,
61 SPBC_ROUTE_CFG_PORT, &result);
62 } else {
63 rio_mport_write_config_32(mport, destid, hopcount,
64 SPP_ROUTE_CFG_DESTID(table),
65 route_destid);
66 rio_mport_read_config_32(mport, destid, hopcount,
67 SPP_ROUTE_CFG_PORT(table), &result);
68 }
69
70 *route_port = result;
71 if (*route_port > 15)
72 ret = -1;
73
74 return ret;
75}
76
77static int
78tsi568_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
79 u16 table)
80{
81 u32 route_idx;
82 u32 lut_size;
83
84 lut_size = (mport->sys_size) ? 0x1ff : 0xff;
85
86 if (table == RIO_GLOBAL_TABLE) {
87 rio_mport_write_config_32(mport, destid, hopcount,
88 SPBC_ROUTE_CFG_DESTID, 0x80000000);
89 for (route_idx = 0; route_idx <= lut_size; route_idx++)
90 rio_mport_write_config_32(mport, destid, hopcount,
91 SPBC_ROUTE_CFG_PORT,
92 RIO_INVALID_ROUTE);
93 } else {
94 rio_mport_write_config_32(mport, destid, hopcount,
95 SPP_ROUTE_CFG_DESTID(table),
96 0x80000000);
97 for (route_idx = 0; route_idx <= lut_size; route_idx++)
98 rio_mport_write_config_32(mport, destid, hopcount,
99 SPP_ROUTE_CFG_PORT(table),
100 RIO_INVALID_ROUTE);
101 }
102
103 return 0;
104}
105
106DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI568, tsi568_route_add_entry, tsi568_route_get_entry, tsi568_route_clr_table);
diff --git a/drivers/rapidio/switches/tsi57x.c b/drivers/rapidio/switches/tsi57x.c
new file mode 100644
index 000000000000..5ad7880787c9
--- /dev/null
+++ b/drivers/rapidio/switches/tsi57x.c
@@ -0,0 +1,106 @@
1/*
2 * RapidIO Tsi57x switch family support
3 *
4 * Copyright 2009 Integrated Device Technology, Inc.
5 * Copyright 2005 MontaVista Software, Inc.
6 * Matt Porter <mporter@kernel.crashing.org>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/rio.h>
15#include <linux/rio_drv.h>
16#include <linux/rio_ids.h>
17#include <linux/delay.h>
18#include "../rio.h"
19
20/* Global (broadcast) route registers */
21#define SPBC_ROUTE_CFG_DESTID 0x10070
22#define SPBC_ROUTE_CFG_PORT 0x10074
23
24/* Per port route registers */
25#define SPP_ROUTE_CFG_DESTID(n) (0x11070 + 0x100*n)
26#define SPP_ROUTE_CFG_PORT(n) (0x11074 + 0x100*n)
27
28static int
29tsi57x_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
30 u16 table, u16 route_destid, u8 route_port)
31{
32 if (table == RIO_GLOBAL_TABLE) {
33 rio_mport_write_config_32(mport, destid, hopcount,
34 SPBC_ROUTE_CFG_DESTID, route_destid);
35 rio_mport_write_config_32(mport, destid, hopcount,
36 SPBC_ROUTE_CFG_PORT, route_port);
37 } else {
38 rio_mport_write_config_32(mport, destid, hopcount,
39 SPP_ROUTE_CFG_DESTID(table), route_destid);
40 rio_mport_write_config_32(mport, destid, hopcount,
41 SPP_ROUTE_CFG_PORT(table), route_port);
42 }
43
44 udelay(10);
45
46 return 0;
47}
48
49static int
50tsi57x_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
51 u16 table, u16 route_destid, u8 *route_port)
52{
53 int ret = 0;
54 u32 result;
55
56 if (table == RIO_GLOBAL_TABLE) {
57 /* Use local RT of the ingress port to avoid possible
58 race condition */
59 rio_mport_read_config_32(mport, destid, hopcount,
60 RIO_SWP_INFO_CAR, &result);
61 table = (result & RIO_SWP_INFO_PORT_NUM_MASK);
62 }
63
64 rio_mport_write_config_32(mport, destid, hopcount,
65 SPP_ROUTE_CFG_DESTID(table), route_destid);
66 rio_mport_read_config_32(mport, destid, hopcount,
67 SPP_ROUTE_CFG_PORT(table), &result);
68
69 *route_port = (u8)result;
70 if (*route_port > 15)
71 ret = -1;
72
73 return ret;
74}
75
76static int
77tsi57x_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
78 u16 table)
79{
80 u32 route_idx;
81 u32 lut_size;
82
83 lut_size = (mport->sys_size) ? 0x1ff : 0xff;
84
85 if (table == RIO_GLOBAL_TABLE) {
86 rio_mport_write_config_32(mport, destid, hopcount,
87 SPBC_ROUTE_CFG_DESTID, 0x80000000);
88 for (route_idx = 0; route_idx <= lut_size; route_idx++)
89 rio_mport_write_config_32(mport, destid, hopcount,
90 SPBC_ROUTE_CFG_PORT,
91 RIO_INVALID_ROUTE);
92 } else {
93 rio_mport_write_config_32(mport, destid, hopcount,
94 SPP_ROUTE_CFG_DESTID(table), 0x80000000);
95 for (route_idx = 0; route_idx <= lut_size; route_idx++)
96 rio_mport_write_config_32(mport, destid, hopcount,
97 SPP_ROUTE_CFG_PORT(table) , RIO_INVALID_ROUTE);
98 }
99
100 return 0;
101}
102
103DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI572, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table);
104DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI574, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table);
105DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI577, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table);
106DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI578, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table);