1130803Smarcel/* $NetBSD: jensenio_bus_intio.c,v 1.7 2023/12/04 00:32:10 thorpej Exp $ */ 2130803Smarcel 3130803Smarcel/*- 4130803Smarcel * Copyright (c) 1999 The NetBSD Foundation, Inc. 5130803Smarcel * All rights reserved. 6130803Smarcel * 7130803Smarcel * This code is derived from software contributed to The NetBSD Foundation 8130803Smarcel * by Jason R. Thorpe. 9130803Smarcel * 10130803Smarcel * Redistribution and use in source and binary forms, with or without 11130803Smarcel * modification, are permitted provided that the following conditions 12130803Smarcel * are met: 13130803Smarcel * 1. Redistributions of source code must retain the above copyright 14130803Smarcel * notice, this list of conditions and the following disclaimer. 15130803Smarcel * 2. Redistributions in binary form must reproduce the above copyright 16130803Smarcel * notice, this list of conditions and the following disclaimer in the 17130803Smarcel * documentation and/or other materials provided with the distribution. 18130803Smarcel * 19130803Smarcel * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20130803Smarcel * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21130803Smarcel * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22130803Smarcel * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23130803Smarcel * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24130803Smarcel * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25130803Smarcel * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26130803Smarcel * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27130803Smarcel * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28130803Smarcel * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29130803Smarcel * POSSIBILITY OF SUCH DAMAGE. 30130803Smarcel */ 31130803Smarcel 32130803Smarcel#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 33130803Smarcel 34130803Smarcel__KERNEL_RCSID(0, "$NetBSD: jensenio_bus_intio.c,v 1.7 2023/12/04 00:32:10 thorpej Exp $"); 35130803Smarcel 36130803Smarcel#include <sys/param.h> 37130803Smarcel#include <sys/systm.h> 38130803Smarcel#include <sys/device.h> 39130803Smarcel#include <sys/vmem.h> 40130803Smarcel 41130803Smarcel#include <sys/bus.h> 42130803Smarcel 43130803Smarcel#include <dev/eisa/eisavar.h> 44130803Smarcel 45130803Smarcel#include <dev/isa/isavar.h> 46130803Smarcel 47130803Smarcel#include <alpha/jensenio/jensenioreg.h> 48130803Smarcel#include <alpha/jensenio/jenseniovar.h> 49130803Smarcel 50130803Smarcel/* mapping/unmapping */ 51130803Smarcelint jensenio_intio_map(void *, bus_addr_t, bus_size_t, int, 52130803Smarcel bus_space_handle_t *, int); 53130803Smarcelvoid jensenio_intio_unmap(void *, bus_space_handle_t, 54130803Smarcel bus_size_t, int); 55130803Smarcelint jensenio_intio_subregion(void *, bus_space_handle_t, 56130803Smarcel bus_size_t, bus_size_t, bus_space_handle_t *); 57130803Smarcel 58130803Smarcel/* allocation/deallocation */ 59130803Smarcel /* Not supported for Internal space */ 60130803Smarcel 61130803Smarcel/* barrier */ 62130803Smarcelstatic inline void jensenio_intio_barrier(void *, bus_space_handle_t, 63130803Smarcel bus_size_t, bus_size_t, int); 64130803Smarcel 65130803Smarcel/* read (single) */ 66130803Smarcelstatic inline uint8_t jensenio_intio_read_1(void *, bus_space_handle_t, bus_size_t); 67130803Smarcel 68130803Smarcel/* read multiple */ 69130803Smarcelvoid jensenio_intio_read_multi_1(void *, bus_space_handle_t, 70130803Smarcel bus_size_t, uint8_t *, bus_size_t); 71130803Smarcel 72130803Smarcel/* read region */ 73130803Smarcel /* Not supported for Internal space */ 74130803Smarcel 75130803Smarcel/* write (single) */ 76130803Smarcelstatic inline void jensenio_intio_write_1(void *, bus_space_handle_t, 77130803Smarcel bus_size_t, uint8_t); 78130803Smarcel 79130803Smarcel/* write multiple */ 80130803Smarcelvoid jensenio_intio_write_multi_1(void *, bus_space_handle_t, 81130803Smarcel bus_size_t, const uint8_t *, bus_size_t); 82130803Smarcel 83130803Smarcel/* write region */ 84130803Smarcel /* Not supported for Internal space */ 85130803Smarcel 86130803Smarcel/* set multiple */ 87130803Smarcelvoid jensenio_intio_set_multi_1(void *, bus_space_handle_t, 88130803Smarcel bus_size_t, uint8_t, bus_size_t); 89130803Smarcel 90130803Smarcel/* set region */ 91130803Smarcel /* Not supported for Internal space */ 92130803Smarcel 93130803Smarcel/* copy */ 94130803Smarcel /* Not supported for Internal space */ 95130803Smarcel 96130803Smarcelvoid 97130803Smarceljensenio_bus_intio_init(bus_space_tag_t t, void *v) 98130803Smarcel{ 99130803Smarcel 100130803Smarcel /* 101130803Smarcel * Initialize the bus space tag. 102130803Smarcel */ 103130803Smarcel 104130803Smarcel memset(t, 0, sizeof(*t)); 105130803Smarcel 106130803Smarcel /* cookie */ 107130803Smarcel t->abs_cookie = v; 108130803Smarcel 109130803Smarcel /* mapping/unmapping */ 110130803Smarcel t->abs_map = jensenio_intio_map; 111130803Smarcel t->abs_unmap = jensenio_intio_unmap; 112130803Smarcel t->abs_subregion = jensenio_intio_subregion; 113130803Smarcel 114130803Smarcel /* barrier */ 115130803Smarcel t->abs_barrier = jensenio_intio_barrier; 116130803Smarcel 117130803Smarcel /* read (single) */ 118130803Smarcel t->abs_r_1 = jensenio_intio_read_1; 119130803Smarcel 120130803Smarcel /* read multiple */ 121130803Smarcel t->abs_rm_1 = jensenio_intio_read_multi_1; 122130803Smarcel 123130803Smarcel /* write (single) */ 124130803Smarcel t->abs_w_1 = jensenio_intio_write_1; 125130803Smarcel 126130803Smarcel /* write multiple */ 127130803Smarcel t->abs_wm_1 = jensenio_intio_write_multi_1; 128130803Smarcel 129130803Smarcel /* set multiple */ 130130803Smarcel t->abs_sm_1 = jensenio_intio_set_multi_1; 131130803Smarcel 132130803Smarcel /* 133130803Smarcel * Extent map is already set up. 134130803Smarcel */ 135130803Smarcel} 136130803Smarcel 137130803Smarcelint 138130803Smarceljensenio_intio_map(void *v, bus_addr_t ioaddr, bus_size_t iosize, int flags, 139130803Smarcel bus_space_handle_t *iohp, int acct) 140130803Smarcel{ 141130803Smarcel struct jensenio_config *jcp = v; 142130803Smarcel int linear = flags & BUS_SPACE_MAP_LINEAR; 143130803Smarcel int error; 144130803Smarcel 145130803Smarcel /* 146130803Smarcel * Can't map i/o space linearly. 147130803Smarcel */ 148130803Smarcel if (linear) 149130803Smarcel return (EOPNOTSUPP); 150130803Smarcel 151130803Smarcel if (acct) { 152130803Smarcel#ifdef EXTENT_DEBUG 153130803Smarcel printf("intio: allocating 0x%lx to 0x%lx\n", ioaddr, 154130803Smarcel ioaddr + iosize - 1); 155130803Smarcel#endif 156130803Smarcel error = vmem_xalloc_addr(jcp->jc_io_arena, ioaddr, iosize, 157130803Smarcel VM_NOSLEEP); 158130803Smarcel if (error) { 159130803Smarcel#ifdef EXTENT_DEBUG 160130803Smarcel printf("intio: allocation failed (%d)\n", error); 161130803Smarcel /* vmem_print(jcp->jc_io_arena); XXX */ 162130803Smarcel#endif 163130803Smarcel return (error); 164130803Smarcel } 165130803Smarcel } 166130803Smarcel 167130803Smarcel *iohp = ALPHA_PHYS_TO_K0SEG((ioaddr << 9) + JENSEN_VL82C106); 168130803Smarcel return (0); 169130803Smarcel} 170130803Smarcel 171130803Smarcelvoid 172130803Smarceljensenio_intio_unmap(void *v, bus_space_handle_t ioh, bus_size_t iosize, 173130803Smarcel int acct) 174130803Smarcel{ 175130803Smarcel struct jensenio_config *jcp = v; 176130803Smarcel bus_addr_t ioaddr; 177130803Smarcel 178130803Smarcel if (acct == 0) 179130803Smarcel return; 180130803Smarcel 181130803Smarcel#ifdef EXTENT_DEBUG 182130803Smarcel printf("intio: freeing handle 0x%lx for 0x%lx\n", ioh, iosize); 183130803Smarcel#endif 184130803Smarcel 185130803Smarcel ioh = ALPHA_K0SEG_TO_PHYS(ioh); 186130803Smarcel 187130803Smarcel ioaddr = (ioh - JENSEN_VL82C106) >> 9; 188130803Smarcel 189130803Smarcel#ifdef EXTENT_DEBUG 190130803Smarcel printf("intio: freeing 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1); 191130803Smarcel#endif 192130803Smarcel vmem_xfree(jcp->jc_io_arena, ioaddr, iosize); 193130803Smarcel} 194130803Smarcel 195130803Smarcelint 196130803Smarceljensenio_intio_subregion(void *v, bus_space_handle_t ioh, bus_size_t offset, 197130803Smarcel bus_size_t size, bus_space_handle_t *nioh) 198130803Smarcel{ 199130803Smarcel 200130803Smarcel *nioh = ioh + (offset << 9); 201130803Smarcel return (0); 202130803Smarcel} 203130803Smarcel 204130803Smarcelstatic inline void 205130803Smarceljensenio_intio_barrier(void *v, bus_space_handle_t h, bus_size_t o, 206130803Smarcel bus_size_t l, int f) 207130803Smarcel{ 208130803Smarcel 209130803Smarcel if ((f & BUS_SPACE_BARRIER_READ) != 0) 210130803Smarcel alpha_mb(); 211130803Smarcel else if ((f & BUS_SPACE_BARRIER_WRITE) != 0) 212130803Smarcel alpha_wmb(); 213130803Smarcel} 214130803Smarcel 215130803Smarcelstatic inline uint8_t 216130803Smarceljensenio_intio_read_1(void *v, bus_space_handle_t ioh, bus_size_t off) 217130803Smarcel{ 218130803Smarcel register uint32_t *port; 219130803Smarcel 220130803Smarcel alpha_mb(); 221130803Smarcel 222130803Smarcel port = (uint32_t *)(ioh + (off << 9)); 223130803Smarcel return (*port & 0xff); 224130803Smarcel} 225130803Smarcel 226130803Smarcelvoid 227130803Smarceljensenio_intio_read_multi_1(void *v, bus_space_handle_t h, bus_size_t o, 228130803Smarcel uint8_t *a, bus_size_t c) 229130803Smarcel{ 230130803Smarcel 231130803Smarcel while (c-- > 0) { 232130803Smarcel jensenio_intio_barrier(v, h, o, sizeof *a, 233130803Smarcel BUS_SPACE_BARRIER_READ); 234130803Smarcel *a++ = jensenio_intio_read_1(v, h, o); 235130803Smarcel } 236130803Smarcel} 237130803Smarcel 238130803Smarcelstatic inline void 239130803Smarceljensenio_intio_write_1(void *v, bus_space_handle_t ioh, bus_size_t off, 240130803Smarcel uint8_t val) 241130803Smarcel{ 242130803Smarcel register uint32_t *port; 243130803Smarcel 244130803Smarcel port = (uint32_t *)(ioh + (off << 9)); 245130803Smarcel *port = val; 246130803Smarcel alpha_mb(); 247130803Smarcel} 248130803Smarcel 249130803Smarcelvoid 250130803Smarceljensenio_intio_write_multi_1(void *v, bus_space_handle_t h, bus_size_t o, 251130803Smarcel const uint8_t *a, bus_size_t c) 252130803Smarcel{ 253130803Smarcel 254130803Smarcel while (c-- > 0) { 255130803Smarcel jensenio_intio_write_1(v, h, o, *a++); 256130803Smarcel jensenio_intio_barrier(v, h, o, sizeof *a, 257130803Smarcel BUS_SPACE_BARRIER_WRITE); 258130803Smarcel } 259130803Smarcel} 260130803Smarcel 261130803Smarcelvoid 262130803Smarceljensenio_intio_set_multi_1(void *v, bus_space_handle_t h, bus_size_t o, 263130803Smarcel uint8_t val, bus_size_t c) 264130803Smarcel{ 265130803Smarcel 266130803Smarcel while (c-- > 0) { 267130803Smarcel jensenio_intio_write_1(v, h, o, val); 268130803Smarcel jensenio_intio_barrier(v, h, o, sizeof val, 269130803Smarcel BUS_SPACE_BARRIER_WRITE); 270130803Smarcel } 271130803Smarcel} 272130803Smarcel