1 /* $NetBSD: ixp425_pci_space.c,v 1.7 2009/10/21 14:15:50 rmind Exp $ */
5 * Ichiro FUKUHARA <ichiro@ichiro.org>.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
31 __KERNEL_RCSID(0, "$NetBSD: ixp425_pci_space.c,v 1.7 2009/10/21 14:15:50 rmind Exp $");
34 * bus_space PCI functions for ixp425
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/queue.h>
43 #include <machine/bus.h>
45 #include <arm/xscale/ixp425reg.h>
46 #include <arm/xscale/ixp425var.h>
49 * Macros to read/write registers
51 #define CSR_READ_4(x) *(volatile uint32_t *) \
52 (IXP425_PCI_CSR_BASE + (x))
53 #define CSR_WRITE_4(x, v) *(volatile uint32_t *) \
54 (IXP425_PCI_CSR_BASE + (x)) = (v)
56 /* Proto types for all the bus_space structure functions */
57 bs_protos(ixp425_pci
);
58 bs_protos(ixp425_pci_io
);
59 bs_protos(ixp425_pci_mem
);
60 bs_protos(bs_notimpl
);
62 /* special I/O functions */
64 inline u_int8_t
_pci_io_bs_r_1(void *, bus_space_handle_t
, bus_size_t
);
65 inline u_int16_t
_pci_io_bs_r_2(void *, bus_space_handle_t
, bus_size_t
);
66 inline u_int32_t
_pci_io_bs_r_4(void *, bus_space_handle_t
, bus_size_t
);
68 inline void _pci_io_bs_w_1(void *, bus_space_handle_t
, bus_size_t
, u_int8_t
);
69 inline void _pci_io_bs_w_2(void *, bus_space_handle_t
, bus_size_t
, u_int16_t
);
70 inline void _pci_io_bs_w_4(void *, bus_space_handle_t
, bus_size_t
, u_int32_t
);
73 struct bus_space ixp425_pci_bs_tag_template
= {
77 /* mapping/unmapping */
80 ixp425_pci_bs_subregion
,
82 /* allocation/deallocation */
86 /* get kernel virtual address */
89 /* mmap bus space for userland */
93 ixp425_pci_bs_barrier
,
151 ixp425_io_bs_init(bus_space_tag_t bs
, void *cookie
)
153 *bs
= ixp425_pci_bs_tag_template
;
154 bs
->bs_cookie
= cookie
;
156 bs
->bs_map
= ixp425_pci_io_bs_map
;
157 bs
->bs_unmap
= ixp425_pci_io_bs_unmap
;
158 bs
->bs_alloc
= ixp425_pci_io_bs_alloc
;
159 bs
->bs_free
= ixp425_pci_io_bs_free
;
160 bs
->bs_vaddr
= ixp425_pci_io_bs_vaddr
;
163 * IXP425 processor does not have PCI I/O windows
166 bs
->bs_r_1
= _pci_io_bs_r_1
;
167 bs
->bs_r_2
= _pci_io_bs_r_2
;
168 bs
->bs_r_4
= _pci_io_bs_r_4
;
171 bs
->bs_w_1
= _pci_io_bs_w_1
;
172 bs
->bs_w_2
= _pci_io_bs_w_2
;
173 bs
->bs_w_4
= _pci_io_bs_w_4
;
177 ixp425_mem_bs_init(bus_space_tag_t bs
, void *cookie
)
179 *bs
= ixp425_pci_bs_tag_template
;
180 bs
->bs_cookie
= cookie
;
182 bs
->bs_map
= ixp425_pci_mem_bs_map
;
183 bs
->bs_unmap
= ixp425_pci_mem_bs_unmap
;
184 bs
->bs_alloc
= ixp425_pci_mem_bs_alloc
;
185 bs
->bs_free
= ixp425_pci_mem_bs_free
;
186 bs
->bs_vaddr
= ixp425_pci_mem_bs_vaddr
;
189 bs
->bs_r_1
= ixp425_pci_mem_bs_r_1
;
190 bs
->bs_r_2
= ixp425_pci_mem_bs_r_2
;
191 bs
->bs_r_4
= ixp425_pci_mem_bs_r_4
;
194 bs
->bs_w_1
= ixp425_pci_mem_bs_w_1
;
195 bs
->bs_w_2
= ixp425_pci_mem_bs_w_2
;
196 bs
->bs_w_4
= ixp425_pci_mem_bs_w_4
;
201 ixp425_pci_bs_subregion(void *t
, bus_space_handle_t bsh
, bus_size_t offset
,
202 bus_size_t size
, bus_space_handle_t
*nbshp
)
204 *nbshp
= bsh
+ offset
;
209 ixp425_pci_bs_barrier(void *t
, bus_space_handle_t bsh
, bus_size_t offset
,
210 bus_size_t len
, int flags
)
216 ixp425_pci_bs_mmap(void *t
, bus_addr_t addr
, off_t off
, int prot
, int flags
)
224 ixp425_pci_io_bs_map(void *t
, bus_addr_t bpa
, bus_size_t size
,
225 int cacheable
, bus_space_handle_t
*bshp
)
232 ixp425_pci_io_bs_unmap(void *t
, bus_space_handle_t bsh
, bus_size_t size
)
238 ixp425_pci_io_bs_alloc(void *t
, bus_addr_t rstart
, bus_addr_t rend
,
239 bus_size_t size
, bus_size_t alignment
, bus_size_t boundary
, int cacheable
,
240 bus_addr_t
*bpap
, bus_space_handle_t
*bshp
)
242 panic("ixp425_pci_io_bs_alloc(): not implemented\n");
246 ixp425_pci_io_bs_free(void *t
, bus_space_handle_t bsh
, bus_size_t size
)
248 panic("ixp425_pci_io_bs_free(): not implemented\n");
252 ixp425_pci_io_bs_vaddr(void *t
, bus_space_handle_t bsh
)
258 /* special I/O functions */
259 #if 1 /* _pci_io_bs_{rw}_{124} */
261 _pci_io_bs_r_1(void *v
, bus_space_handle_t ioh
, bus_size_t off
)
263 u_int32_t data
, n
, be
;
267 be
= (0xf & ~(1U << n
)) << NP_CBE_SHIFT
;
270 CSR_WRITE_4(PCI_NP_AD
, (ioh
+ off
) & ~3);
271 CSR_WRITE_4(PCI_NP_CBE
, be
| COMMAND_NP_IO_READ
);
272 data
= CSR_READ_4(PCI_NP_RDATA
);
273 if (CSR_READ_4(PCI_ISR
) & ISR_PFE
)
274 CSR_WRITE_4(PCI_ISR
, ISR_PFE
);
277 return data
>> (8 * n
);
281 _pci_io_bs_r_2(void *v
, bus_space_handle_t ioh
, bus_size_t off
)
283 u_int32_t data
, n
, be
;
287 be
= (0xf & ~((1U << n
) | (1U << (n
+ 1)))) << NP_CBE_SHIFT
;
290 CSR_WRITE_4(PCI_NP_AD
, (ioh
+ off
) & ~3);
291 CSR_WRITE_4(PCI_NP_CBE
, be
| COMMAND_NP_IO_READ
);
292 data
= CSR_READ_4(PCI_NP_RDATA
);
293 if (CSR_READ_4(PCI_ISR
) & ISR_PFE
)
294 CSR_WRITE_4(PCI_ISR
, ISR_PFE
);
297 return data
>> (8 * n
);
301 _pci_io_bs_r_4(void *v
, bus_space_handle_t ioh
, bus_size_t off
)
307 CSR_WRITE_4(PCI_NP_AD
, (ioh
+ off
) & ~3);
308 CSR_WRITE_4(PCI_NP_CBE
, COMMAND_NP_IO_READ
);
309 data
= CSR_READ_4(PCI_NP_RDATA
);
310 if (CSR_READ_4(PCI_ISR
) & ISR_PFE
)
311 CSR_WRITE_4(PCI_ISR
, ISR_PFE
);
318 _pci_io_bs_w_1(void *v
, bus_space_handle_t ioh
, bus_size_t off
,
321 u_int32_t data
, n
, be
;
325 be
= (0xf & ~(1U << n
)) << NP_CBE_SHIFT
;
326 data
= val
<< (8 * n
);
329 CSR_WRITE_4(PCI_NP_AD
, (ioh
+ off
) & ~3);
330 CSR_WRITE_4(PCI_NP_CBE
, be
| COMMAND_NP_IO_WRITE
);
331 CSR_WRITE_4(PCI_NP_WDATA
, data
);
332 if (CSR_READ_4(PCI_ISR
) & ISR_PFE
)
333 CSR_WRITE_4(PCI_ISR
, ISR_PFE
);
338 _pci_io_bs_w_2(void *v
, bus_space_handle_t ioh
, bus_size_t off
,
341 u_int32_t data
, n
, be
;
345 be
= (0xf & ~((1U << n
) | (1U << (n
+ 1)))) << NP_CBE_SHIFT
;
346 data
= val
<< (8 * n
);
349 CSR_WRITE_4(PCI_NP_AD
, (ioh
+ off
) & ~3);
350 CSR_WRITE_4(PCI_NP_CBE
, be
| COMMAND_NP_IO_WRITE
);
351 CSR_WRITE_4(PCI_NP_WDATA
, data
);
352 if (CSR_READ_4(PCI_ISR
) & ISR_PFE
)
353 CSR_WRITE_4(PCI_ISR
, ISR_PFE
);
358 _pci_io_bs_w_4(void *v
, bus_space_handle_t ioh
, bus_size_t off
,
364 CSR_WRITE_4(PCI_NP_AD
, (ioh
+ off
) & ~3);
365 CSR_WRITE_4(PCI_NP_CBE
, COMMAND_NP_IO_WRITE
);
366 CSR_WRITE_4(PCI_NP_WDATA
, val
);
367 if (CSR_READ_4(PCI_ISR
) & ISR_PFE
)
368 CSR_WRITE_4(PCI_ISR
, ISR_PFE
);
371 #endif /* _pci_io_bs_{rw}_{124} */
375 ixp425_pci_mem_bs_map(void *t
, bus_addr_t bpa
, bus_size_t size
,
376 int cacheable
, bus_space_handle_t
*bshp
)
378 const struct pmap_devmap
*pd
;
387 if ((pd
= pmap_devmap_find_pa(bpa
, size
)) != NULL
) {
388 /* Device was statically mapped. */
389 *bshp
= pd
->pd_va
+ (bpa
- pd
->pd_pa
);
393 endpa
= round_page(bpa
+ size
);
394 offset
= bpa
& PAGE_MASK
;
395 startpa
= trunc_page(bpa
);
398 va
= uvm_km_alloc(kernel_map
, endpa
- startpa
, 0,
399 UVM_KMF_VAONLY
| UVM_KMF_NOWAIT
);
403 /* Store the bus space handle */
406 /* Now map the pages */
407 for (pa
= startpa
; pa
< endpa
; pa
+= PAGE_SIZE
, va
+= PAGE_SIZE
) {
408 pmap_kenter_pa(va
, pa
, VM_PROT_READ
| VM_PROT_WRITE
, 0);
410 *pte
&= ~L2_S_CACHE_MASK
;
413 pmap_update(pmap_kernel());
419 ixp425_pci_mem_bs_unmap(void *t
, bus_space_handle_t bsh
, bus_size_t size
)
424 if (pmap_devmap_find_va(bsh
, size
) != NULL
) {
425 /* Device was statically mapped; nothing to do. */
429 endva
= round_page(bsh
+ size
);
430 va
= trunc_page(bsh
);
432 pmap_kremove(va
, endva
- va
);
433 uvm_km_free(kernel_map
, va
, endva
- va
, UVM_KMF_VAONLY
);
437 ixp425_pci_mem_bs_alloc(void *t
, bus_addr_t rstart
, bus_addr_t rend
,
438 bus_size_t size
, bus_size_t alignment
, bus_size_t boundary
, int cacheable
,
439 bus_addr_t
*bpap
, bus_space_handle_t
*bshp
)
441 panic("ixp425_mem_bs_alloc(): not implemented\n");
445 ixp425_pci_mem_bs_free(void *t
, bus_space_handle_t bsh
, bus_size_t size
)
447 panic("ixp425_mem_bs_free(): not implemented\n");
451 ixp425_pci_mem_bs_vaddr(void *t
, bus_space_handle_t bsh
)
453 return ((void *)bsh
);
455 /* End of ixp425_pci_space.c */