~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/rapidio/switches/idtcps.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * IDT CPS RapidIO switches support
 
3
 *
 
4
 * Copyright 2009-2010 Integrated Device Technology, Inc.
 
5
 * Alexandre Bounine <alexandre.bounine@idt.com>
 
6
 *
 
7
 * This program is free software; you can redistribute  it and/or modify it
 
8
 * under  the terms of  the GNU General  Public License as published by the
 
9
 * Free Software Foundation;  either version 2 of the  License, or (at your
 
10
 * option) any later version.
 
11
 */
 
12
 
 
13
#include <linux/rio.h>
 
14
#include <linux/rio_drv.h>
 
15
#include <linux/rio_ids.h>
 
16
#include "../rio.h"
 
17
 
 
18
#define CPS_DEFAULT_ROUTE       0xde
 
19
#define CPS_NO_ROUTE            0xdf
 
20
 
 
21
#define IDTCPS_RIO_DOMAIN 0xf20020
 
22
 
 
23
static int
 
24
idtcps_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
 
25
                       u16 table, u16 route_destid, u8 route_port)
 
26
{
 
27
        u32 result;
 
28
 
 
29
        if (route_port == RIO_INVALID_ROUTE)
 
30
                route_port = CPS_DEFAULT_ROUTE;
 
31
 
 
32
        if (table == RIO_GLOBAL_TABLE) {
 
33
                rio_mport_write_config_32(mport, destid, hopcount,
 
34
                                RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
 
35
 
 
36
                rio_mport_read_config_32(mport, destid, hopcount,
 
37
                                RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
 
38
 
 
39
                result = (0xffffff00 & result) | (u32)route_port;
 
40
                rio_mport_write_config_32(mport, destid, hopcount,
 
41
                                RIO_STD_RTE_CONF_PORT_SEL_CSR, result);
 
42
        }
 
43
 
 
44
        return 0;
 
45
}
 
46
 
 
47
static int
 
48
idtcps_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
 
49
                       u16 table, u16 route_destid, u8 *route_port)
 
50
{
 
51
        u32 result;
 
52
 
 
53
        if (table == RIO_GLOBAL_TABLE) {
 
54
                rio_mport_write_config_32(mport, destid, hopcount,
 
55
                                RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
 
56
 
 
57
                rio_mport_read_config_32(mport, destid, hopcount,
 
58
                                RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
 
59
 
 
60
                if (CPS_DEFAULT_ROUTE == (u8)result ||
 
61
                    CPS_NO_ROUTE == (u8)result)
 
62
                        *route_port = RIO_INVALID_ROUTE;
 
63
                else
 
64
                        *route_port = (u8)result;
 
65
        }
 
66
 
 
67
        return 0;
 
68
}
 
69
 
 
70
static int
 
71
idtcps_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
 
72
                       u16 table)
 
73
{
 
74
        u32 i;
 
75
 
 
76
        if (table == RIO_GLOBAL_TABLE) {
 
77
                for (i = 0x80000000; i <= 0x800000ff;) {
 
78
                        rio_mport_write_config_32(mport, destid, hopcount,
 
79
                                RIO_STD_RTE_CONF_DESTID_SEL_CSR, i);
 
80
                        rio_mport_write_config_32(mport, destid, hopcount,
 
81
                                RIO_STD_RTE_CONF_PORT_SEL_CSR,
 
82
                                (CPS_DEFAULT_ROUTE << 24) |
 
83
                                (CPS_DEFAULT_ROUTE << 16) |
 
84
                                (CPS_DEFAULT_ROUTE << 8) | CPS_DEFAULT_ROUTE);
 
85
                        i += 4;
 
86
                }
 
87
        }
 
88
 
 
89
        return 0;
 
90
}
 
91
 
 
92
static int
 
93
idtcps_set_domain(struct rio_mport *mport, u16 destid, u8 hopcount,
 
94
                       u8 sw_domain)
 
95
{
 
96
        /*
 
97
         * Switch domain configuration operates only at global level
 
98
         */
 
99
        rio_mport_write_config_32(mport, destid, hopcount,
 
100
                                  IDTCPS_RIO_DOMAIN, (u32)sw_domain);
 
101
        return 0;
 
102
}
 
103
 
 
104
static int
 
105
idtcps_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount,
 
106
                       u8 *sw_domain)
 
107
{
 
108
        u32 regval;
 
109
 
 
110
        /*
 
111
         * Switch domain configuration operates only at global level
 
112
         */
 
113
        rio_mport_read_config_32(mport, destid, hopcount,
 
114
                                IDTCPS_RIO_DOMAIN, &regval);
 
115
 
 
116
        *sw_domain = (u8)(regval & 0xff);
 
117
 
 
118
        return 0;
 
119
}
 
120
 
 
121
static int idtcps_switch_init(struct rio_dev *rdev, int do_enum)
 
122
{
 
123
        pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
 
124
        rdev->rswitch->add_entry = idtcps_route_add_entry;
 
125
        rdev->rswitch->get_entry = idtcps_route_get_entry;
 
126
        rdev->rswitch->clr_table = idtcps_route_clr_table;
 
127
        rdev->rswitch->set_domain = idtcps_set_domain;
 
128
        rdev->rswitch->get_domain = idtcps_get_domain;
 
129
        rdev->rswitch->em_init = NULL;
 
130
        rdev->rswitch->em_handle = NULL;
 
131
 
 
132
        if (do_enum) {
 
133
                /* set TVAL = ~50us */
 
134
                rio_write_config_32(rdev,
 
135
                        rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8);
 
136
                /* Ensure that default routing is disabled on startup */
 
137
                rio_write_config_32(rdev,
 
138
                                    RIO_STD_RTE_DEFAULT_PORT, CPS_NO_ROUTE);
 
139
        }
 
140
 
 
141
        return 0;
 
142
}
 
143
 
 
144
DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS6Q, idtcps_switch_init);
 
145
DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS8, idtcps_switch_init);
 
146
DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS10Q, idtcps_switch_init);
 
147
DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS12, idtcps_switch_init);
 
148
DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS16, idtcps_switch_init);
 
149
DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDT70K200, idtcps_switch_init);