u-boot-brain/board/bluewater/gurnard/gurnard.c
Tom Rini 83d290c56f SPDX: Convert all of our single license tags to Linux Kernel style
When U-Boot started using SPDX tags we were among the early adopters and
there weren't a lot of other examples to borrow from.  So we picked the
area of the file that usually had a full license text and replaced it
with an appropriate SPDX-License-Identifier: entry.  Since then, the
Linux Kernel has adopted SPDX tags and they place it as the very first
line in a file (except where shebangs are used, then it's second line)
and with slightly different comment styles than us.

In part due to community overlap, in part due to better tag visibility
and in part for other minor reasons, switch over to that style.

This commit changes all instances where we have a single declared
license in the tag as both the before and after are identical in tag
contents.  There's also a few places where I found we did not have a tag
and have introduced one.

Signed-off-by: Tom Rini <trini@konsulko.com>
2018-05-07 09:34:12 -04:00

424 lines
10 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Bluewater Systems Snapper 9260/9G20 modules
*
* (C) Copyright 2011 Bluewater Systems
* Author: Andre Renaud <andre@bluewatersys.com>
* Author: Ryan Mallon <ryan@bluewatersys.com>
*/
#include <common.h>
#include <atmel_lcd.h>
#include <atmel_lcdc.h>
#include <atmel_mci.h>
#include <dm.h>
#include <lcd.h>
#include <net.h>
#ifndef CONFIG_DM_ETH
#include <netdev.h>
#endif
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/arch/at91sam9g45_matrix.h>
#include <asm/arch/at91sam9_smc.h>
#include <asm/arch/at91_common.h>
#include <asm/arch/at91_emac.h>
#include <asm/arch/at91_rstc.h>
#include <asm/arch/at91_rtc.h>
#include <asm/arch/at91_sck.h>
#include <asm/arch/atmel_serial.h>
#include <asm/arch/clk.h>
#include <asm/arch/gpio.h>
#include <dm/uclass-internal.h>
#ifdef CONFIG_GURNARD_SPLASH
#include "splash_logo.h"
#endif
DECLARE_GLOBAL_DATA_PTR;
/* IO Expander pins */
#define IO_EXP_ETH_RESET (0 << 1)
#define IO_EXP_ETH_POWER (1 << 1)
#ifdef CONFIG_MACB
static void gurnard_macb_hw_init(void)
{
struct at91_port *pioa = (struct at91_port *)ATMEL_BASE_PIOA;
at91_periph_clk_enable(ATMEL_ID_EMAC);
/*
* Enable pull-up on:
* RXDV (PA12) => MODE0 - PHY also has pull-up
* ERX0 (PA13) => MODE1 - PHY also has pull-up
* ERX1 (PA15) => MODE2 - PHY also has pull-up
*/
writel(pin_to_mask(AT91_PIN_PA15) |
pin_to_mask(AT91_PIN_PA12) |
pin_to_mask(AT91_PIN_PA13),
&pioa->puer);
at91_phy_reset();
at91_macb_hw_init();
}
#endif
#ifdef CONFIG_CMD_NAND
static int gurnard_nand_hw_init(void)
{
struct at91_matrix *matrix = (struct at91_matrix *)ATMEL_BASE_MATRIX;
struct at91_smc *smc = (struct at91_smc *)ATMEL_BASE_SMC;
ulong flags;
int ret;
/* Enable CS3 as NAND/SmartMedia */
setbits_le32(&matrix->ebicsa, AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
/* Configure SMC CS3 for NAND/SmartMedia */
writel(AT91_SMC_SETUP_NWE(2) | AT91_SMC_SETUP_NCS_WR(0) |
AT91_SMC_SETUP_NRD(2) | AT91_SMC_SETUP_NCS_RD(0),
&smc->cs[3].setup);
writel(AT91_SMC_PULSE_NWE(4) | AT91_SMC_PULSE_NCS_WR(4) |
AT91_SMC_PULSE_NRD(4) | AT91_SMC_PULSE_NCS_RD(4),
&smc->cs[3].pulse);
writel(AT91_SMC_CYCLE_NWE(7) | AT91_SMC_CYCLE_NRD(7),
&smc->cs[3].cycle);
#ifdef CONFIG_SYS_NAND_DBW_16
flags = AT91_SMC_MODE_DBW_16;
#else
flags = AT91_SMC_MODE_DBW_8;
#endif
writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_WM_NWE |
AT91_SMC_MODE_EXNW_DISABLE |
flags |
AT91_SMC_MODE_TDF_CYCLE(3),
&smc->cs[3].mode);
ret = gpio_request(CONFIG_SYS_NAND_READY_PIN, "nand_rdy");
if (ret)
return ret;
gpio_direction_input(CONFIG_SYS_NAND_READY_PIN);
/* Enable NandFlash */
ret = gpio_request(CONFIG_SYS_NAND_ENABLE_PIN, "nand_ce");
if (ret)
return ret;
gpio_direction_output(CONFIG_SYS_NAND_ENABLE_PIN, 1);
return 0;
}
#endif
#ifdef CONFIG_GURNARD_SPLASH
static void lcd_splash(int width, int height)
{
u16 colour;
int x, y;
u16 *base_addr = (u16 *)gd->video_bottom;
memset(base_addr, 0xff, width * height * 2);
/*
* Blit the logo to the center of the screen
*/
for (y = 0; y < BMP_LOGO_HEIGHT; y++) {
for (x = 0; x < BMP_LOGO_WIDTH; x++) {
int posx, posy;
colour = bmp_logo_palette[bmp_logo_bitmap[
y * BMP_LOGO_WIDTH + x]];
posx = x + (width - BMP_LOGO_WIDTH) / 2;
posy = y;
base_addr[posy * width + posx] = colour;
}
}
}
#endif
#ifdef CONFIG_DM_VIDEO
static void at91sam9g45_lcd_hw_init(void)
{
at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */
at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */
at91_set_A_periph(AT91_PIN_PE3, 0); /* LCDVSYNC */
at91_set_A_periph(AT91_PIN_PE4, 0); /* LCDHSYNC */
at91_set_A_periph(AT91_PIN_PE5, 0); /* LCDDOTCK */
at91_set_A_periph(AT91_PIN_PE7, 0); /* LCDD0 */
at91_set_A_periph(AT91_PIN_PE8, 0); /* LCDD1 */
at91_set_A_periph(AT91_PIN_PE9, 0); /* LCDD2 */
at91_set_A_periph(AT91_PIN_PE10, 0); /* LCDD3 */
at91_set_A_periph(AT91_PIN_PE11, 0); /* LCDD4 */
at91_set_A_periph(AT91_PIN_PE12, 0); /* LCDD5 */
at91_set_A_periph(AT91_PIN_PE13, 0); /* LCDD6 */
at91_set_A_periph(AT91_PIN_PE14, 0); /* LCDD7 */
at91_set_A_periph(AT91_PIN_PE15, 0); /* LCDD8 */
at91_set_A_periph(AT91_PIN_PE16, 0); /* LCDD9 */
at91_set_A_periph(AT91_PIN_PE17, 0); /* LCDD10 */
at91_set_A_periph(AT91_PIN_PE18, 0); /* LCDD11 */
at91_set_A_periph(AT91_PIN_PE19, 0); /* LCDD12 */
at91_set_B_periph(AT91_PIN_PE20, 0); /* LCDD13 */
at91_set_A_periph(AT91_PIN_PE21, 0); /* LCDD14 */
at91_set_A_periph(AT91_PIN_PE22, 0); /* LCDD15 */
at91_set_A_periph(AT91_PIN_PE23, 0); /* LCDD16 */
at91_set_A_periph(AT91_PIN_PE24, 0); /* LCDD17 */
at91_set_A_periph(AT91_PIN_PE25, 0); /* LCDD18 */
at91_set_A_periph(AT91_PIN_PE26, 0); /* LCDD19 */
at91_set_A_periph(AT91_PIN_PE27, 0); /* LCDD20 */
at91_set_B_periph(AT91_PIN_PE28, 0); /* LCDD21 */
at91_set_A_periph(AT91_PIN_PE29, 0); /* LCDD22 */
at91_set_A_periph(AT91_PIN_PE30, 0); /* LCDD23 */
at91_periph_clk_enable(ATMEL_ID_LCDC);
}
#endif
#ifdef CONFIG_GURNARD_FPGA
/**
* Initialise the memory bus settings so that we can talk to the
* memory mapped FPGA
*/
static int fpga_hw_init(void)
{
struct at91_matrix *matrix = (struct at91_matrix *)ATMEL_BASE_MATRIX;
struct at91_smc *smc = (struct at91_smc *)ATMEL_BASE_SMC;
int i;
setbits_le32(&matrix->ebicsa, AT91_MATRIX_EBI_CS1A_SDRAMC);
at91_set_a_periph(2, 4, 0); /* EBIA21 */
at91_set_a_periph(2, 5, 0); /* EBIA22 */
at91_set_a_periph(2, 6, 0); /* EBIA23 */
at91_set_a_periph(2, 7, 0); /* EBIA24 */
at91_set_a_periph(2, 12, 0); /* EBIA25 */
for (i = 15; i <= 31; i++) /* EBINWAIT & EBID16 - 31 */
at91_set_a_periph(2, i, 0);
/* configure SMC cs0 for FPGA access timing */
writel(AT91_SMC_SETUP_NWE(1) | AT91_SMC_SETUP_NCS_WR(2) |
AT91_SMC_SETUP_NRD(0) | AT91_SMC_SETUP_NCS_RD(2),
&smc->cs[0].setup);
writel(AT91_SMC_PULSE_NWE(5) | AT91_SMC_PULSE_NCS_WR(4) |
AT91_SMC_PULSE_NRD(6) | AT91_SMC_PULSE_NCS_RD(4),
&smc->cs[0].pulse);
writel(AT91_SMC_CYCLE_NWE(6) | AT91_SMC_CYCLE_NRD(6),
&smc->cs[0].cycle);
writel(AT91_SMC_MODE_BAT |
AT91_SMC_MODE_EXNW_DISABLE |
AT91_SMC_MODE_DBW_32 |
AT91_SMC_MODE_TDF |
AT91_SMC_MODE_TDF_CYCLE(2),
&smc->cs[0].mode);
/* Do a write to within EBI_CS1 to enable the SDCK */
writel(0, ATMEL_BASE_CS1);
return 0;
}
#endif
#ifdef CONFIG_CMD_USB
#define USB0_ENABLE_PIN AT91_PIN_PB22
#define USB1_ENABLE_PIN AT91_PIN_PB23
void gurnard_usb_init(void)
{
at91_set_gpio_output(USB0_ENABLE_PIN, 1);
at91_set_gpio_value(USB0_ENABLE_PIN, 0);
at91_set_gpio_output(USB1_ENABLE_PIN, 1);
at91_set_gpio_value(USB1_ENABLE_PIN, 0);
}
#endif
#ifdef CONFIG_GENERIC_ATMEL_MCI
int cpu_mmc_init(bd_t *bis)
{
return atmel_mci_init((void *)ATMEL_BASE_MCI0);
}
#endif
static void gurnard_enable_console(int enable)
{
at91_set_gpio_output(AT91_PIN_PB14, 1);
at91_set_gpio_value(AT91_PIN_PB14, enable ? 0 : 1);
}
void at91sam9g45_slowclock_init(void)
{
/*
* On AT91SAM9G45 revC CPUs, the slow clock can be based on an
* internal impreciseRC oscillator or an external 32kHz oscillator.
* Switch to the latter.
*/
unsigned i, tmp;
ulong *reg = (ulong *)ATMEL_BASE_SCKCR;
tmp = readl(reg);
if ((tmp & AT91SAM9G45_SCKCR_OSCSEL) == AT91SAM9G45_SCKCR_OSCSEL_RC) {
timer_init();
tmp |= AT91SAM9G45_SCKCR_OSC32EN;
writel(tmp, reg);
for (i = 0; i < 1200; i++)
udelay(1000);
tmp |= AT91SAM9G45_SCKCR_OSCSEL_32;
writel(tmp, reg);
udelay(200);
tmp &= ~AT91SAM9G45_SCKCR_RCEN;
writel(tmp, reg);
}
}
int board_early_init_f(void)
{
at91_seriald_hw_init();
gurnard_enable_console(1);
return 0;
}
int board_init(void)
{
const char *rev_str;
#ifdef CONFIG_CMD_NAND
int ret;
#endif
at91_periph_clk_enable(ATMEL_ID_PIOA);
at91_periph_clk_enable(ATMEL_ID_PIOB);
at91_periph_clk_enable(ATMEL_ID_PIOC);
at91_periph_clk_enable(ATMEL_ID_PIODE);
at91sam9g45_slowclock_init();
/*
* Clear the RTC IDR to disable all IRQs. Avoid issues when Linux
* boots with spurious IRQs.
*/
writel(0xffffffff, AT91_RTC_IDR);
/* Make sure that the reset signal is attached properly */
setbits_le32(AT91_ASM_RSTC_MR, AT91_RSTC_KEY | AT91_RSTC_MR_URSTEN);
gd->bd->bi_arch_number = MACH_TYPE_SNAPPER_9260;
/* Address of boot parameters */
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
#ifdef CONFIG_CMD_NAND
ret = gurnard_nand_hw_init();
if (ret)
return ret;
#endif
#ifdef CONFIG_ATMEL_SPI
at91_spi0_hw_init(1 << 4);
#endif
#ifdef CONFIG_MACB
gurnard_macb_hw_init();
#endif
#ifdef CONFIG_GURNARD_FPGA
fpga_hw_init();
#endif
#ifdef CONFIG_CMD_USB
gurnard_usb_init();
#endif
#ifdef CONFIG_CMD_MMC
at91_set_A_periph(AT91_PIN_PA12, 0);
at91_set_gpio_output(AT91_PIN_PA8, 1);
at91_set_gpio_value(AT91_PIN_PA8, 0);
at91_mci_hw_init();
#endif
#ifdef CONFIG_DM_VIDEO
at91sam9g45_lcd_hw_init();
at91_set_A_periph(AT91_PIN_PE6, 1); /* power up */
/* Select the second timing index for board rev 2 */
rev_str = env_get("board_rev");
if (rev_str && !strncmp(rev_str, "2", 1)) {
struct udevice *dev;
uclass_find_first_device(UCLASS_VIDEO, &dev);
if (dev) {
struct atmel_lcd_platdata *plat = dev_get_platdata(dev);
plat->timing_index = 1;
}
}
#endif
return 0;
}
int board_late_init(void)
{
u_int8_t env_enetaddr[8];
char *env_str;
char *end;
int i;
/*
* Set MAC address so we do not need to init Ethernet before Linux
* boot
*/
env_str = env_get("ethaddr");
if (env_str) {
struct at91_emac *emac = (struct at91_emac *)ATMEL_BASE_EMAC;
/* Parse MAC address */
for (i = 0; i < 6; i++) {
env_enetaddr[i] = env_str ?
simple_strtoul(env_str, &end, 16) : 0;
if (env_str)
env_str = (*end) ? end+1 : end;
}
/* Set hardware address */
writel(env_enetaddr[0] | env_enetaddr[1] << 8 |
env_enetaddr[2] << 16 | env_enetaddr[3] << 24,
&emac->sa2l);
writel((env_enetaddr[4] | env_enetaddr[5] << 8), &emac->sa2h);
printf("MAC: %s\n", env_get("ethaddr"));
} else {
/* Not set in environment */
printf("MAC: not set\n");
}
#ifdef CONFIG_GURNARD_SPLASH
lcd_splash(480, 272);
#endif
return 0;
}
#ifndef CONFIG_DM_ETH
int board_eth_init(bd_t *bis)
{
return macb_eth_initialize(0, (void *)ATMEL_BASE_EMAC, 0);
}
#endif
int dram_init(void)
{
gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
CONFIG_SYS_SDRAM_SIZE);
return 0;
}
void reset_phy(void)
{
}
static struct atmel_serial_platdata at91sam9260_serial_plat = {
.base_addr = ATMEL_BASE_DBGU,
};
U_BOOT_DEVICE(at91sam9260_serial) = {
.name = "serial_atmel",
.platdata = &at91sam9260_serial_plat,
};