fdt_powerpc.c revision 209906
1209906Sraj/*- 2209906Sraj * Copyright (c) 2009-2010 The FreeBSD Foundation 3209906Sraj * All rights reserved. 4209906Sraj * 5209906Sraj * This software was developed by Semihalf under sponsorship from 6209906Sraj * the FreeBSD Foundation. 7209906Sraj * 8209906Sraj * Redistribution and use in source and binary forms, with or without 9209906Sraj * modification, are permitted provided that the following conditions 10209906Sraj * are met: 11209906Sraj * 1. Redistributions of source code must retain the above copyright 12209906Sraj * notice, this list of conditions and the following disclaimer. 13209906Sraj * 2. Redistributions in binary form must reproduce the above copyright 14209906Sraj * notice, this list of conditions and the following disclaimer in the 15209906Sraj * documentation and/or other materials provided with the distribution. 16209906Sraj * 17209906Sraj * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18209906Sraj * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19209906Sraj * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20209906Sraj * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21209906Sraj * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22209906Sraj * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23209906Sraj * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24209906Sraj * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25209906Sraj * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26209906Sraj * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27209906Sraj * SUCH DAMAGE. 28209906Sraj */ 29209906Sraj 30209906Sraj#include <sys/cdefs.h> 31209906Sraj__FBSDID("$FreeBSD: head/sys/dev/fdt/fdt_powerpc.c 209906 2010-07-11 20:49:36Z raj $"); 32209906Sraj 33209906Sraj#include <sys/param.h> 34209906Sraj#include <sys/systm.h> 35209906Sraj#include <sys/kernel.h> 36209906Sraj#include <sys/module.h> 37209906Sraj#include <sys/bus.h> 38209906Sraj 39209906Sraj#include <machine/intr_machdep.h> 40209906Sraj 41209906Sraj#include <dev/ofw/ofw_bus.h> 42209906Sraj#include <dev/ofw/ofw_bus_subr.h> 43209906Sraj#include <dev/ofw/openfirm.h> 44209906Sraj 45209906Sraj#include "ofw_bus_if.h" 46209906Sraj#include "fdt_common.h" 47209906Sraj 48209906Srajstatic void 49209906Srajfdt_fixup_busfreq(phandle_t root) 50209906Sraj{ 51209906Sraj phandle_t sb, cpus, child; 52209906Sraj pcell_t freq; 53209906Sraj 54209906Sraj /* 55209906Sraj * Do a strict check so as to skip non-SOC nodes, which also claim 56209906Sraj * simple-bus compatibility such as eLBC etc. 57209906Sraj */ 58209906Sraj if ((sb = fdt_find_compatible(root, "simple-bus", 1)) == 0) 59209906Sraj return; 60209906Sraj 61209906Sraj /* 62209906Sraj * This fixup uses /cpus/ bus-frequency prop value to set simple-bus 63209906Sraj * bus-frequency property. 64209906Sraj */ 65209906Sraj if ((cpus = OF_finddevice("/cpus")) == 0) 66209906Sraj return; 67209906Sraj 68209906Sraj if ((child = OF_child(cpus)) == 0) 69209906Sraj return; 70209906Sraj 71209906Sraj if (OF_getprop(child, "bus-frequency", (void *)&freq, 72209906Sraj sizeof(freq)) <= 0) 73209906Sraj return; 74209906Sraj 75209906Sraj OF_setprop(sb, "bus-frequency", (void *)&freq, sizeof(freq)); 76209906Sraj} 77209906Sraj 78209906Srajstruct fdt_fixup_entry fdt_fixup_table[] = { 79209906Sraj { "fsl,MPC8572DS", &fdt_fixup_busfreq }, 80209906Sraj { "MPC8555CDS", &fdt_fixup_busfreq }, 81209906Sraj { NULL, NULL } 82209906Sraj}; 83209906Sraj 84209906Srajstatic int 85209906Srajfdt_pic_decode_iic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, 86209906Sraj int *pol) 87209906Sraj{ 88209906Sraj if (!fdt_is_compatible(node, "chrp,iic")) 89209906Sraj return (ENXIO); 90209906Sraj 91209906Sraj *interrupt = intr[0]; 92209906Sraj 93209906Sraj switch (intr[1]) { 94209906Sraj case 0: 95209906Sraj /* Active L level */ 96209906Sraj *trig = INTR_TRIGGER_LEVEL; 97209906Sraj *pol = INTR_POLARITY_LOW; 98209906Sraj break; 99209906Sraj case 1: 100209906Sraj /* Active H level */ 101209906Sraj *trig = INTR_TRIGGER_LEVEL; 102209906Sraj *pol = INTR_POLARITY_HIGH; 103209906Sraj break; 104209906Sraj case 2: 105209906Sraj /* H to L edge */ 106209906Sraj *trig = INTR_TRIGGER_EDGE; 107209906Sraj *pol = INTR_POLARITY_LOW; 108209906Sraj break; 109209906Sraj case 3: 110209906Sraj /* L to H edge */ 111209906Sraj *trig = INTR_TRIGGER_EDGE; 112209906Sraj *pol = INTR_POLARITY_HIGH; 113209906Sraj break; 114209906Sraj default: 115209906Sraj *trig = INTR_TRIGGER_CONFORM; 116209906Sraj *pol = INTR_POLARITY_CONFORM; 117209906Sraj } 118209906Sraj return (0); 119209906Sraj} 120209906Sraj 121209906Srajstatic int 122209906Srajfdt_pic_decode_openpic(phandle_t node, pcell_t *intr, int *interrupt, 123209906Sraj int *trig, int *pol) 124209906Sraj{ 125209906Sraj 126209906Sraj if (!fdt_is_compatible(node, "chrp,open-pic")) 127209906Sraj return (ENXIO); 128209906Sraj 129209906Sraj /* 130209906Sraj * XXX The interrupt number read out from the MPC85XX device tree is 131209906Sraj * already offset by 16 to reflect the 'internal' IRQ range shift on 132209906Sraj * the OpenPIC. 133209906Sraj */ 134209906Sraj *interrupt = intr[0]; 135209906Sraj 136209906Sraj switch (intr[1]) { 137209906Sraj case 0: 138209906Sraj /* L to H edge */ 139209906Sraj *trig = INTR_TRIGGER_EDGE; 140209906Sraj *pol = INTR_POLARITY_HIGH; 141209906Sraj break; 142209906Sraj case 1: 143209906Sraj /* Active L level */ 144209906Sraj *trig = INTR_TRIGGER_LEVEL; 145209906Sraj *pol = INTR_POLARITY_LOW; 146209906Sraj break; 147209906Sraj case 2: 148209906Sraj /* Active H level */ 149209906Sraj *trig = INTR_TRIGGER_LEVEL; 150209906Sraj *pol = INTR_POLARITY_HIGH; 151209906Sraj break; 152209906Sraj case 3: 153209906Sraj /* H to L edge */ 154209906Sraj *trig = INTR_TRIGGER_EDGE; 155209906Sraj *pol = INTR_POLARITY_LOW; 156209906Sraj break; 157209906Sraj default: 158209906Sraj *trig = INTR_TRIGGER_CONFORM; 159209906Sraj *pol = INTR_POLARITY_CONFORM; 160209906Sraj } 161209906Sraj return (0); 162209906Sraj} 163209906Sraj 164209906Srajfdt_pic_decode_t fdt_pic_table[] = { 165209906Sraj &fdt_pic_decode_iic, 166209906Sraj &fdt_pic_decode_openpic, 167209906Sraj NULL 168209906Sraj}; 169