1a1cd472aSRafal Jaworowski /*- 2a1cd472aSRafal Jaworowski * Copyright (C) 2008 Semihalf, Rafal Jaworowski 3a1cd472aSRafal Jaworowski * All rights reserved. 4a1cd472aSRafal Jaworowski * 5a1cd472aSRafal Jaworowski * Redistribution and use in source and binary forms, with or without 6a1cd472aSRafal Jaworowski * modification, are permitted provided that the following conditions 7a1cd472aSRafal Jaworowski * are met: 8a1cd472aSRafal Jaworowski * 1. Redistributions of source code must retain the above copyright 9a1cd472aSRafal Jaworowski * notice, this list of conditions and the following disclaimer. 10a1cd472aSRafal Jaworowski * 2. Redistributions in binary form must reproduce the above copyright 11a1cd472aSRafal Jaworowski * notice, this list of conditions and the following disclaimer in the 12a1cd472aSRafal Jaworowski * documentation and/or other materials provided with the distribution. 13a1cd472aSRafal Jaworowski * 14a1cd472aSRafal Jaworowski * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15a1cd472aSRafal Jaworowski * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16a1cd472aSRafal Jaworowski * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17a1cd472aSRafal Jaworowski * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 18a1cd472aSRafal Jaworowski * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19a1cd472aSRafal Jaworowski * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20a1cd472aSRafal Jaworowski * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21a1cd472aSRafal Jaworowski * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22a1cd472aSRafal Jaworowski * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23a1cd472aSRafal Jaworowski * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24a1cd472aSRafal Jaworowski * SUCH DAMAGE. 25a1cd472aSRafal Jaworowski */ 26a1cd472aSRafal Jaworowski 27a1cd472aSRafal Jaworowski #include <sys/cdefs.h> 28a1cd472aSRafal Jaworowski __FBSDID("$FreeBSD$"); 29a1cd472aSRafal Jaworowski 30a1cd472aSRafal Jaworowski #include <sys/param.h> 31a1cd472aSRafal Jaworowski #include <sys/systm.h> 32d1d3233eSRafal Jaworowski #include <sys/lock.h> 33d1d3233eSRafal Jaworowski #include <sys/mutex.h> 34d1d3233eSRafal Jaworowski #include <sys/rman.h> 35a1cd472aSRafal Jaworowski 368b79898eSRafal Jaworowski #include <vm/vm.h> 378b79898eSRafal Jaworowski #include <vm/vm_param.h> 388b79898eSRafal Jaworowski 39a1cd472aSRafal Jaworowski #include <machine/cpu.h> 40a1cd472aSRafal Jaworowski #include <machine/cpufunc.h> 412a134f71SNathan Whitehorn #include <machine/pio.h> 42a1cd472aSRafal Jaworowski #include <machine/spr.h> 43a1cd472aSRafal Jaworowski 44fe48da3fSRafal Jaworowski #include <powerpc/mpc85xx/mpc85xx.h> 458b79898eSRafal Jaworowski 46a1cd472aSRafal Jaworowski /* 47a1cd472aSRafal Jaworowski * MPC85xx system specific routines 48a1cd472aSRafal Jaworowski */ 49a1cd472aSRafal Jaworowski 50fe48da3fSRafal Jaworowski uint32_t 51fe48da3fSRafal Jaworowski ccsr_read4(uintptr_t addr) 52a1cd472aSRafal Jaworowski { 53fe48da3fSRafal Jaworowski volatile uint32_t *ptr = (void *)addr; 54a1cd472aSRafal Jaworowski 55fe48da3fSRafal Jaworowski return (*ptr); 56fe48da3fSRafal Jaworowski } 57fe48da3fSRafal Jaworowski 58fe48da3fSRafal Jaworowski void 59fe48da3fSRafal Jaworowski ccsr_write4(uintptr_t addr, uint32_t val) 60fe48da3fSRafal Jaworowski { 61fe48da3fSRafal Jaworowski volatile uint32_t *ptr = (void *)addr; 62fe48da3fSRafal Jaworowski 63fe48da3fSRafal Jaworowski *ptr = val; 6413d47f30SNathan Whitehorn powerpc_iomb(); 65fe48da3fSRafal Jaworowski } 66fe48da3fSRafal Jaworowski 67389e4721SRafal Jaworowski int 6825c22eb4SRafal Jaworowski law_getmax(void) 6925c22eb4SRafal Jaworowski { 7025c22eb4SRafal Jaworowski uint32_t ver; 7125c22eb4SRafal Jaworowski 7225c22eb4SRafal Jaworowski ver = SVR_VER(mfspr(SPR_SVR)); 738a4b7c64SMarcel Moolenaar if (ver == SVR_MPC8555E || ver == SVR_MPC8555) 7425c22eb4SRafal Jaworowski return (8); 758a4b7c64SMarcel Moolenaar if (ver == SVR_MPC8548E || ver == SVR_MPC8548 || 768a4b7c64SMarcel Moolenaar ver == SVR_MPC8533E || ver == SVR_MPC8533) 778a4b7c64SMarcel Moolenaar return (10); 788a4b7c64SMarcel Moolenaar 798a4b7c64SMarcel Moolenaar return (12); 8025c22eb4SRafal Jaworowski } 8125c22eb4SRafal Jaworowski 8225c22eb4SRafal Jaworowski #define _LAW_SR(trgt,size) (0x80000000 | (trgt << 20) | (ffsl(size) - 2)) 8325c22eb4SRafal Jaworowski #define _LAW_BAR(addr) (addr >> 12) 8425c22eb4SRafal Jaworowski 8525c22eb4SRafal Jaworowski int 8625c22eb4SRafal Jaworowski law_enable(int trgt, u_long addr, u_long size) 8725c22eb4SRafal Jaworowski { 8825c22eb4SRafal Jaworowski uint32_t bar, sr; 8925c22eb4SRafal Jaworowski int i, law_max; 9025c22eb4SRafal Jaworowski 91*e845939dSMarcel Moolenaar if (size == 0) 92*e845939dSMarcel Moolenaar return (0); 93*e845939dSMarcel Moolenaar 9425c22eb4SRafal Jaworowski law_max = law_getmax(); 9525c22eb4SRafal Jaworowski bar = _LAW_BAR(addr); 9625c22eb4SRafal Jaworowski sr = _LAW_SR(trgt, size); 9725c22eb4SRafal Jaworowski 9825c22eb4SRafal Jaworowski /* Bail if already programmed. */ 9925c22eb4SRafal Jaworowski for (i = 0; i < law_max; i++) 10025c22eb4SRafal Jaworowski if (sr == ccsr_read4(OCP85XX_LAWSR(i)) && 10125c22eb4SRafal Jaworowski bar == ccsr_read4(OCP85XX_LAWBAR(i))) 10225c22eb4SRafal Jaworowski return (0); 10325c22eb4SRafal Jaworowski 10425c22eb4SRafal Jaworowski /* Find an unused access window. */ 10525c22eb4SRafal Jaworowski for (i = 0; i < law_max; i++) 10625c22eb4SRafal Jaworowski if ((ccsr_read4(OCP85XX_LAWSR(i)) & 0x80000000) == 0) 10725c22eb4SRafal Jaworowski break; 10825c22eb4SRafal Jaworowski 10925c22eb4SRafal Jaworowski if (i == law_max) 11025c22eb4SRafal Jaworowski return (ENOSPC); 11125c22eb4SRafal Jaworowski 11225c22eb4SRafal Jaworowski ccsr_write4(OCP85XX_LAWBAR(i), bar); 11325c22eb4SRafal Jaworowski ccsr_write4(OCP85XX_LAWSR(i), sr); 11425c22eb4SRafal Jaworowski return (0); 11525c22eb4SRafal Jaworowski } 11625c22eb4SRafal Jaworowski 11725c22eb4SRafal Jaworowski int 11825c22eb4SRafal Jaworowski law_disable(int trgt, u_long addr, u_long size) 11925c22eb4SRafal Jaworowski { 12025c22eb4SRafal Jaworowski uint32_t bar, sr; 12125c22eb4SRafal Jaworowski int i, law_max; 12225c22eb4SRafal Jaworowski 12325c22eb4SRafal Jaworowski law_max = law_getmax(); 12425c22eb4SRafal Jaworowski bar = _LAW_BAR(addr); 12525c22eb4SRafal Jaworowski sr = _LAW_SR(trgt, size); 12625c22eb4SRafal Jaworowski 12725c22eb4SRafal Jaworowski /* Find and disable requested LAW. */ 12825c22eb4SRafal Jaworowski for (i = 0; i < law_max; i++) 12925c22eb4SRafal Jaworowski if (sr == ccsr_read4(OCP85XX_LAWSR(i)) && 13025c22eb4SRafal Jaworowski bar == ccsr_read4(OCP85XX_LAWBAR(i))) { 13125c22eb4SRafal Jaworowski ccsr_write4(OCP85XX_LAWBAR(i), 0); 13225c22eb4SRafal Jaworowski ccsr_write4(OCP85XX_LAWSR(i), 0); 13325c22eb4SRafal Jaworowski return (0); 13425c22eb4SRafal Jaworowski } 13525c22eb4SRafal Jaworowski 13625c22eb4SRafal Jaworowski return (ENOENT); 13725c22eb4SRafal Jaworowski } 13825c22eb4SRafal Jaworowski 139d1d3233eSRafal Jaworowski int 140d1d3233eSRafal Jaworowski law_pci_target(struct resource *res, int *trgt_mem, int *trgt_io) 141d1d3233eSRafal Jaworowski { 142d1d3233eSRafal Jaworowski u_long start; 143d1d3233eSRafal Jaworowski uint32_t ver; 144d1d3233eSRafal Jaworowski int trgt, rv; 145d1d3233eSRafal Jaworowski 146d1d3233eSRafal Jaworowski ver = SVR_VER(mfspr(SPR_SVR)); 147d1d3233eSRafal Jaworowski 148d1d3233eSRafal Jaworowski start = rman_get_start(res) & 0xf000; 149d1d3233eSRafal Jaworowski 150d1d3233eSRafal Jaworowski rv = 0; 151d1d3233eSRafal Jaworowski trgt = -1; 152d1d3233eSRafal Jaworowski switch (start) { 153d1d3233eSRafal Jaworowski case 0x8000: 154d1d3233eSRafal Jaworowski trgt = 0; 155d1d3233eSRafal Jaworowski break; 156d1d3233eSRafal Jaworowski case 0x9000: 157d1d3233eSRafal Jaworowski trgt = 1; 158d1d3233eSRafal Jaworowski break; 159d1d3233eSRafal Jaworowski case 0xa000: 1608a4b7c64SMarcel Moolenaar if (ver == SVR_MPC8548E || ver == SVR_MPC8548) 1618a4b7c64SMarcel Moolenaar trgt = 3; 162d1d3233eSRafal Jaworowski else 1638a4b7c64SMarcel Moolenaar trgt = 2; 1648a4b7c64SMarcel Moolenaar break; 1658a4b7c64SMarcel Moolenaar case 0xb000: 1668a4b7c64SMarcel Moolenaar if (ver == SVR_MPC8548E || ver == SVR_MPC8548) 167d1d3233eSRafal Jaworowski rv = EINVAL; 1688a4b7c64SMarcel Moolenaar else 1698a4b7c64SMarcel Moolenaar trgt = 3; 170d1d3233eSRafal Jaworowski break; 171d1d3233eSRafal Jaworowski default: 172d1d3233eSRafal Jaworowski rv = ENXIO; 173d1d3233eSRafal Jaworowski } 174*e845939dSMarcel Moolenaar if (rv == 0) { 175*e845939dSMarcel Moolenaar *trgt_mem = trgt; 176*e845939dSMarcel Moolenaar *trgt_io = trgt; 177*e845939dSMarcel Moolenaar } 178d1d3233eSRafal Jaworowski return (rv); 179d1d3233eSRafal Jaworowski } 180d1d3233eSRafal Jaworowski 181