aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/host/pci-mvebu.c
diff options
context:
space:
mode:
authorSeungwon Jeon <tgih.jun@samsung.com>2013-10-04 05:58:15 -0400
committerJason Cooper <jason@lakedaemon.net>2013-10-08 13:18:32 -0400
commit032b4c0cc321b7b14e4035997f6debd1b42cdbe2 (patch)
tree15d03a6f2ec238ac8dc09fc1aeb2f1be9df2dbf5 /drivers/pci/host/pci-mvebu.c
parent9f352f0e6c0fa2dc608812df297769789b7ecc51 (diff)
PCI: mvebu: add I/O access wrappers
This change adds wrapper functions for MMIO access to PCIe IP block. And some 8/16-bit access are replaced by 32-bit. Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'drivers/pci/host/pci-mvebu.c')
-rw-r--r--drivers/pci/host/pci-mvebu.c97
1 files changed, 55 insertions, 42 deletions
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 10c0895e42b3..73b6baea4879 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -140,29 +140,39 @@ struct mvebu_pcie_port {
140 size_t iowin_size; 140 size_t iowin_size;
141}; 141};
142 142
143static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg)
144{
145 writel(val, port->base + reg);
146}
147
148static inline u32 mvebu_readl(struct mvebu_pcie_port *port, u32 reg)
149{
150 return readl(port->base + reg);
151}
152
143static bool mvebu_pcie_link_up(struct mvebu_pcie_port *port) 153static bool mvebu_pcie_link_up(struct mvebu_pcie_port *port)
144{ 154{
145 return !(readl(port->base + PCIE_STAT_OFF) & PCIE_STAT_LINK_DOWN); 155 return !(mvebu_readl(port, PCIE_STAT_OFF) & PCIE_STAT_LINK_DOWN);
146} 156}
147 157
148static void mvebu_pcie_set_local_bus_nr(struct mvebu_pcie_port *port, int nr) 158static void mvebu_pcie_set_local_bus_nr(struct mvebu_pcie_port *port, int nr)
149{ 159{
150 u32 stat; 160 u32 stat;
151 161
152 stat = readl(port->base + PCIE_STAT_OFF); 162 stat = mvebu_readl(port, PCIE_STAT_OFF);
153 stat &= ~PCIE_STAT_BUS; 163 stat &= ~PCIE_STAT_BUS;
154 stat |= nr << 8; 164 stat |= nr << 8;
155 writel(stat, port->base + PCIE_STAT_OFF); 165 mvebu_writel(port, stat, PCIE_STAT_OFF);
156} 166}
157 167
158static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr) 168static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr)
159{ 169{
160 u32 stat; 170 u32 stat;
161 171
162 stat = readl(port->base + PCIE_STAT_OFF); 172 stat = mvebu_readl(port, PCIE_STAT_OFF);
163 stat &= ~PCIE_STAT_DEV; 173 stat &= ~PCIE_STAT_DEV;
164 stat |= nr << 16; 174 stat |= nr << 16;
165 writel(stat, port->base + PCIE_STAT_OFF); 175 mvebu_writel(port, stat, PCIE_STAT_OFF);
166} 176}
167 177
168/* 178/*
@@ -180,33 +190,34 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
180 190
181 /* First, disable and clear BARs and windows. */ 191 /* First, disable and clear BARs and windows. */
182 for (i = 1; i < 3; i++) { 192 for (i = 1; i < 3; i++) {
183 writel(0, port->base + PCIE_BAR_CTRL_OFF(i)); 193 mvebu_writel(port, 0, PCIE_BAR_CTRL_OFF(i));
184 writel(0, port->base + PCIE_BAR_LO_OFF(i)); 194 mvebu_writel(port, 0, PCIE_BAR_LO_OFF(i));
185 writel(0, port->base + PCIE_BAR_HI_OFF(i)); 195 mvebu_writel(port, 0, PCIE_BAR_HI_OFF(i));
186 } 196 }
187 197
188 for (i = 0; i < 5; i++) { 198 for (i = 0; i < 5; i++) {
189 writel(0, port->base + PCIE_WIN04_CTRL_OFF(i)); 199 mvebu_writel(port, 0, PCIE_WIN04_CTRL_OFF(i));
190 writel(0, port->base + PCIE_WIN04_BASE_OFF(i)); 200 mvebu_writel(port, 0, PCIE_WIN04_BASE_OFF(i));
191 writel(0, port->base + PCIE_WIN04_REMAP_OFF(i)); 201 mvebu_writel(port, 0, PCIE_WIN04_REMAP_OFF(i));
192 } 202 }
193 203
194 writel(0, port->base + PCIE_WIN5_CTRL_OFF); 204 mvebu_writel(port, 0, PCIE_WIN5_CTRL_OFF);
195 writel(0, port->base + PCIE_WIN5_BASE_OFF); 205 mvebu_writel(port, 0, PCIE_WIN5_BASE_OFF);
196 writel(0, port->base + PCIE_WIN5_REMAP_OFF); 206 mvebu_writel(port, 0, PCIE_WIN5_REMAP_OFF);
197 207
198 /* Setup windows for DDR banks. Count total DDR size on the fly. */ 208 /* Setup windows for DDR banks. Count total DDR size on the fly. */
199 size = 0; 209 size = 0;
200 for (i = 0; i < dram->num_cs; i++) { 210 for (i = 0; i < dram->num_cs; i++) {
201 const struct mbus_dram_window *cs = dram->cs + i; 211 const struct mbus_dram_window *cs = dram->cs + i;
202 212
203 writel(cs->base & 0xffff0000, 213 mvebu_writel(port, cs->base & 0xffff0000,
204 port->base + PCIE_WIN04_BASE_OFF(i)); 214 PCIE_WIN04_BASE_OFF(i));
205 writel(0, port->base + PCIE_WIN04_REMAP_OFF(i)); 215 mvebu_writel(port, 0, PCIE_WIN04_REMAP_OFF(i));
206 writel(((cs->size - 1) & 0xffff0000) | 216 mvebu_writel(port,
207 (cs->mbus_attr << 8) | 217 ((cs->size - 1) & 0xffff0000) |
208 (dram->mbus_dram_target_id << 4) | 1, 218 (cs->mbus_attr << 8) |
209 port->base + PCIE_WIN04_CTRL_OFF(i)); 219 (dram->mbus_dram_target_id << 4) | 1,
220 PCIE_WIN04_CTRL_OFF(i));
210 221
211 size += cs->size; 222 size += cs->size;
212 } 223 }
@@ -216,41 +227,40 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
216 size = 1 << fls(size); 227 size = 1 << fls(size);
217 228
218 /* Setup BAR[1] to all DRAM banks. */ 229 /* Setup BAR[1] to all DRAM banks. */
219 writel(dram->cs[0].base, port->base + PCIE_BAR_LO_OFF(1)); 230 mvebu_writel(port, dram->cs[0].base, PCIE_BAR_LO_OFF(1));
220 writel(0, port->base + PCIE_BAR_HI_OFF(1)); 231 mvebu_writel(port, 0, PCIE_BAR_HI_OFF(1));
221 writel(((size - 1) & 0xffff0000) | 1, 232 mvebu_writel(port, ((size - 1) & 0xffff0000) | 1,
222 port->base + PCIE_BAR_CTRL_OFF(1)); 233 PCIE_BAR_CTRL_OFF(1));
223} 234}
224 235
225static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port) 236static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
226{ 237{
227 u16 cmd; 238 u32 cmd, mask;
228 u32 mask;
229 239
230 /* Point PCIe unit MBUS decode windows to DRAM space. */ 240 /* Point PCIe unit MBUS decode windows to DRAM space. */
231 mvebu_pcie_setup_wins(port); 241 mvebu_pcie_setup_wins(port);
232 242
233 /* Master + slave enable. */ 243 /* Master + slave enable. */
234 cmd = readw(port->base + PCIE_CMD_OFF); 244 cmd = mvebu_readl(port, PCIE_CMD_OFF);
235 cmd |= PCI_COMMAND_IO; 245 cmd |= PCI_COMMAND_IO;
236 cmd |= PCI_COMMAND_MEMORY; 246 cmd |= PCI_COMMAND_MEMORY;
237 cmd |= PCI_COMMAND_MASTER; 247 cmd |= PCI_COMMAND_MASTER;
238 writew(cmd, port->base + PCIE_CMD_OFF); 248 mvebu_writel(port, cmd, PCIE_CMD_OFF);
239 249
240 /* Enable interrupt lines A-D. */ 250 /* Enable interrupt lines A-D. */
241 mask = readl(port->base + PCIE_MASK_OFF); 251 mask = mvebu_readl(port, PCIE_MASK_OFF);
242 mask |= PCIE_MASK_ENABLE_INTS; 252 mask |= PCIE_MASK_ENABLE_INTS;
243 writel(mask, port->base + PCIE_MASK_OFF); 253 mvebu_writel(port, mask, PCIE_MASK_OFF);
244} 254}
245 255
246static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port, 256static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
247 struct pci_bus *bus, 257 struct pci_bus *bus,
248 u32 devfn, int where, int size, u32 *val) 258 u32 devfn, int where, int size, u32 *val)
249{ 259{
250 writel(PCIE_CONF_ADDR(bus->number, devfn, where), 260 mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
251 port->base + PCIE_CONF_ADDR_OFF); 261 PCIE_CONF_ADDR_OFF);
252 262
253 *val = readl(port->base + PCIE_CONF_DATA_OFF); 263 *val = mvebu_readl(port, PCIE_CONF_DATA_OFF);
254 264
255 if (size == 1) 265 if (size == 1)
256 *val = (*val >> (8 * (where & 3))) & 0xff; 266 *val = (*val >> (8 * (where & 3))) & 0xff;
@@ -264,21 +274,24 @@ static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
264 struct pci_bus *bus, 274 struct pci_bus *bus,
265 u32 devfn, int where, int size, u32 val) 275 u32 devfn, int where, int size, u32 val)
266{ 276{
267 int ret = PCIBIOS_SUCCESSFUL; 277 u32 _val, shift = 8 * (where & 3);
268 278
269 writel(PCIE_CONF_ADDR(bus->number, devfn, where), 279 mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
270 port->base + PCIE_CONF_ADDR_OFF); 280 PCIE_CONF_ADDR_OFF);
281 _val = mvebu_readl(port, PCIE_CONF_DATA_OFF);
271 282
272 if (size == 4) 283 if (size == 4)
273 writel(val, port->base + PCIE_CONF_DATA_OFF); 284 _val = val;
274 else if (size == 2) 285 else if (size == 2)
275 writew(val, port->base + PCIE_CONF_DATA_OFF + (where & 3)); 286 _val = (_val & ~(0xffff << shift)) | ((val & 0xffff) << shift);
276 else if (size == 1) 287 else if (size == 1)
277 writeb(val, port->base + PCIE_CONF_DATA_OFF + (where & 3)); 288 _val = (_val & ~(0xff << shift)) | ((val & 0xff) << shift);
278 else 289 else
279 ret = PCIBIOS_BAD_REGISTER_NUMBER; 290 return PCIBIOS_BAD_REGISTER_NUMBER;
280 291
281 return ret; 292 mvebu_writel(port, _val, PCIE_CONF_DATA_OFF);
293
294 return PCIBIOS_SUCCESSFUL;
282} 295}
283 296
284static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) 297static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)