at91sam9g45.c revision 266087
172339Sabial/*-
272339Sabial * Copyright (c) 2005 Olivier Houchard.  All rights reserved.
372339Sabial * Copyright (c) 2010 Greg Ansley.  All rights reserved.
472339Sabial * Copyright (c) 2012 Andrew Turner.  All rights reserved.
572339Sabial *
672339Sabial * Redistribution and use in source and binary forms, with or without
772339Sabial * modification, are permitted provided that the following conditions
872339Sabial * are met:
972339Sabial * 1. Redistributions of source code must retain the above copyright
1072339Sabial *    notice, this list of conditions and the following disclaimer.
1172339Sabial * 2. Redistributions in binary form must reproduce the above copyright
1272339Sabial *    notice, this list of conditions and the following disclaimer in the
1372339Sabial *    documentation and/or other materials provided with the distribution.
1472339Sabial *
1572339Sabial * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1672339Sabial * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1772339Sabial * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1872339Sabial * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
1972339Sabial * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2072339Sabial * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2172339Sabial * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2272339Sabial * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2372339Sabial * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2472339Sabial * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2572339Sabial * SUCH DAMAGE.
2672339Sabial */
2772339Sabial
2872339Sabial#include <sys/cdefs.h>
2972339Sabial__FBSDID("$FreeBSD: stable/10/sys/arm/at91/at91sam9g45.c 266087 2014-05-14 20:31:54Z ian $");
3072339Sabial
3172339Sabial#include <sys/param.h>
3272339Sabial#include <sys/systm.h>
3372339Sabial#include <sys/bus.h>
3472339Sabial#include <sys/kernel.h>
3572339Sabial#include <sys/malloc.h>
3672339Sabial#include <sys/module.h>
3772339Sabial
3872339Sabial#define	_ARM32_BUS_DMA_PRIVATE
3972339Sabial#include <machine/bus.h>
4072339Sabial
4172339Sabial#include <arm/at91/at91var.h>
4272339Sabial#include <arm/at91/at91reg.h>
4372339Sabial#include <arm/at91/at91soc.h>
4472339Sabial#include <arm/at91/at91_aicreg.h>
4572339Sabial#include <arm/at91/at91sam9g45reg.h>
4672339Sabial#include <arm/at91/at91_pitreg.h>
4772339Sabial#include <arm/at91/at91_pmcreg.h>
4872339Sabial#include <arm/at91/at91_pmcvar.h>
4972339Sabial#include <arm/at91/at91_rstreg.h>
5072339Sabial
5172339Sabial/*
5272339Sabial * Standard priority levels for the system.  0 is lowest and 7 is highest.
5372339Sabial * These values are the ones Atmel uses for its Linux port
5472339Sabial */
5572339Sabialstatic const int at91_irq_prio[32] =
5672339Sabial{
5772339Sabial	7,	/* Advanced Interrupt Controller */
5872339Sabial	7,	/* System Peripherals */
5972339Sabial	1,	/* Parallel IO Controller A */
6072339Sabial	1,	/* Parallel IO Controller B */
6172339Sabial	1,	/* Parallel IO Controller C */
6272339Sabial	1,	/* Parallel IO Controller D and E */
6372339Sabial	0,
6472339Sabial	5,	/* USART 0 */
6572339Sabial	5,	/* USART 1 */
6672339Sabial	5,	/* USART 2 */
6772339Sabial	5,	/* USART 3 */
6872339Sabial	0,	/* Multimedia Card Interface 0 */
6972339Sabial	6,	/* Two-Wire Interface 0 */
7072339Sabial	6,	/* Two-Wire Interface 1 */
7172339Sabial	5,	/* Serial Peripheral Interface 0 */
7272339Sabial	5,	/* Serial Peripheral Interface 1 */
7372339Sabial	4,	/* Serial Synchronous Controller 0 */
7472339Sabial	4,	/* Serial Synchronous Controller 1 */
7572339Sabial	0,	/* Timer Counter 0, 1, 2, 3, 4 and 5 */
7672339Sabial	0,	/* Pulse Width Modulation Controller */
7772339Sabial	0,	/* Touch Screen Controller */
7872339Sabial	0,	/* DMA Controller */
7972339Sabial	2,	/* USB Host High Speed port */
8072339Sabial	3,	/* LCD Controller */
8172339Sabial	5,	/* AC97 Controller */
8272339Sabial	3,	/* Ethernet */
8372339Sabial	0,	/* Image Sensor Interface */
8472339Sabial	2,	/* USB Device High Speed port */
8572339Sabial	0,	/* (reserved) */
8672339Sabial	0,	/* Multimedia Card Interface 1 */
8772339Sabial	0,	/* (reserved) */
8872339Sabial	0,	/* Advanced Interrupt Controller IRQ0 */
8972339Sabial};
9072339Sabial
9172339Sabialstatic const uint32_t at91_pio_base[] = {
9272339Sabial	AT91SAM9G45_PIOA_BASE,
9372339Sabial	AT91SAM9G45_PIOB_BASE,
9472339Sabial	AT91SAM9G45_PIOC_BASE,
9572339Sabial	AT91SAM9G45_PIOD_BASE,
9672339Sabial	AT91SAM9G45_PIOE_BASE,
9772339Sabial};
9872339Sabial
9972339Sabial#define DEVICE(_name, _id, _unit)		\
10072339Sabial	{					\
10172339Sabial		_name, _unit,			\
10272339Sabial		AT91SAM9G45_ ## _id ##_BASE,	\
10372339Sabial		AT91SAM9G45_ ## _id ## _SIZE,	\
10472339Sabial		AT91SAM9G45_IRQ_ ## _id		\
10572339Sabial	}
10672339Sabial
10772339Sabialstatic const struct cpu_devs at91_devs[] =
10872339Sabial{
10972339Sabial	DEVICE("at91_pmc", PMC,  0),
11072339Sabial	DEVICE("at91_wdt", WDT,  0),
11172339Sabial	DEVICE("at91_rst", RSTC, 0),
11272339Sabial	DEVICE("at91_pit", PIT,  0),
11372339Sabial	DEVICE("at91_pio", PIOA, 0),
11472339Sabial	DEVICE("at91_pio", PIOB, 1),
11572339Sabial	DEVICE("at91_pio", PIOC, 2),
11672339Sabial	DEVICE("at91_pio", PIOD, 3),
11772339Sabial	DEVICE("at91_pio", PIOE, 4),
11872339Sabial	DEVICE("at91_twi", TWI0, 0),
11972339Sabial	DEVICE("at91_twi", TWI1, 1),
12072339Sabial	DEVICE("at91_mci", HSMCI0, 0),
12172339Sabial	DEVICE("at91_mci", HSMCI1, 1),
12272339Sabial	DEVICE("uart", DBGU,   0),
12372339Sabial	DEVICE("uart", USART0, 1),
12472339Sabial	DEVICE("uart", USART1, 2),
12572339Sabial	DEVICE("uart", USART2, 3),
12672339Sabial	DEVICE("uart", USART3, 4),
12772339Sabial	DEVICE("spi",  SPI0,   0),
12872339Sabial	DEVICE("spi",  SPI1,   1),
12972339Sabial	DEVICE("ate",  EMAC,   0),
13072339Sabial	DEVICE("macb", EMAC,   0),
13172339Sabial	DEVICE("nand", NAND,   0),
13272339Sabial	DEVICE("ohci", OHCI,   0),
13372339Sabial	{ 0, 0, 0, 0, 0 }
13472339Sabial};
13572339Sabial
13672339Sabialstatic void
13772339Sabialat91_clock_init(void)
13872339Sabial{
13972339Sabial	struct at91_pmc_clock *clk;
14072339Sabial
14172339Sabial	/* Update USB host port clock info */
14272339Sabial	clk = at91_pmc_clock_ref("uhpck");
14372339Sabial	clk->pmc_mask  = PMC_SCER_UHP_SAM9;
14472339Sabial	at91_pmc_clock_deref(clk);
14572339Sabial
14672339Sabial	/* Each SOC has different PLL contraints */
14772339Sabial	clk = at91_pmc_clock_ref("plla");
14872339Sabial	clk->pll_min_in    = SAM9G45_PLL_A_MIN_IN_FREQ;		/*   2 MHz */
14972339Sabial	clk->pll_max_in    = SAM9G45_PLL_A_MAX_IN_FREQ;		/*  32 MHz */
15072339Sabial	clk->pll_min_out   = SAM9G45_PLL_A_MIN_OUT_FREQ;	/* 400 MHz */
15172339Sabial	clk->pll_max_out   = SAM9G45_PLL_A_MAX_OUT_FREQ;	/* 800 MHz */
15272339Sabial	clk->pll_mul_shift = SAM9G45_PLL_A_MUL_SHIFT;
15372339Sabial	clk->pll_mul_mask  = SAM9G45_PLL_A_MUL_MASK;
15472339Sabial	clk->pll_div_shift = SAM9G45_PLL_A_DIV_SHIFT;
15572339Sabial	clk->pll_div_mask  = SAM9G45_PLL_A_DIV_MASK;
15672339Sabial	clk->set_outb      = at91_pmc_800mhz_plla_outb;
15772339Sabial	at91_pmc_clock_deref(clk);
15872339Sabial}
15972339Sabial
16072339Sabialstatic struct at91_soc_data soc_data = {
16172339Sabial	.soc_delay = at91_pit_delay,
16272339Sabial	.soc_reset = at91_rst_cpu_reset,
16372339Sabial	.soc_clock_init = at91_clock_init,
16472339Sabial	.soc_irq_prio = at91_irq_prio,
16572339Sabial	.soc_children = at91_devs,
16672339Sabial	.soc_pio_base = at91_pio_base,
16772339Sabial	.soc_pio_count = nitems(at91_pio_base),
16872339Sabial};
16972339Sabial
17072339SabialAT91_SOC(AT91_T_SAM9G45, &soc_data);
17172339Sabial