mpc85xx.c revision 257178
1178596Sraj/*- 2178596Sraj * Copyright (C) 2008 Semihalf, Rafal Jaworowski 3178596Sraj * All rights reserved. 4178596Sraj * 5178596Sraj * Redistribution and use in source and binary forms, with or without 6178596Sraj * modification, are permitted provided that the following conditions 7178596Sraj * are met: 8178596Sraj * 1. Redistributions of source code must retain the above copyright 9178596Sraj * notice, this list of conditions and the following disclaimer. 10178596Sraj * 2. Redistributions in binary form must reproduce the above copyright 11178596Sraj * notice, this list of conditions and the following disclaimer in the 12178596Sraj * documentation and/or other materials provided with the distribution. 13178596Sraj * 14178596Sraj * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15178596Sraj * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16178596Sraj * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17178596Sraj * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 18178596Sraj * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19178596Sraj * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20178596Sraj * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21178596Sraj * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22178596Sraj * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23178596Sraj * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24178596Sraj * SUCH DAMAGE. 25178596Sraj */ 26178596Sraj 27178596Sraj#include <sys/cdefs.h> 28178596Sraj__FBSDID("$FreeBSD: head/sys/powerpc/mpc85xx/mpc85xx.c 257178 2013-10-26 18:18:14Z nwhitehorn $"); 29178596Sraj 30178596Sraj#include <sys/param.h> 31178596Sraj#include <sys/systm.h> 32209908Sraj#include <sys/lock.h> 33209908Sraj#include <sys/mutex.h> 34209908Sraj#include <sys/rman.h> 35178596Sraj 36178597Sraj#include <vm/vm.h> 37178597Sraj#include <vm/vm_param.h> 38178597Sraj 39178596Sraj#include <machine/cpu.h> 40178596Sraj#include <machine/cpufunc.h> 41234609Snwhitehorn#include <machine/pio.h> 42178596Sraj#include <machine/spr.h> 43178596Sraj 44257178Snwhitehorn#include <dev/fdt/fdt_common.h> 45257178Snwhitehorn 46186227Sraj#include <powerpc/mpc85xx/mpc85xx.h> 47178597Sraj 48178596Sraj/* 49178596Sraj * MPC85xx system specific routines 50178596Sraj */ 51178596Sraj 52186227Srajuint32_t 53186227Srajccsr_read4(uintptr_t addr) 54186227Sraj{ 55186227Sraj volatile uint32_t *ptr = (void *)addr; 56186227Sraj 57186227Sraj return (*ptr); 58186227Sraj} 59186227Sraj 60178596Srajvoid 61186227Srajccsr_write4(uintptr_t addr, uint32_t val) 62178596Sraj{ 63186227Sraj volatile uint32_t *ptr = (void *)addr; 64178596Sraj 65186227Sraj *ptr = val; 66234579Snwhitehorn powerpc_iomb(); 67186227Sraj} 68186227Sraj 69189757Srajint 70186288Srajlaw_getmax(void) 71186288Sraj{ 72186288Sraj uint32_t ver; 73186288Sraj 74186288Sraj ver = SVR_VER(mfspr(SPR_SVR)); 75222428Smarcel if (ver == SVR_MPC8555E || ver == SVR_MPC8555) 76222428Smarcel return (8); 77222428Smarcel if (ver == SVR_MPC8548E || ver == SVR_MPC8548 || 78222428Smarcel ver == SVR_MPC8533E || ver == SVR_MPC8533) 79189757Sraj return (10); 80222428Smarcel 81222428Smarcel return (12); 82186288Sraj} 83186288Sraj 84186288Sraj#define _LAW_SR(trgt,size) (0x80000000 | (trgt << 20) | (ffsl(size) - 2)) 85186288Sraj#define _LAW_BAR(addr) (addr >> 12) 86186288Sraj 87186288Srajint 88186288Srajlaw_enable(int trgt, u_long addr, u_long size) 89186288Sraj{ 90186288Sraj uint32_t bar, sr; 91186288Sraj int i, law_max; 92186288Sraj 93235934Smarcel if (size == 0) 94235934Smarcel return (0); 95235934Smarcel 96186288Sraj law_max = law_getmax(); 97186288Sraj bar = _LAW_BAR(addr); 98186288Sraj sr = _LAW_SR(trgt, size); 99186288Sraj 100186288Sraj /* Bail if already programmed. */ 101186288Sraj for (i = 0; i < law_max; i++) 102186288Sraj if (sr == ccsr_read4(OCP85XX_LAWSR(i)) && 103186288Sraj bar == ccsr_read4(OCP85XX_LAWBAR(i))) 104186288Sraj return (0); 105186288Sraj 106186288Sraj /* Find an unused access window. */ 107186288Sraj for (i = 0; i < law_max; i++) 108186288Sraj if ((ccsr_read4(OCP85XX_LAWSR(i)) & 0x80000000) == 0) 109186288Sraj break; 110186288Sraj 111186288Sraj if (i == law_max) 112186288Sraj return (ENOSPC); 113186288Sraj 114186288Sraj ccsr_write4(OCP85XX_LAWBAR(i), bar); 115186288Sraj ccsr_write4(OCP85XX_LAWSR(i), sr); 116186288Sraj return (0); 117186288Sraj} 118186288Sraj 119186288Srajint 120186288Srajlaw_disable(int trgt, u_long addr, u_long size) 121186288Sraj{ 122186288Sraj uint32_t bar, sr; 123186288Sraj int i, law_max; 124186288Sraj 125186288Sraj law_max = law_getmax(); 126186288Sraj bar = _LAW_BAR(addr); 127186288Sraj sr = _LAW_SR(trgt, size); 128186288Sraj 129186288Sraj /* Find and disable requested LAW. */ 130186288Sraj for (i = 0; i < law_max; i++) 131186288Sraj if (sr == ccsr_read4(OCP85XX_LAWSR(i)) && 132186288Sraj bar == ccsr_read4(OCP85XX_LAWBAR(i))) { 133186288Sraj ccsr_write4(OCP85XX_LAWBAR(i), 0); 134186288Sraj ccsr_write4(OCP85XX_LAWSR(i), 0); 135186288Sraj return (0); 136186288Sraj } 137186288Sraj 138186288Sraj return (ENOENT); 139186288Sraj} 140186288Sraj 141209908Srajint 142209908Srajlaw_pci_target(struct resource *res, int *trgt_mem, int *trgt_io) 143209908Sraj{ 144209908Sraj u_long start; 145209908Sraj uint32_t ver; 146209908Sraj int trgt, rv; 147209908Sraj 148209908Sraj ver = SVR_VER(mfspr(SPR_SVR)); 149209908Sraj 150209908Sraj start = rman_get_start(res) & 0xf000; 151209908Sraj 152209908Sraj rv = 0; 153209908Sraj trgt = -1; 154209908Sraj switch (start) { 155209908Sraj case 0x8000: 156209908Sraj trgt = 0; 157209908Sraj break; 158209908Sraj case 0x9000: 159209908Sraj trgt = 1; 160209908Sraj break; 161209908Sraj case 0xa000: 162222428Smarcel if (ver == SVR_MPC8548E || ver == SVR_MPC8548) 163222428Smarcel trgt = 3; 164222428Smarcel else 165209908Sraj trgt = 2; 166222428Smarcel break; 167222428Smarcel case 0xb000: 168222428Smarcel if (ver == SVR_MPC8548E || ver == SVR_MPC8548) 169222428Smarcel rv = EINVAL; 170209908Sraj else 171222428Smarcel trgt = 3; 172209908Sraj break; 173209908Sraj default: 174209908Sraj rv = ENXIO; 175209908Sraj } 176235934Smarcel if (rv == 0) { 177235934Smarcel *trgt_mem = trgt; 178235934Smarcel *trgt_io = trgt; 179235934Smarcel } 180209908Sraj return (rv); 181209908Sraj} 182209908Sraj 183