pxa_space.c revision 179595
1179595Sbenno/* $NetBSD: obio_space.c,v 1.6 2003/07/15 00:25:05 lukem Exp $ */ 2179595Sbenno 3179595Sbenno/*- 4179595Sbenno * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc. 5179595Sbenno * All rights reserved. 6179595Sbenno * 7179595Sbenno * Written by Jason R. Thorpe for Wasabi Systems, Inc. 8179595Sbenno * 9179595Sbenno * Redistribution and use in source and binary forms, with or without 10179595Sbenno * modification, are permitted provided that the following conditions 11179595Sbenno * are met: 12179595Sbenno * 1. Redistributions of source code must retain the above copyright 13179595Sbenno * notice, this list of conditions and the following disclaimer. 14179595Sbenno * 2. Redistributions in binary form must reproduce the above copyright 15179595Sbenno * notice, this list of conditions and the following disclaimer in the 16179595Sbenno * documentation and/or other materials provided with the distribution. 17179595Sbenno * 3. All advertising materials mentioning features or use of this software 18179595Sbenno * must display the following acknowledgement: 19179595Sbenno * This product includes software developed for the NetBSD Project by 20179595Sbenno * Wasabi Systems, Inc. 21179595Sbenno * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22179595Sbenno * or promote products derived from this software without specific prior 23179595Sbenno * written permission. 24179595Sbenno * 25179595Sbenno * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26179595Sbenno * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27179595Sbenno * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28179595Sbenno * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29179595Sbenno * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30179595Sbenno * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31179595Sbenno * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32179595Sbenno * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33179595Sbenno * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34179595Sbenno * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35179595Sbenno * POSSIBILITY OF SUCH DAMAGE. 36179595Sbenno */ 37179595Sbenno 38179595Sbenno/* 39179595Sbenno * bus_space functions for PXA devices 40179595Sbenno */ 41179595Sbenno 42179595Sbenno#include <sys/cdefs.h> 43179595Sbenno__FBSDID("$FreeBSD: head/sys/arm/xscale/pxa/pxa_space.c 179595 2008-06-06 05:08:09Z benno $"); 44179595Sbenno 45179595Sbenno#include <sys/param.h> 46179595Sbenno#include <sys/systm.h> 47179595Sbenno#include <sys/bus.h> 48179595Sbenno#include <sys/kernel.h> 49179595Sbenno#include <sys/malloc.h> 50179595Sbenno 51179595Sbenno#include <machine/pcb.h> 52179595Sbenno 53179595Sbenno#include <vm/vm.h> 54179595Sbenno#include <vm/pmap.h> 55179595Sbenno#include <vm/vm_kern.h> 56179595Sbenno#include <vm/vm_extern.h> 57179595Sbenno 58179595Sbenno#include <machine/bus.h> 59179595Sbenno 60179595Sbenno#include <arm/xscale/pxa/pxareg.h> 61179595Sbenno#include <arm/xscale/pxa/pxavar.h> 62179595Sbenno 63179595SbennoMALLOC_DEFINE(M_PXATAG, "PXA bus_space tags", "Bus_space tags for PXA"); 64179595Sbenno 65179595Sbenno/* Prototypes for all the bus_space structure functions */ 66179595Sbennobs_protos(obio); 67179595Sbennobs_protos(generic); 68179595Sbennobs_protos(generic_armv4); 69179595Sbennobs_protos(pxa); 70179595Sbenno 71179595Sbenno/* 72179595Sbenno * The obio bus space tag. This is constant for all instances, so 73179595Sbenno * we never have to explicitly "create" it. 74179595Sbenno */ 75179595Sbennostruct bus_space _base_tag = { 76179595Sbenno /* cookie */ 77179595Sbenno (void *) 0, 78179595Sbenno 79179595Sbenno /* mapping/unmapping */ 80179595Sbenno obio_bs_map, 81179595Sbenno obio_bs_unmap, 82179595Sbenno obio_bs_subregion, 83179595Sbenno 84179595Sbenno /* allocation/deallocation */ 85179595Sbenno obio_bs_alloc, 86179595Sbenno obio_bs_free, 87179595Sbenno 88179595Sbenno /* barrier */ 89179595Sbenno obio_bs_barrier, 90179595Sbenno 91179595Sbenno /* read (single) */ 92179595Sbenno pxa_bs_r_1, 93179595Sbenno pxa_bs_r_2, 94179595Sbenno pxa_bs_r_4, 95179595Sbenno NULL, 96179595Sbenno 97179595Sbenno /* read multiple */ 98179595Sbenno pxa_bs_rm_1, 99179595Sbenno pxa_bs_rm_2, 100179595Sbenno NULL, 101179595Sbenno NULL, 102179595Sbenno 103179595Sbenno /* read region */ 104179595Sbenno pxa_bs_rr_1, 105179595Sbenno NULL, 106179595Sbenno NULL, 107179595Sbenno NULL, 108179595Sbenno 109179595Sbenno /* write (single) */ 110179595Sbenno pxa_bs_w_1, 111179595Sbenno pxa_bs_w_2, 112179595Sbenno pxa_bs_w_4, 113179595Sbenno NULL, 114179595Sbenno 115179595Sbenno /* write multiple */ 116179595Sbenno pxa_bs_wm_1, 117179595Sbenno pxa_bs_wm_2, 118179595Sbenno NULL, 119179595Sbenno NULL, 120179595Sbenno 121179595Sbenno /* write region */ 122179595Sbenno NULL, 123179595Sbenno NULL, 124179595Sbenno NULL, 125179595Sbenno NULL, 126179595Sbenno 127179595Sbenno /* set multiple */ 128179595Sbenno NULL, 129179595Sbenno NULL, 130179595Sbenno NULL, 131179595Sbenno NULL, 132179595Sbenno 133179595Sbenno /* set region */ 134179595Sbenno NULL, 135179595Sbenno NULL, 136179595Sbenno NULL, 137179595Sbenno NULL, 138179595Sbenno 139179595Sbenno /* copy */ 140179595Sbenno NULL, 141179595Sbenno NULL, 142179595Sbenno NULL, 143179595Sbenno NULL, 144179595Sbenno}; 145179595Sbenno 146179595Sbennostatic struct bus_space _obio_tag; 147179595Sbenno 148179595Sbennobus_space_tag_t base_tag = &_base_tag; 149179595Sbennobus_space_tag_t obio_tag = NULL; 150179595Sbenno 151179595Sbennovoid 152179595Sbennopxa_obio_tag_init() 153179595Sbenno{ 154179595Sbenno 155179595Sbenno bcopy(&_base_tag, &_obio_tag, sizeof(struct bus_space)); 156179595Sbenno _obio_tag.bs_cookie = (void *)PXA2X0_PERIPH_OFFSET; 157179595Sbenno obio_tag = &_obio_tag; 158179595Sbenno} 159179595Sbenno 160179595Sbennobus_space_tag_t 161179595Sbennopxa_bus_tag_alloc(bus_addr_t offset) 162179595Sbenno{ 163179595Sbenno struct bus_space *tag; 164179595Sbenno 165179595Sbenno tag = (struct bus_space *)malloc(sizeof(struct bus_space), M_PXATAG, 166179595Sbenno M_WAITOK); 167179595Sbenno if (tag == NULL) { 168179595Sbenno return (NULL); 169179595Sbenno } 170179595Sbenno 171179595Sbenno bcopy(&_base_tag, tag, sizeof(struct bus_space)); 172179595Sbenno tag->bs_cookie = (void *)offset; 173179595Sbenno 174179595Sbenno return ((bus_space_tag_t)tag); 175179595Sbenno} 176179595Sbenno 177179595Sbennoint 178179595Sbennoobio_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags, 179179595Sbenno bus_space_handle_t *bshp) 180179595Sbenno{ 181179595Sbenno const struct pmap_devmap *pd; 182179595Sbenno vm_paddr_t startpa, endpa, pa, offset; 183179595Sbenno vm_offset_t va; 184179595Sbenno pt_entry_t *pte; 185179595Sbenno 186179595Sbenno if ((pd = pmap_devmap_find_pa(bpa, size)) != NULL) { 187179595Sbenno /* Device was statically mapped. */ 188179595Sbenno *bshp = pd->pd_va + (bpa - pd->pd_pa); 189179595Sbenno return (0); 190179595Sbenno } 191179595Sbenno 192179595Sbenno endpa = round_page(bpa + size); 193179595Sbenno offset = bpa & PAGE_MASK; 194179595Sbenno startpa = trunc_page(bpa); 195179595Sbenno 196179595Sbenno va = kmem_alloc(kernel_map, endpa - startpa); 197179595Sbenno if (va == 0) 198179595Sbenno return (ENOMEM); 199179595Sbenno 200179595Sbenno *bshp = va + offset; 201179595Sbenno 202179595Sbenno for (pa = startpa; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) { 203179595Sbenno pmap_kenter(va, pa); 204179595Sbenno pte = vtopte(va); 205179595Sbenno *pte &= ~L2_S_CACHE_MASK; 206179595Sbenno PTE_SYNC(pte); 207179595Sbenno } 208179595Sbenno 209179595Sbenno return (0); 210179595Sbenno} 211179595Sbenno 212179595Sbennoint 213179595Sbennoobio_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, 214179595Sbenno bus_size_t alignment, bus_size_t boundary, int flags, bus_addr_t *bpap, 215179595Sbenno bus_space_handle_t *bshp) 216179595Sbenno{ 217179595Sbenno 218179595Sbenno panic("obio_bs_alloc(): not implemented"); 219179595Sbenno} 220179595Sbenno 221179595Sbenno 222179595Sbennovoid 223179595Sbennoobio_bs_unmap(void *t, bus_space_handle_t h, bus_size_t size) 224179595Sbenno{ 225179595Sbenno vm_offset_t va, endva; 226179595Sbenno 227179595Sbenno if (pmap_devmap_find_va((vm_offset_t)t, size) != NULL) { 228179595Sbenno /* Device was statically mapped; nothing to do. */ 229179595Sbenno return; 230179595Sbenno } 231179595Sbenno 232179595Sbenno endva = round_page((vm_offset_t)t + size); 233179595Sbenno va = trunc_page((vm_offset_t)t); 234179595Sbenno 235179595Sbenno while (va < endva) { 236179595Sbenno pmap_kremove(va); 237179595Sbenno va += PAGE_SIZE; 238179595Sbenno } 239179595Sbenno kmem_free(kernel_map, va, endva - va); 240179595Sbenno} 241179595Sbenno 242179595Sbennovoid 243179595Sbennoobio_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size) 244179595Sbenno{ 245179595Sbenno 246179595Sbenno panic("obio_bs_free(): not implemented"); 247179595Sbenno} 248179595Sbenno 249179595Sbennoint 250179595Sbennoobio_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset, 251179595Sbenno bus_size_t size, bus_space_handle_t *nbshp) 252179595Sbenno{ 253179595Sbenno 254179595Sbenno *nbshp = bsh + offset; 255179595Sbenno return (0); 256179595Sbenno} 257179595Sbenno 258179595Sbennovoid 259179595Sbennoobio_bs_barrier(void *t, bus_space_handle_t bsh, bus_size_t offset, 260179595Sbenno bus_size_t len, int flags) 261179595Sbenno{ 262179595Sbenno 263179595Sbenno /* Nothing to do. */ 264179595Sbenno} 265179595Sbenno 266179595Sbenno#define READ_SINGLE(type, proto, base) \ 267179595Sbenno type \ 268179595Sbenno proto(void *cookie, bus_space_handle_t bsh, bus_size_t offset) \ 269179595Sbenno { \ 270179595Sbenno bus_addr_t tag_offset; \ 271179595Sbenno type value; \ 272179595Sbenno tag_offset = (bus_addr_t)cookie; \ 273179595Sbenno value = base(NULL, bsh + tag_offset, offset); \ 274179595Sbenno return (value); \ 275179595Sbenno } 276179595Sbenno 277179595SbennoREAD_SINGLE(u_int8_t, pxa_bs_r_1, generic_bs_r_1) 278179595SbennoREAD_SINGLE(u_int16_t, pxa_bs_r_2, generic_armv4_bs_r_2) 279179595SbennoREAD_SINGLE(u_int32_t, pxa_bs_r_4, generic_bs_r_4) 280179595Sbenno 281179595Sbenno#undef READ_SINGLE 282179595Sbenno 283179595Sbenno#define WRITE_SINGLE(type, proto, base) \ 284179595Sbenno void \ 285179595Sbenno proto(void *cookie, bus_space_handle_t bsh, bus_size_t offset, \ 286179595Sbenno type value) \ 287179595Sbenno { \ 288179595Sbenno bus_addr_t tag_offset; \ 289179595Sbenno tag_offset = (bus_addr_t)cookie; \ 290179595Sbenno base(NULL, bsh + tag_offset, offset, value); \ 291179595Sbenno } 292179595Sbenno 293179595SbennoWRITE_SINGLE(u_int8_t, pxa_bs_w_1, generic_bs_w_1) 294179595SbennoWRITE_SINGLE(u_int16_t, pxa_bs_w_2, generic_armv4_bs_w_2) 295179595SbennoWRITE_SINGLE(u_int32_t, pxa_bs_w_4, generic_bs_w_4) 296179595Sbenno 297179595Sbenno#undef WRITE_SINGLE 298179595Sbenno 299179595Sbenno#define READ_MULTI(type, proto, base) \ 300179595Sbenno void \ 301179595Sbenno proto(void *cookie, bus_space_handle_t bsh, bus_size_t offset, \ 302179595Sbenno type *dest, bus_size_t count) \ 303179595Sbenno { \ 304179595Sbenno bus_addr_t tag_offset; \ 305179595Sbenno tag_offset = (bus_addr_t)cookie; \ 306179595Sbenno base(NULL, bsh + tag_offset, offset, dest, count); \ 307179595Sbenno } 308179595Sbenno 309179595SbennoREAD_MULTI(u_int8_t, pxa_bs_rm_1, generic_bs_rm_1) 310179595SbennoREAD_MULTI(u_int16_t, pxa_bs_rm_2, generic_armv4_bs_rm_2) 311179595Sbenno 312179595SbennoREAD_MULTI(u_int8_t, pxa_bs_rr_1, generic_bs_rr_1) 313179595Sbenno 314179595Sbenno#undef READ_MULTI 315179595Sbenno 316179595Sbenno#define WRITE_MULTI(type, proto, base) \ 317179595Sbenno void \ 318179595Sbenno proto(void *cookie, bus_space_handle_t bsh, bus_size_t offset, \ 319179595Sbenno const type *src, bus_size_t count) \ 320179595Sbenno { \ 321179595Sbenno bus_addr_t tag_offset; \ 322179595Sbenno tag_offset = (bus_addr_t)cookie; \ 323179595Sbenno base(NULL, bsh + tag_offset, offset, src, count); \ 324179595Sbenno } 325179595Sbenno 326179595SbennoWRITE_MULTI(u_int8_t, pxa_bs_wm_1, generic_bs_wm_1) 327179595SbennoWRITE_MULTI(u_int16_t, pxa_bs_wm_2, generic_armv4_bs_wm_2) 328179595Sbenno 329179595Sbenno#undef WRITE_MULTI 330