mpc85xx.c revision 189757
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 189757 2009-03-13 06:28:20Z raj $"); 29178596Sraj 30178596Sraj#include <sys/param.h> 31178596Sraj#include <sys/systm.h> 32178596Sraj 33178597Sraj#include <vm/vm.h> 34178597Sraj#include <vm/vm_param.h> 35178597Sraj 36178596Sraj#include <machine/cpu.h> 37178596Sraj#include <machine/cpufunc.h> 38178596Sraj#include <machine/spr.h> 39178596Sraj 40178597Sraj#include <powerpc/mpc85xx/ocpbus.h> 41186227Sraj#include <powerpc/mpc85xx/mpc85xx.h> 42178597Sraj 43178596Sraj/* 44178596Sraj * MPC85xx system specific routines 45178596Sraj */ 46178596Sraj 47186227Srajuint32_t 48186227Srajccsr_read4(uintptr_t addr) 49186227Sraj{ 50186227Sraj volatile uint32_t *ptr = (void *)addr; 51186227Sraj 52186227Sraj return (*ptr); 53186227Sraj} 54186227Sraj 55178596Srajvoid 56186227Srajccsr_write4(uintptr_t addr, uint32_t val) 57178596Sraj{ 58186227Sraj volatile uint32_t *ptr = (void *)addr; 59178596Sraj 60186227Sraj *ptr = val; 61186227Sraj __asm __volatile("eieio; sync"); 62186227Sraj} 63186227Sraj 64189757Srajint 65186288Srajlaw_getmax(void) 66186288Sraj{ 67186288Sraj uint32_t ver; 68186288Sraj 69186288Sraj ver = SVR_VER(mfspr(SPR_SVR)); 70186288Sraj if (ver == SVR_MPC8572E || ver == SVR_MPC8572) 71186288Sraj return (12); 72189757Sraj else if (ver == SVR_MPC8548E || ver == SVR_MPC8548) 73189757Sraj return (10); 74186288Sraj else 75186288Sraj return (8); 76186288Sraj} 77186288Sraj 78186288Sraj#define _LAW_SR(trgt,size) (0x80000000 | (trgt << 20) | (ffsl(size) - 2)) 79186288Sraj#define _LAW_BAR(addr) (addr >> 12) 80186288Sraj 81186288Srajint 82186288Srajlaw_enable(int trgt, u_long addr, u_long size) 83186288Sraj{ 84186288Sraj uint32_t bar, sr; 85186288Sraj int i, law_max; 86186288Sraj 87186288Sraj law_max = law_getmax(); 88186288Sraj bar = _LAW_BAR(addr); 89186288Sraj sr = _LAW_SR(trgt, size); 90186288Sraj 91186288Sraj /* Bail if already programmed. */ 92186288Sraj for (i = 0; i < law_max; i++) 93186288Sraj if (sr == ccsr_read4(OCP85XX_LAWSR(i)) && 94186288Sraj bar == ccsr_read4(OCP85XX_LAWBAR(i))) 95186288Sraj return (0); 96186288Sraj 97186288Sraj /* Find an unused access window. */ 98186288Sraj for (i = 0; i < law_max; i++) 99186288Sraj if ((ccsr_read4(OCP85XX_LAWSR(i)) & 0x80000000) == 0) 100186288Sraj break; 101186288Sraj 102186288Sraj if (i == law_max) 103186288Sraj return (ENOSPC); 104186288Sraj 105186288Sraj ccsr_write4(OCP85XX_LAWBAR(i), bar); 106186288Sraj ccsr_write4(OCP85XX_LAWSR(i), sr); 107186288Sraj return (0); 108186288Sraj} 109186288Sraj 110186288Srajint 111186288Srajlaw_disable(int trgt, u_long addr, u_long size) 112186288Sraj{ 113186288Sraj uint32_t bar, sr; 114186288Sraj int i, law_max; 115186288Sraj 116186288Sraj law_max = law_getmax(); 117186288Sraj bar = _LAW_BAR(addr); 118186288Sraj sr = _LAW_SR(trgt, size); 119186288Sraj 120186288Sraj /* Find and disable requested LAW. */ 121186288Sraj for (i = 0; i < law_max; i++) 122186288Sraj if (sr == ccsr_read4(OCP85XX_LAWSR(i)) && 123186288Sraj bar == ccsr_read4(OCP85XX_LAWBAR(i))) { 124186288Sraj ccsr_write4(OCP85XX_LAWBAR(i), 0); 125186288Sraj ccsr_write4(OCP85XX_LAWSR(i), 0); 126186288Sraj return (0); 127186288Sraj } 128186288Sraj 129186288Sraj return (ENOENT); 130186288Sraj} 131186288Sraj 132186227Srajvoid 133186227Srajcpu_reset(void) 134186227Sraj{ 135186227Sraj uint32_t ver = SVR_VER(mfspr(SPR_SVR)); 136186227Sraj 137189757Sraj if (ver == SVR_MPC8572E || ver == SVR_MPC8572 || 138189757Sraj ver == SVR_MPC8548E || ver == SVR_MPC8548) 139178597Sraj /* Systems with dedicated reset register */ 140186227Sraj ccsr_write4(OCP85XX_RSTCR, 2); 141178597Sraj else { 142178597Sraj /* Clear DBCR0, disables debug interrupts and events. */ 143178597Sraj mtspr(SPR_DBCR0, 0); 144186227Sraj __asm __volatile("isync"); 145178596Sraj 146178597Sraj /* Enable Debug Interrupts in MSR. */ 147178597Sraj mtmsr(mfmsr() | PSL_DE); 148178596Sraj 149178597Sraj /* Enable debug interrupts and issue reset. */ 150186227Sraj mtspr(SPR_DBCR0, mfspr(SPR_DBCR0) | DBCR0_IDM | 151186227Sraj DBCR0_RST_SYSTEM); 152178597Sraj } 153178597Sraj 154178596Sraj printf("Reset failed...\n"); 155178596Sraj while (1); 156178596Sraj} 157