at91rm9200.c revision 238397
1/*- 2 * Copyright (c) 2005 Olivier Houchard. All rights reserved. 3 * Copyright (c) 2010 Greg Ansley. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: head/sys/arm/at91/at91rm9200.c 238397 2012-07-12 13:45:58Z imp $"); 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/bus.h> 33#include <sys/kernel.h> 34#include <sys/malloc.h> 35#include <sys/module.h> 36 37#define _ARM32_BUS_DMA_PRIVATE 38#include <machine/bus.h> 39 40#include <arm/at91/at91var.h> 41#include <arm/at91/at91reg.h> 42#include <arm/at91/at91rm92reg.h> 43#include <arm/at91/at91_aicreg.h> 44#include <arm/at91/at91_pmcreg.h> 45#include <arm/at91/at91_streg.h> 46#include <arm/at91/at91_pmcvar.h> 47#include <arm/at91/at91soc.h> 48 49/* 50 * Standard priority levels for the system. 0 is lowest and 7 is highest. 51 * These values are the ones Atmel uses for its Linux port, which differ 52 * a little form the ones that are in the standard distribution. Also, 53 * the ones marked with 'TWEEK' are different based on experience. 54 */ 55static const int at91_irq_prio[32] = 56{ 57 7, /* Advanced Interrupt Controller (FIQ) */ 58 7, /* System Peripherals */ 59 1, /* Parallel IO Controller A */ 60 1, /* Parallel IO Controller B */ 61 1, /* Parallel IO Controller C */ 62 1, /* Parallel IO Controller D */ 63 5, /* USART 0 */ 64 5, /* USART 1 */ 65 5, /* USART 2 */ 66 5, /* USART 3 */ 67 0, /* Multimedia Card Interface */ 68 2, /* USB Device Port */ 69 4, /* Two-Wire Interface */ /* TWEEK */ 70 5, /* Serial Peripheral Interface */ 71 4, /* Serial Synchronous Controller 0 */ 72 6, /* Serial Synchronous Controller 1 */ /* TWEEK */ 73 4, /* Serial Synchronous Controller 2 */ 74 0, /* Timer Counter 0 */ 75 6, /* Timer Counter 1 */ /* TWEEK */ 76 0, /* Timer Counter 2 */ 77 0, /* Timer Counter 3 */ 78 0, /* Timer Counter 4 */ 79 0, /* Timer Counter 5 */ 80 2, /* USB Host port */ 81 3, /* Ethernet MAC */ 82 0, /* Advanced Interrupt Controller (IRQ0) */ 83 0, /* Advanced Interrupt Controller (IRQ1) */ 84 0, /* Advanced Interrupt Controller (IRQ2) */ 85 0, /* Advanced Interrupt Controller (IRQ3) */ 86 0, /* Advanced Interrupt Controller (IRQ4) */ 87 0, /* Advanced Interrupt Controller (IRQ5) */ 88 0 /* Advanced Interrupt Controller (IRQ6) */ 89}; 90 91#define DEVICE(_name, _id, _unit) \ 92 { \ 93 _name, _unit, \ 94 AT91RM92_ ## _id ##_BASE, \ 95 AT91RM92_ ## _id ## _SIZE, \ 96 AT91RM92_IRQ_ ## _id \ 97 } 98 99static const struct cpu_devs at91_devs[] = 100{ 101 DEVICE("at91_pmc", PMC, 0), 102 DEVICE("at91_st", ST, 0), 103 DEVICE("at91_pio", PIOA, 0), 104 DEVICE("at91_pio", PIOB, 1), 105 DEVICE("at91_pio", PIOC, 2), 106 DEVICE("at91_pio", PIOD, 3), 107 DEVICE("at91_rtc", RTC, 0), 108 109 DEVICE("at91_mci", MCI, 0), 110 DEVICE("at91_twi", TWI, 0), 111 DEVICE("at91_udp", UDP, 0), 112 DEVICE("ate", EMAC, 0), 113 DEVICE("at91_ssc", SSC0, 0), 114 DEVICE("at91_ssc", SSC1, 1), 115 DEVICE("at91_ssc", SSC2, 2), 116 DEVICE("spi", SPI, 0), 117 118 DEVICE("uart", DBGU, 0), 119 DEVICE("uart", USART0, 1), 120 DEVICE("uart", USART1, 2), 121 DEVICE("uart", USART2, 3), 122 DEVICE("uart", USART3, 4), 123 DEVICE("at91_aic", AIC, 0), 124 DEVICE("at91_mc", MC, 0), 125 DEVICE("at91_tc", TC0, 0), 126 DEVICE("at91_tc", TC1, 1), 127 DEVICE("ohci", OHCI, 0), 128 DEVICE("af91_cfata", CF, 0), 129 { 0, 0, 0, 0, 0 } 130}; 131 132static uint32_t 133at91_pll_outb(int freq) 134{ 135 136 if (freq > 155000000) 137 return (0x0000); 138 else 139 return (0x8000); 140} 141 142#if 0 143/* -- XXX are these needed? */ 144 /* Disable all interrupts for RTC (0xe24 == RTC_IDR) */ 145 bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xe24, 0xffffffff); 146 147 /* Disable all interrupts for the SDRAM controller */ 148 bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xfa8, 0xffffffff); 149#endif 150 151static void 152at91_clock_init(void) 153{ 154 struct at91_pmc_clock *clk; 155 156 /* Update USB device port clock info */ 157 clk = at91_pmc_clock_ref("udpck"); 158 clk->pmc_mask = PMC_SCER_UDP; 159 at91_pmc_clock_deref(clk); 160 161 /* Update USB host port clock info */ 162 clk = at91_pmc_clock_ref("uhpck"); 163 clk->pmc_mask = PMC_SCER_UHP; 164 at91_pmc_clock_deref(clk); 165 166 /* Each SOC has different PLL contraints */ 167 clk = at91_pmc_clock_ref("plla"); 168 clk->pll_min_in = RM9200_PLL_A_MIN_IN_FREQ; /* 1 MHz */ 169 clk->pll_max_in = RM9200_PLL_A_MAX_IN_FREQ; /* 32 MHz */ 170 clk->pll_min_out = RM9200_PLL_A_MIN_OUT_FREQ; /* 80 MHz */ 171 clk->pll_max_out = RM9200_PLL_A_MAX_OUT_FREQ; /* 180 MHz */ 172 clk->pll_mul_shift = RM9200_PLL_A_MUL_SHIFT; 173 clk->pll_mul_mask = RM9200_PLL_A_MUL_MASK; 174 clk->pll_div_shift = RM9200_PLL_A_DIV_SHIFT; 175 clk->pll_div_mask = RM9200_PLL_A_DIV_MASK; 176 clk->set_outb = at91_pll_outb; 177 at91_pmc_clock_deref(clk); 178 179 clk = at91_pmc_clock_ref("pllb"); 180 clk->pll_min_in = RM9200_PLL_B_MIN_IN_FREQ; /* 100 KHz */ 181 clk->pll_max_in = RM9200_PLL_B_MAX_IN_FREQ; /* 32 MHz */ 182 clk->pll_min_out = RM9200_PLL_B_MIN_OUT_FREQ; /* 30 MHz */ 183 clk->pll_max_out = RM9200_PLL_B_MAX_OUT_FREQ; /* 240 MHz */ 184 clk->pll_mul_shift = RM9200_PLL_B_MUL_SHIFT; 185 clk->pll_mul_mask = RM9200_PLL_B_MUL_MASK; 186 clk->pll_div_shift = RM9200_PLL_B_DIV_SHIFT; 187 clk->pll_div_mask = RM9200_PLL_B_DIV_MASK; 188 clk->set_outb = at91_pll_outb; 189 at91_pmc_clock_deref(clk); 190} 191 192static struct at91_soc_data soc_data = { 193 .soc_delay = at91_st_delay, 194 .soc_reset = at91_st_cpu_reset, 195 .soc_clock_init = at91_clock_init, 196 .soc_irq_prio = at91_irq_prio, 197 .soc_children = at91_devs, 198}; 199 200AT91_SOC(AT91_T_RM9200, &soc_data); 201