mpc85xx.c revision 257178
193787Sdes/*- 294691Sdes * Copyright (C) 2008 Semihalf, Rafal Jaworowski 393787Sdes * All rights reserved. 493787Sdes * 593787Sdes * Redistribution and use in source and binary forms, with or without 693787Sdes * modification, are permitted provided that the following conditions 793787Sdes * are met: 893787Sdes * 1. Redistributions of source code must retain the above copyright 993787Sdes * notice, this list of conditions and the following disclaimer. 1093787Sdes * 2. Redistributions in binary form must reproduce the above copyright 1193787Sdes * notice, this list of conditions and the following disclaimer in the 1293787Sdes * documentation and/or other materials provided with the distribution. 1393787Sdes * 1493787Sdes * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1593787Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1693787Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1793787Sdes * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 1893787Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1993787Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2093787Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2193787Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2293787Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2393787Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2493787Sdes * SUCH DAMAGE. 2593787Sdes */ 2693787Sdes 2793787Sdes#include <sys/cdefs.h> 2893787Sdes__FBSDID("$FreeBSD: head/sys/powerpc/mpc85xx/mpc85xx.c 257178 2013-10-26 18:18:14Z nwhitehorn $"); 2993787Sdes 3093787Sdes#include <sys/param.h> 3193787Sdes#include <sys/systm.h> 3293787Sdes#include <sys/lock.h> 3393787Sdes#include <sys/mutex.h> 3493787Sdes#include <sys/rman.h> 3593787Sdes 3693787Sdes#include <vm/vm.h> 3793787Sdes#include <vm/vm_param.h> 3893787Sdes 3993787Sdes#include <machine/cpu.h> 4093787Sdes#include <machine/cpufunc.h> 4193787Sdes#include <machine/pio.h> 4293787Sdes#include <machine/spr.h> 4393787Sdes 4493787Sdes#include <dev/fdt/fdt_common.h> 4593787Sdes 4693787Sdes#include <powerpc/mpc85xx/mpc85xx.h> 4793787Sdes 4893787Sdes/* 4993787Sdes * MPC85xx system specific routines 5093787Sdes */ 5193787Sdes 5293787Sdesuint32_t 5393787Sdesccsr_read4(uintptr_t addr) 5493787Sdes{ 5593787Sdes volatile uint32_t *ptr = (void *)addr; 5693787Sdes 5793787Sdes return (*ptr); 5893787Sdes} 5993787Sdes 6093787Sdesvoid 6193787Sdesccsr_write4(uintptr_t addr, uint32_t val) 6293787Sdes{ 6394691Sdes volatile uint32_t *ptr = (void *)addr; 6493787Sdes 6593787Sdes *ptr = val; 6693787Sdes powerpc_iomb(); 6793787Sdes} 6893787Sdes 6993787Sdesint 7093787Sdeslaw_getmax(void) 7193787Sdes{ 7293787Sdes uint32_t ver; 7393787Sdes 7493787Sdes ver = SVR_VER(mfspr(SPR_SVR)); 7593787Sdes if (ver == SVR_MPC8555E || ver == SVR_MPC8555) 7693787Sdes return (8); 7793787Sdes if (ver == SVR_MPC8548E || ver == SVR_MPC8548 || 7893787Sdes ver == SVR_MPC8533E || ver == SVR_MPC8533) 7993787Sdes return (10); 8093787Sdes 8193787Sdes return (12); 8293787Sdes} 8393787Sdes 8493787Sdes#define _LAW_SR(trgt,size) (0x80000000 | (trgt << 20) | (ffsl(size) - 2)) 8593787Sdes#define _LAW_BAR(addr) (addr >> 12) 8693787Sdes 8793787Sdesint 8893787Sdeslaw_enable(int trgt, u_long addr, u_long size) 8993787Sdes{ 9093787Sdes uint32_t bar, sr; 9193787Sdes int i, law_max; 9293787Sdes 9393787Sdes if (size == 0) 9493787Sdes return (0); 9593787Sdes 9693787Sdes law_max = law_getmax(); 9793787Sdes bar = _LAW_BAR(addr); 9893787Sdes sr = _LAW_SR(trgt, size); 9993787Sdes 10093787Sdes /* Bail if already programmed. */ 10193787Sdes for (i = 0; i < law_max; i++) 10293787Sdes if (sr == ccsr_read4(OCP85XX_LAWSR(i)) && 10393787Sdes bar == ccsr_read4(OCP85XX_LAWBAR(i))) 10493787Sdes return (0); 10593787Sdes 10693787Sdes /* Find an unused access window. */ 10793787Sdes for (i = 0; i < law_max; i++) 10893787Sdes if ((ccsr_read4(OCP85XX_LAWSR(i)) & 0x80000000) == 0) 10993787Sdes break; 11093787Sdes 11193787Sdes if (i == law_max) 11293787Sdes return (ENOSPC); 11393787Sdes 11493787Sdes ccsr_write4(OCP85XX_LAWBAR(i), bar); 11593787Sdes ccsr_write4(OCP85XX_LAWSR(i), sr); 11693787Sdes return (0); 11793787Sdes} 11893787Sdes 11993787Sdesint 12093787Sdeslaw_disable(int trgt, u_long addr, u_long size) 12193787Sdes{ 12293787Sdes uint32_t bar, sr; 12393787Sdes int i, law_max; 12493787Sdes 12593787Sdes law_max = law_getmax(); 12693787Sdes bar = _LAW_BAR(addr); 12793787Sdes sr = _LAW_SR(trgt, size); 12893787Sdes 12993787Sdes /* Find and disable requested LAW. */ 13093787Sdes for (i = 0; i < law_max; i++) 13193787Sdes if (sr == ccsr_read4(OCP85XX_LAWSR(i)) && 13293787Sdes bar == ccsr_read4(OCP85XX_LAWBAR(i))) { 13393787Sdes ccsr_write4(OCP85XX_LAWBAR(i), 0); 13493787Sdes ccsr_write4(OCP85XX_LAWSR(i), 0); 13593787Sdes return (0); 13693787Sdes } 13793787Sdes 13893787Sdes return (ENOENT); 13993787Sdes} 14093787Sdes 14193787Sdesint 14293787Sdeslaw_pci_target(struct resource *res, int *trgt_mem, int *trgt_io) 14394691Sdes{ 14493787Sdes u_long start; 14594691Sdes uint32_t ver; 14694691Sdes int trgt, rv; 14793787Sdes 14893787Sdes ver = SVR_VER(mfspr(SPR_SVR)); 14993787Sdes 15093787Sdes start = rman_get_start(res) & 0xf000; 15193787Sdes 15293787Sdes rv = 0; 15393787Sdes trgt = -1; 15493787Sdes switch (start) { 15593787Sdes case 0x8000: 15693787Sdes trgt = 0; 15793787Sdes break; 15893787Sdes case 0x9000: 15993787Sdes trgt = 1; 16093787Sdes break; 16193787Sdes case 0xa000: 16293787Sdes if (ver == SVR_MPC8548E || ver == SVR_MPC8548) 16393787Sdes trgt = 3; 16493787Sdes else 16594691Sdes trgt = 2; 16693787Sdes break; 16794691Sdes case 0xb000: 16894691Sdes if (ver == SVR_MPC8548E || ver == SVR_MPC8548) 16993787Sdes rv = EINVAL; 17093787Sdes else 17193787Sdes trgt = 3; 17293787Sdes break; 17393787Sdes default: 17493787Sdes rv = ENXIO; 17593787Sdes } 17693787Sdes if (rv == 0) { 17793787Sdes *trgt_mem = trgt; 17893787Sdes *trgt_io = trgt; 17993787Sdes } 18093787Sdes return (rv); 18193787Sdes} 18293787Sdes 18393787Sdes