mpc85xx.c revision 222428
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 222428 2011-05-28 19:14:16Z marcel $"); 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> 41178596Sraj#include <machine/spr.h> 42178596Sraj 43186227Sraj#include <powerpc/mpc85xx/mpc85xx.h> 44178597Sraj 45178596Sraj/* 46178596Sraj * MPC85xx system specific routines 47178596Sraj */ 48178596Sraj 49186227Srajuint32_t 50186227Srajccsr_read4(uintptr_t addr) 51186227Sraj{ 52186227Sraj volatile uint32_t *ptr = (void *)addr; 53186227Sraj 54186227Sraj return (*ptr); 55186227Sraj} 56186227Sraj 57178596Srajvoid 58186227Srajccsr_write4(uintptr_t addr, uint32_t val) 59178596Sraj{ 60186227Sraj volatile uint32_t *ptr = (void *)addr; 61178596Sraj 62186227Sraj *ptr = val; 63186227Sraj __asm __volatile("eieio; sync"); 64186227Sraj} 65186227Sraj 66189757Srajint 67186288Srajlaw_getmax(void) 68186288Sraj{ 69186288Sraj uint32_t ver; 70186288Sraj 71186288Sraj ver = SVR_VER(mfspr(SPR_SVR)); 72222428Smarcel if (ver == SVR_MPC8555E || ver == SVR_MPC8555) 73222428Smarcel return (8); 74222428Smarcel if (ver == SVR_MPC8548E || ver == SVR_MPC8548 || 75222428Smarcel ver == SVR_MPC8533E || ver == SVR_MPC8533) 76189757Sraj return (10); 77222428Smarcel 78222428Smarcel return (12); 79186288Sraj} 80186288Sraj 81186288Sraj#define _LAW_SR(trgt,size) (0x80000000 | (trgt << 20) | (ffsl(size) - 2)) 82186288Sraj#define _LAW_BAR(addr) (addr >> 12) 83186288Sraj 84186288Srajint 85186288Srajlaw_enable(int trgt, u_long addr, u_long size) 86186288Sraj{ 87186288Sraj uint32_t bar, sr; 88186288Sraj int i, law_max; 89186288Sraj 90186288Sraj law_max = law_getmax(); 91186288Sraj bar = _LAW_BAR(addr); 92186288Sraj sr = _LAW_SR(trgt, size); 93186288Sraj 94186288Sraj /* Bail if already programmed. */ 95186288Sraj for (i = 0; i < law_max; i++) 96186288Sraj if (sr == ccsr_read4(OCP85XX_LAWSR(i)) && 97186288Sraj bar == ccsr_read4(OCP85XX_LAWBAR(i))) 98186288Sraj return (0); 99186288Sraj 100186288Sraj /* Find an unused access window. */ 101186288Sraj for (i = 0; i < law_max; i++) 102186288Sraj if ((ccsr_read4(OCP85XX_LAWSR(i)) & 0x80000000) == 0) 103186288Sraj break; 104186288Sraj 105186288Sraj if (i == law_max) 106186288Sraj return (ENOSPC); 107186288Sraj 108186288Sraj ccsr_write4(OCP85XX_LAWBAR(i), bar); 109186288Sraj ccsr_write4(OCP85XX_LAWSR(i), sr); 110186288Sraj return (0); 111186288Sraj} 112186288Sraj 113186288Srajint 114186288Srajlaw_disable(int trgt, u_long addr, u_long size) 115186288Sraj{ 116186288Sraj uint32_t bar, sr; 117186288Sraj int i, law_max; 118186288Sraj 119186288Sraj law_max = law_getmax(); 120186288Sraj bar = _LAW_BAR(addr); 121186288Sraj sr = _LAW_SR(trgt, size); 122186288Sraj 123186288Sraj /* Find and disable requested LAW. */ 124186288Sraj for (i = 0; i < law_max; i++) 125186288Sraj if (sr == ccsr_read4(OCP85XX_LAWSR(i)) && 126186288Sraj bar == ccsr_read4(OCP85XX_LAWBAR(i))) { 127186288Sraj ccsr_write4(OCP85XX_LAWBAR(i), 0); 128186288Sraj ccsr_write4(OCP85XX_LAWSR(i), 0); 129186288Sraj return (0); 130186288Sraj } 131186288Sraj 132186288Sraj return (ENOENT); 133186288Sraj} 134186288Sraj 135209908Srajint 136209908Srajlaw_pci_target(struct resource *res, int *trgt_mem, int *trgt_io) 137209908Sraj{ 138209908Sraj u_long start; 139209908Sraj uint32_t ver; 140209908Sraj int trgt, rv; 141209908Sraj 142209908Sraj ver = SVR_VER(mfspr(SPR_SVR)); 143209908Sraj 144209908Sraj start = rman_get_start(res) & 0xf000; 145209908Sraj 146209908Sraj rv = 0; 147209908Sraj trgt = -1; 148209908Sraj switch (start) { 149209908Sraj case 0x8000: 150209908Sraj trgt = 0; 151209908Sraj break; 152209908Sraj case 0x9000: 153209908Sraj trgt = 1; 154209908Sraj break; 155209908Sraj case 0xa000: 156222428Smarcel if (ver == SVR_MPC8548E || ver == SVR_MPC8548) 157222428Smarcel trgt = 3; 158222428Smarcel else 159209908Sraj trgt = 2; 160222428Smarcel break; 161222428Smarcel case 0xb000: 162222428Smarcel if (ver == SVR_MPC8548E || ver == SVR_MPC8548) 163222428Smarcel rv = EINVAL; 164209908Sraj else 165222428Smarcel trgt = 3; 166209908Sraj break; 167209908Sraj default: 168209908Sraj rv = ENXIO; 169209908Sraj } 170209908Sraj *trgt_mem = *trgt_io = trgt; 171209908Sraj return (rv); 172209908Sraj} 173209908Sraj 174