Commit | Line | Data |
---|---|---|
830c7df4 RM |
1 | /* |
2 | * Sonics Silicon Backplane SoC host related functions. | |
3 | * Subsystem core | |
4 | * | |
5 | * Copyright 2005, Broadcom Corporation | |
6 | * Copyright 2006, 2007, Michael Buesch <m@bues.ch> | |
7 | * | |
8 | * Licensed under the GNU/GPL. See COPYING for details. | |
9 | */ | |
10 | ||
11 | #include <linux/ssb/ssb.h> | |
12 | ||
13 | #include "ssb_private.h" | |
14 | ||
15 | static u8 ssb_host_soc_read8(struct ssb_device *dev, u16 offset) | |
16 | { | |
17 | struct ssb_bus *bus = dev->bus; | |
18 | ||
19 | offset += dev->core_index * SSB_CORE_SIZE; | |
20 | return readb(bus->mmio + offset); | |
21 | } | |
22 | ||
23 | static u16 ssb_host_soc_read16(struct ssb_device *dev, u16 offset) | |
24 | { | |
25 | struct ssb_bus *bus = dev->bus; | |
26 | ||
27 | offset += dev->core_index * SSB_CORE_SIZE; | |
28 | return readw(bus->mmio + offset); | |
29 | } | |
30 | ||
31 | static u32 ssb_host_soc_read32(struct ssb_device *dev, u16 offset) | |
32 | { | |
33 | struct ssb_bus *bus = dev->bus; | |
34 | ||
35 | offset += dev->core_index * SSB_CORE_SIZE; | |
36 | return readl(bus->mmio + offset); | |
37 | } | |
38 | ||
39 | #ifdef CONFIG_SSB_BLOCKIO | |
40 | static void ssb_host_soc_block_read(struct ssb_device *dev, void *buffer, | |
41 | size_t count, u16 offset, u8 reg_width) | |
42 | { | |
43 | struct ssb_bus *bus = dev->bus; | |
44 | void __iomem *addr; | |
45 | ||
46 | offset += dev->core_index * SSB_CORE_SIZE; | |
47 | addr = bus->mmio + offset; | |
48 | ||
49 | switch (reg_width) { | |
50 | case sizeof(u8): { | |
51 | u8 *buf = buffer; | |
52 | ||
53 | while (count) { | |
54 | *buf = __raw_readb(addr); | |
55 | buf++; | |
56 | count--; | |
57 | } | |
58 | break; | |
59 | } | |
60 | case sizeof(u16): { | |
61 | __le16 *buf = buffer; | |
62 | ||
63 | SSB_WARN_ON(count & 1); | |
64 | while (count) { | |
65 | *buf = (__force __le16)__raw_readw(addr); | |
66 | buf++; | |
67 | count -= 2; | |
68 | } | |
69 | break; | |
70 | } | |
71 | case sizeof(u32): { | |
72 | __le32 *buf = buffer; | |
73 | ||
74 | SSB_WARN_ON(count & 3); | |
75 | while (count) { | |
76 | *buf = (__force __le32)__raw_readl(addr); | |
77 | buf++; | |
78 | count -= 4; | |
79 | } | |
80 | break; | |
81 | } | |
82 | default: | |
83 | SSB_WARN_ON(1); | |
84 | } | |
85 | } | |
86 | #endif /* CONFIG_SSB_BLOCKIO */ | |
87 | ||
88 | static void ssb_host_soc_write8(struct ssb_device *dev, u16 offset, u8 value) | |
89 | { | |
90 | struct ssb_bus *bus = dev->bus; | |
91 | ||
92 | offset += dev->core_index * SSB_CORE_SIZE; | |
93 | writeb(value, bus->mmio + offset); | |
94 | } | |
95 | ||
96 | static void ssb_host_soc_write16(struct ssb_device *dev, u16 offset, u16 value) | |
97 | { | |
98 | struct ssb_bus *bus = dev->bus; | |
99 | ||
100 | offset += dev->core_index * SSB_CORE_SIZE; | |
101 | writew(value, bus->mmio + offset); | |
102 | } | |
103 | ||
104 | static void ssb_host_soc_write32(struct ssb_device *dev, u16 offset, u32 value) | |
105 | { | |
106 | struct ssb_bus *bus = dev->bus; | |
107 | ||
108 | offset += dev->core_index * SSB_CORE_SIZE; | |
109 | writel(value, bus->mmio + offset); | |
110 | } | |
111 | ||
112 | #ifdef CONFIG_SSB_BLOCKIO | |
113 | static void ssb_host_soc_block_write(struct ssb_device *dev, const void *buffer, | |
114 | size_t count, u16 offset, u8 reg_width) | |
115 | { | |
116 | struct ssb_bus *bus = dev->bus; | |
117 | void __iomem *addr; | |
118 | ||
119 | offset += dev->core_index * SSB_CORE_SIZE; | |
120 | addr = bus->mmio + offset; | |
121 | ||
122 | switch (reg_width) { | |
123 | case sizeof(u8): { | |
124 | const u8 *buf = buffer; | |
125 | ||
126 | while (count) { | |
127 | __raw_writeb(*buf, addr); | |
128 | buf++; | |
129 | count--; | |
130 | } | |
131 | break; | |
132 | } | |
133 | case sizeof(u16): { | |
134 | const __le16 *buf = buffer; | |
135 | ||
136 | SSB_WARN_ON(count & 1); | |
137 | while (count) { | |
138 | __raw_writew((__force u16)(*buf), addr); | |
139 | buf++; | |
140 | count -= 2; | |
141 | } | |
142 | break; | |
143 | } | |
144 | case sizeof(u32): { | |
145 | const __le32 *buf = buffer; | |
146 | ||
147 | SSB_WARN_ON(count & 3); | |
148 | while (count) { | |
149 | __raw_writel((__force u32)(*buf), addr); | |
150 | buf++; | |
151 | count -= 4; | |
152 | } | |
153 | break; | |
154 | } | |
155 | default: | |
156 | SSB_WARN_ON(1); | |
157 | } | |
158 | } | |
159 | #endif /* CONFIG_SSB_BLOCKIO */ | |
160 | ||
161 | /* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */ | |
162 | const struct ssb_bus_ops ssb_host_soc_ops = { | |
163 | .read8 = ssb_host_soc_read8, | |
164 | .read16 = ssb_host_soc_read16, | |
165 | .read32 = ssb_host_soc_read32, | |
166 | .write8 = ssb_host_soc_write8, | |
167 | .write16 = ssb_host_soc_write16, | |
168 | .write32 = ssb_host_soc_write32, | |
169 | #ifdef CONFIG_SSB_BLOCKIO | |
170 | .block_read = ssb_host_soc_block_read, | |
171 | .block_write = ssb_host_soc_block_write, | |
172 | #endif | |
173 | }; |