Commit 54d822a6 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6:
  avr32: Fix GPIO initcall breakage
  avr32: Scale loops_per_jiffy when cpu frequency changes
  avr32: Fix bug in LCD pin setup on port C
  avr32: Add defconfig for the favr-32 board
  avr32: Add defconfig for the mimc200 board
  avr32: Add MIMC200 board support
  avr32: Fix MIMC200 board use of SPD network pins
  avr32: add support for EarthLCD Favr-32 board
  avr32: Add support for EVKLCD10X addon boards
  avr32: Kconfig: Remove pointless if around atstk1000 include
parents 22484856 d9214556
......@@ -121,11 +121,19 @@ config BOARD_ATSTK1000
config BOARD_ATNGW100
bool "ATNGW100 Network Gateway"
select CPU_AT32AP7000
config BOARD_FAVR_32
bool "Favr-32 LCD-board"
select CPU_AT32AP7000
config BOARD_MIMC200
bool "MIMC200 CPU board"
select CPU_AT32AP7000
endchoice
if BOARD_ATSTK1000
source "arch/avr32/boards/atstk1000/Kconfig"
endif
source "arch/avr32/boards/atngw100/Kconfig"
source "arch/avr32/boards/favr-32/Kconfig"
choice
prompt "Boot loader type"
......
......@@ -33,6 +33,8 @@ head-y += arch/avr32/kernel/head.o
core-y += $(machdirs)
core-$(CONFIG_BOARD_ATSTK1000) += arch/avr32/boards/atstk1000/
core-$(CONFIG_BOARD_ATNGW100) += arch/avr32/boards/atngw100/
core-$(CONFIG_BOARD_FAVR_32) += arch/avr32/boards/favr-32/
core-$(CONFIG_BOARD_MIMC200) += arch/avr32/boards/mimc200/
core-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/
core-y += arch/avr32/kernel/
core-y += arch/avr32/mm/
......
# NGW100 customization
if BOARD_ATNGW100
config BOARD_ATNGW100_EVKLCD10X
bool "Add support for EVKLCD10X addon board"
help
This enables support for the EVKLCD100 (QVGA) or EVKLCD101 (VGA)
addon board for the NGW100. By enabling this the LCD controller and
AC97 controller is added as platform devices.
This choice disables the detect pin and the write-protect pin for the
MCI platform device, since it conflicts with the LCD platform device.
The MCI pins can be reenabled by editing the "add device function" but
this may break the setup for other displays that use these pins.
Choose 'Y' here if you have a EVKLCD100/101 connected to the NGW100.
choice
prompt "LCD panel resolution on EVKLCD10X"
depends on BOARD_ATNGW100_EVKLCD10X
default BOARD_ATNGW100_EVKLCD10X_VGA
config BOARD_ATNGW100_EVKLCD10X_QVGA
bool "QVGA (320x240)"
config BOARD_ATNGW100_EVKLCD10X_VGA
bool "VGA (640x480)"
config BOARD_ATNGW100_EVKLCD10X_POW_QVGA
bool "Powertip QVGA (320x240)"
endchoice
endif # BOARD_ATNGW100
obj-y += setup.o flash.o
obj-y += setup.o flash.o
obj-$(CONFIG_BOARD_ATNGW100_EVKLCD10X) += evklcd10x.o
/*
* Board-specific setup code for the ATEVKLCD10X addon board to the ATNGW100
* Network Gateway
*
* Copyright (C) 2008 Atmel Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/linkage.h>
#include <linux/fb.h>
#include <linux/platform_device.h>
#include <video/atmel_lcdc.h>
#include <asm/setup.h>
#include <mach/at32ap700x.h>
#include <mach/board.h>
static struct ac97c_platform_data __initdata ac97c0_data = {
.dma_rx_periph_id = 3,
.dma_tx_periph_id = 4,
.dma_controller_id = 0,
.reset_pin = GPIO_PIN_PB(19),
};
#ifdef CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA
static struct fb_videomode __initdata tcg057vglad_modes[] = {
{
.name = "640x480 @ 60",
.refresh = 60,
.xres = 640, .yres = 480,
.pixclock = KHZ2PICOS(25180),
.left_margin = 64, .right_margin = 31,
.upper_margin = 34, .lower_margin = 2,
.hsync_len = 96, .vsync_len = 4,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
};
static struct fb_monspecs __initdata atevklcd10x_default_monspecs = {
.manufacturer = "KYO",
.monitor = "TCG057VGLAD",
.modedb = tcg057vglad_modes,
.modedb_len = ARRAY_SIZE(tcg057vglad_modes),
.hfmin = 19948,
.hfmax = 31478,
.vfmin = 50,
.vfmax = 67,
.dclkmax = 28330000,
};
static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = {
.default_bpp = 16,
.default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
.default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT
| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
| ATMEL_LCDC_MEMOR_BIG),
.default_monspecs = &atevklcd10x_default_monspecs,
.guard_time = 2,
};
#elif CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA
static struct fb_videomode __initdata tcg057qvlad_modes[] = {
{
.name = "320x240 @ 60",
.refresh = 60,
.xres = 320, .yres = 240,
.pixclock = KHZ2PICOS(6300),
.left_margin = 52, .right_margin = 28,
.upper_margin = 7, .lower_margin = 2,
.hsync_len = 96, .vsync_len = 4,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
};
static struct fb_monspecs __initdata atevklcd10x_default_monspecs = {
.manufacturer = "KYO",
.monitor = "TCG057QVLAD",
.modedb = tcg057qvlad_modes,
.modedb_len = ARRAY_SIZE(tcg057qvlad_modes),
.hfmin = 19948,
.hfmax = 31478,
.vfmin = 50,
.vfmax = 67,
.dclkmax = 7000000,
};
static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = {
.default_bpp = 16,
.default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
.default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT
| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
| ATMEL_LCDC_MEMOR_BIG),
.default_monspecs = &atevklcd10x_default_monspecs,
.guard_time = 2,
};
#elif CONFIG_BOARD_ATNGW100_EVKLCD10X_POW_QVGA
static struct fb_videomode __initdata ph320240t_modes[] = {
{
.name = "320x240 @ 60",
.refresh = 60,
.xres = 320, .yres = 240,
.pixclock = KHZ2PICOS(6300),
.left_margin = 38, .right_margin = 20,
.upper_margin = 15, .lower_margin = 5,
.hsync_len = 30, .vsync_len = 3,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
};
static struct fb_monspecs __initdata atevklcd10x_default_monspecs = {
.manufacturer = "POW",
.monitor = "PH320240T",
.modedb = ph320240t_modes,
.modedb_len = ARRAY_SIZE(ph320240t_modes),
.hfmin = 14400,
.hfmax = 21600,
.vfmin = 50,
.vfmax = 90,
.dclkmax = 6400000,
};
static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = {
.default_bpp = 16,
.default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
.default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT
| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
| ATMEL_LCDC_MEMOR_BIG),
.default_monspecs = &atevklcd10x_default_monspecs,
.guard_time = 2,
};
#endif
static int __init atevklcd10x_init(void)
{
at32_add_device_ac97c(0, &ac97c0_data);
at32_add_device_lcdc(0, &atevklcd10x_lcdc_data,
fbmem_start, fbmem_size, 1);
return 0;
}
postcore_initcall(atevklcd10x_init);
......@@ -56,8 +56,13 @@ static struct spi_board_info spi0_board_info[] __initdata = {
static struct mci_platform_data __initdata mci0_data = {
.slot[0] = {
.bus_width = 4,
#ifndef CONFIG_BOARD_ATNGW100_EVKLCD10X
.detect_pin = GPIO_PIN_PC(25),
.wp_pin = GPIO_PIN_PE(0),
#else
.detect_pin = GPIO_PIN_NONE,
.wp_pin = GPIO_PIN_NONE,
#endif
},
};
......@@ -172,8 +177,6 @@ static int __init atngw100_init(void)
* reserve any pins for it.
*/
at32_add_system_devices();
at32_add_device_usart(0);
set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
......
......@@ -305,8 +305,6 @@ static int __init atstk1002_init(void)
at32_reserve_pin(GPIO_PIN_PE(15)); /* DATA[31] */
at32_reserve_pin(GPIO_PIN_PE(26)); /* SDCS */
at32_add_system_devices();
#ifdef CONFIG_BOARD_ATSTK1006
smc_set_timing(&nand_config, &nand_timing);
smc_set_configuration(3, &nand_config);
......
......@@ -149,8 +149,6 @@ static int __init atstk1003_init(void)
at32_reserve_pin(GPIO_PIN_PE(15)); /* DATA[31] */
at32_reserve_pin(GPIO_PIN_PE(26)); /* SDCS */
at32_add_system_devices();
#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
at32_add_device_usart(1);
#else
......
......@@ -132,8 +132,6 @@ void __init setup_board(void)
static int __init atstk1004_init(void)
{
at32_add_system_devices();
#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
at32_add_device_usart(1);
#else
......
# Favr-32 customization
if BOARD_FAVR_32
config BOARD_FAVR32_ABDAC_RATE
int "DAC target rate"
default 44100
range 32000 50000
help
Specify the target rate the internal DAC should try to match. This
will use PLL1 to generate a frequency as close as possible to this
rate.
Must be within the range 32000 to 50000, which should be suitable to
generate most other frequencies in power of 2 steps.
Ex:
48000 will also suit 24000 and 12000
44100 will also suit 22050 and 11025
32000 will also suit 16000 and 8000
endif # BOARD_FAVR_32
obj-y += setup.o flash.o
/*
* Favr-32 board-specific flash initialization
*
* Copyright (C) 2008 Atmel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <asm/arch/smc.h>
static struct smc_timing flash_timing __initdata = {
.ncs_read_setup = 0,
.nrd_setup = 40,
.ncs_write_setup = 0,
.nwe_setup = 10,
.ncs_read_pulse = 80,
.nrd_pulse = 40,
.ncs_write_pulse = 65,
.nwe_pulse = 55,
.read_cycle = 120,
.write_cycle = 120,
};
static struct smc_config flash_config __initdata = {
.bus_width = 2,
.nrd_controlled = 1,
.nwe_controlled = 1,
.byte_write = 1,
};
static struct mtd_partition flash_parts[] = {
{
.name = "u-boot",
.offset = 0x00000000,
.size = 0x00020000, /* 128 KiB */
.mask_flags = MTD_WRITEABLE,
},
{
.name = "root",
.offset = 0x00020000,
.size = 0x007d0000,
},
{
.name = "env",
.offset = 0x007f0000,
.size = 0x00010000,
.mask_flags = MTD_WRITEABLE,
},
};
static struct physmap_flash_data flash_data = {
.width = 2,
.nr_parts = ARRAY_SIZE(flash_parts),
.parts = flash_parts,
};
static struct resource flash_resource = {
.start = 0x00000000,
.end = 0x007fffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device flash_device = {
.name = "physmap-flash",
.id = 0,
.resource = &flash_resource,
.num_resources = 1,
.dev = {
.platform_data = &flash_data,
},
};
/* This needs to be called after the SMC has been initialized */
static int __init favr32_flash_init(void)
{
int ret;
smc_set_timing(&flash_config, &flash_timing);
ret = smc_set_configuration(0, &flash_config);
if (ret < 0) {
printk(KERN_ERR "Favr-32: failed to set NOR flash timing\n");
return ret;
}
platform_device_register(&flash_device);
return 0;
}
device_initcall(favr32_flash_init);
/*
* Favr-32 board-specific setup code.
*
* Copyright (C) 2008 Atmel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
#include <linux/etherdevice.h>
#include <linux/bootmem.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/linkage.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/atmel-pwm-bl.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <video/atmel_lcdc.h>
#include <asm/setup.h>
#include <asm/arch/at32ap700x.h>
#include <asm/arch/init.h>
#include <asm/arch/board.h>
#include <asm/arch/portmux.h>
/* Oscillator frequencies. These are board-specific */
unsigned long at32_board_osc_rates[3] = {
[0] = 32768, /* 32.768 kHz on RTC osc */
[1] = 20000000, /* 20 MHz on osc0 */
[2] = 12000000, /* 12 MHz on osc1 */
};
/* Initialized by bootloader-specific startup code. */
struct tag *bootloader_tags __initdata;
struct eth_addr {
u8 addr[6];
};
static struct eth_addr __initdata hw_addr[1];
static struct eth_platform_data __initdata eth_data[1] = {
{
.phy_mask = ~(1U << 1),
},
};
static int ads7843_get_pendown_state(void)
{
return !gpio_get_value(GPIO_PIN_PB(3));
}
static struct ads7846_platform_data ads7843_data = {
.model = 7843,
.get_pendown_state = ads7843_get_pendown_state,
.pressure_max = 255,
/*
* Values below are for debounce filtering, these can be experimented
* with further.
*/
.debounce_max = 20,
.debounce_rep = 4,
.debounce_tol = 5,
};
static struct spi_board_info __initdata spi1_board_info[] = {
{
/* ADS7843 touch controller */
.modalias = "ads7846",
.max_speed_hz = 2000000,
.chip_select = 0,
.bus_num = 1,
.platform_data = &ads7843_data,
},
};
static struct fb_videomode __initdata lb104v03_modes[] = {
{
.name = "640x480 @ 50",
.refresh = 50,
.xres = 640, .yres = 480,
.pixclock = KHZ2PICOS(25100),
.left_margin = 90, .right_margin = 70,
.upper_margin = 30, .lower_margin = 15,
.hsync_len = 12, .vsync_len = 2,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
};
static struct fb_monspecs __initdata favr32_default_monspecs = {
.manufacturer = "LG",
.monitor = "LB104V03",
.modedb = lb104v03_modes,
.modedb_len = ARRAY_SIZE(lb104v03_modes),
.hfmin = 27273,
.hfmax = 31111,
.vfmin = 45,
.vfmax = 60,
.dclkmax = 28000000,
};
struct atmel_lcdfb_info __initdata favr32_lcdc_data = {
.default_bpp = 16,
.default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
.default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT
| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
| ATMEL_LCDC_MEMOR_BIG),
.default_monspecs = &favr32_default_monspecs,
.guard_time = 2,
};
static struct gpio_led favr32_leds[] = {
{
.name = "green",
.gpio = GPIO_PIN_PE(19),
.default_trigger = "heartbeat",
.active_low = 1,
},
{
.name = "red",
.gpio = GPIO_PIN_PE(20),
.active_low = 1,
},
};
static struct gpio_led_platform_data favr32_led_data = {
.num_leds = ARRAY_SIZE(favr32_leds),
.leds = favr32_leds,
};
static struct platform_device favr32_led_dev = {
.name = "leds-gpio",
.id = 0,
.dev = {
.platform_data = &favr32_led_data,
},
};
/*
* The next two functions should go away as the boot loader is
* supposed to initialize the macb address registers with a valid
* ethernet address. But we need to keep it around for a while until
* we can be reasonably sure the boot loader does this.
*
* The phy_id is ignored as the driver will probe for it.
*/
static int __init parse_tag_ethernet(struct tag *tag)
{
int i;
i = tag->u.ethernet.mac_index;
if (i < ARRAY_SIZE(hw_addr))
memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address,
sizeof(hw_addr[i].addr));
return 0;
}
__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
static void __init set_hw_addr(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
const u8 *addr;
void __iomem *regs;
struct clk *pclk;
if (!res)
return;
if (pdev->id >= ARRAY_SIZE(hw_addr))
return;
addr = hw_addr[pdev->id].addr;
if (!is_valid_ether_addr(addr))
return;
/*
* Since this is board-specific code, we'll cheat and use the
* physical address directly as we happen to know that it's
* the same as the virtual address.
*/
regs = (void __iomem __force *)res->start;
pclk = clk_get(&pdev->dev, "pclk");
if (!pclk)
return;
clk_enable(pclk);
__raw_writel((addr[3] << 24) | (addr[2] << 16)
| (addr[1] << 8) | addr[0], regs + 0x98);
__raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);
clk_disable(pclk);
clk_put(pclk);
}
void __init favr32_setup_leds(void)
{
unsigned i;
for (i = 0; i < ARRAY_SIZE(favr32_leds); i++)
at32_select_gpio(favr32_leds[i].gpio, AT32_GPIOF_OUTPUT);
platform_device_register(&favr32_led_dev);
}
static struct atmel_pwm_bl_platform_data atmel_pwm_bl_pdata = {
.pwm_channel = 2,
.pwm_frequency = 200000,
.pwm_compare_max = 345,
.pwm_duty_max = 345,
.pwm_duty_min = 90,
.pwm_active_low = 1,
.gpio_on = GPIO_PIN_PA(28),
.on_active_low = 0,
};
static struct platform_device atmel_pwm_bl_dev = {
.name = "atmel-pwm-bl",
.id = 0,
.dev = {
.platform_data = &atmel_pwm_bl_pdata,
},
};
static void __init favr32_setup_atmel_pwm_bl(void)
{
platform_device_register(&atmel_pwm_bl_dev);
at32_select_gpio(atmel_pwm_bl_pdata.gpio_on, 0);
}
void __init setup_board(void)
{
at32_map_usart(3, 0); /* USART 3 => /dev/ttyS0 */
at32_setup_serial_console(0);
}
static int __init set_abdac_rate(struct platform_device *pdev)
{
int retval;
struct clk *osc1;
struct clk *pll1;
struct clk *abdac;
if (pdev == NULL)
return -ENXIO;
osc1 = clk_get(NULL, "osc1");
if (IS_ERR(osc1)) {
retval = PTR_ERR(osc1);
goto out;
}
pll1 = clk_get(NULL, "pll1");
if (IS_ERR(pll1)) {
retval = PTR_ERR(pll1);
goto out_osc1;
}
abdac = clk_get(&pdev->dev, "sample_clk");
if (IS_ERR(abdac)) {
retval = PTR_ERR(abdac);
goto out_pll1;
}
retval = clk_set_parent(pll1, osc1);
if (retval != 0)
goto out_abdac;
/*
* Rate is 32000 to 50000 and ABDAC oversamples 256x. Multiply, in
* power of 2, to a value above 80 MHz. Power of 2 so it is possible
* for the generic clock to divide it down again and 80 MHz is the
* lowest frequency for the PLL.
*/
retval = clk_round_rate(pll1,
CONFIG_BOARD_FAVR32_ABDAC_RATE * 256 * 16);
if (retval < 0)
goto out_abdac;
retval = clk_set_rate(pll1, retval);
if (retval != 0)
goto out_abdac;
retval = clk_set_parent(abdac, pll1);
if (retval != 0)
goto out_abdac;
out_abdac:
clk_put(abdac);
out_pll1:
clk_put(pll1);
out_osc1:
clk_put(osc1);
out:
return retval;
}
static int __init favr32_init(void)
{
/*
* Favr-32 uses 32-bit SDRAM interface. Reserve the SDRAM-specific
* pins so that nobody messes with them.
*/
at32_reserve_pin(GPIO_PIN_PE(0)); /* DATA[16] */
at32_reserve_pin(GPIO_PIN_PE(1)); /* DATA[17] */
at32_reserve_pin(GPIO_PIN_PE(2)); /* DATA[18] */
at32_reserve_pin(GPIO_PIN_PE(3)); /* DATA[19] */
at32_reserve_pin(GPIO_PIN_PE(4)); /* DATA[20] */
at32_reserve_pin(GPIO_PIN_PE(5)); /* DATA[21] */
at32_reserve_pin(GPIO_PIN_PE(6)); /* DATA[22] */
at32_reserve_pin(GPIO_PIN_PE(7)); /* DATA[23] */
at32_reserve_pin(GPIO_PIN_PE(8)); /* DATA[24] */
at32_reserve_pin(GPIO_PIN_PE(9)); /* DATA[25] */
at32_reserve_pin(GPIO_PIN_PE(10)); /* DATA[26] */
at32_reserve_pin(GPIO_PIN_PE(11)); /* DATA[27] */
at32_reserve_pin(GPIO_PIN_PE(12)); /* DATA[28] */
at32_reserve_pin(GPIO_PIN_PE(13)); /* DATA[29] */
at32_reserve_pin(GPIO_PIN_PE(14)); /* DATA[30] */
at32_reserve_pin(GPIO_PIN_PE(15)); /* DATA[31] */
at32_reserve_pin(GPIO_PIN_PE(26)); /* SDCS */
at32_select_gpio(GPIO_PIN_PB(3), 0); /* IRQ from ADS7843 */
at32_add_system_devices();
at32_add_device_usart(0);
set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
spi1_board_info[0].irq = gpio_to_irq(GPIO_PIN_PB(3));
set_abdac_rate(at32_add_device_abdac(0));
at32_add_device_pwm(1 << atmel_pwm_bl_pdata.pwm_channel);
at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
at32_add_device_mci(0, NULL);
at32_add_device_usba(0, NULL);
at32_add_device_lcdc(0, &favr32_lcdc_data, fbmem_start, fbmem_size, 0);
favr32_setup_leds();
favr32_setup_atmel_pwm_bl();
return 0;
}
postcore_initcall(favr32_init);
obj-y += setup.o flash.o fram.o
/*
* MIMC200 board-specific flash initialization
*
* Copyright (C) 2008 Mercury IMC Ltd
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <mach/smc.h>
static struct smc_timing flash_timing __initdata = {
.ncs_read_setup = 0,
.nrd_setup = 15,
.ncs_write_setup = 0,
.nwe_setup = 0,
.ncs_read_pulse = 115,
.nrd_pulse = 110,
.ncs_write_pulse = 60,
.nwe_pulse = 60,
.read_cycle = 115,
.write_cycle = 100,
};
static struct smc_config flash_config __initdata = {
.bus_width = 2,
.nrd_controlled = 1,
.nwe_controlled = 1,
.byte_write = 1,
};
/* system flash definition */
static struct mtd_partition flash_parts_system[] = {
{
.name = "u-boot",
.offset = 0x00000000,
.size = 0x00020000, /* 128 KiB */
.mask_flags = MTD_WRITEABLE,
},
{
.name = "root",
.offset = 0x00020000,
.size = 0x007c0000,
},
{
.name = "splash",
.offset = 0x007e0000,
.size = 0x00010000, /* 64KiB */
},
{
.name = "env",
.offset = 0x007f0000,
.size = 0x00010000,
.mask_flags = MTD_WRITEABLE,
},
};
static struct physmap_flash_data flash_system = {
.width = 2,
.nr_parts = ARRAY_SIZE(flash_parts_system),
.parts = flash_parts_system,
};
static struct resource flash_resource_system = {
.start = 0x00000000,
.end = 0x007fffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device flash_device_system = {
.name = "physmap-flash",
.id = 0,
.resource = &flash_resource_system,
.num_resources = 1,
.dev = {
.platform_data = &flash_system,
},
};
/* data flash definition */
static struct mtd_partition flash_parts_data[] = {
{
.name = "data",
.offset = 0x00000000,
.size = 0x00800000,
},
};
static struct physmap_flash_data flash_data = {
.width = 2,
.nr_parts = ARRAY_SIZE(flash_parts_data),
.parts = flash_parts_data,
};
static struct resource flash_resource_data = {
.start = 0x08000000,
.end = 0x087fffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device flash_device_data = {
.name = "physmap-flash",
.id = 1,
.resource = &flash_resource_data,
.num_resources = 1,
.dev = {
.platform_data = &flash_data,
},
};
/* This needs to be called after the SMC has been initialized */
static int __init mimc200_flash_init(void)
{
int ret;
smc_set_timing(&flash_config, &flash_timing);
ret = smc_set_configuration(0, &flash_config);
if (ret < 0) {
printk(KERN_ERR "mimc200: failed to set 'System' NOR flash timing\n");
return ret;
}
ret = smc_set_configuration(1, &flash_config);
if (ret < 0) {
printk(KERN_ERR "mimc200: failed to set 'Data' NOR flash timing\n");
return ret;
}
platform_device_register(&flash_device_system);
platform_device_register(&flash_device_data);
return 0;
}
device_initcall(mimc200_flash_init);
/*
* FRAM driver for MIMC200 board
*
* Copyright 2008 Mark Jackson <mpfj@mimc.co.uk>
*
* This module adds *very* simply support for the system's FRAM device.
* At the moment, this is hard-coded to the MIMC200 platform, and only
* supports mmap().
*/
#define FRAM_VERSION "1.0"
#include <linux/miscdevice.h>
#include <linux/proc_fs.h>
#include <linux/mm.h>
#include <linux/io.h>
#define FRAM_BASE 0xac000000
#define FRAM_SIZE 0x20000
/*
* The are the file operation function for user access to /dev/fram
*/
static int fram_mmap(struct file *filp, struct vm_area_struct *vma)
{
int ret;
ret = remap_pfn_range(vma,
vma->vm_start,
virt_to_phys((void *)((unsigned long)FRAM_BASE)) >> PAGE_SHIFT,
vma->vm_end-vma->vm_start,
PAGE_SHARED);
if (ret != 0)
return -EAGAIN;
return 0;
}
static const struct file_operations fram_fops = {
.owner = THIS_MODULE,
.mmap = fram_mmap,
};
#define FRAM_MINOR 0
static struct miscdevice fram_dev = {
FRAM_MINOR,
"fram",
&fram_fops
};
static int __init
fram_init(void)
{
int ret;
ret = misc_register(&fram_dev);
if (ret) {
printk(KERN_ERR "fram: can't misc_register on minor=%d\n",
FRAM_MINOR);
return ret;
}
printk(KERN_INFO "FRAM memory driver v" FRAM_VERSION "\n");
return 0;
}
static void __exit
fram_cleanup_module(void)
{
misc_deregister(&fram_dev);
}
module_init(fram_init);
module_exit(fram_cleanup_module);
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(FRAM_MINOR);
/*
* Board-specific setup code for the MIMC200
*
* Copyright (C) 2008 Mercury IMC Ltd
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
extern struct atmel_lcdfb_info mimc200_lcdc_data;
#include <linux/clk.h>
#include <linux/etherdevice.h>
#include <linux/i2c-gpio.h>
#include <linux/init.h>
#include <linux/linkage.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/leds.h>
#include <linux/spi/spi.h>
#include <linux/spi/eeprom.h>
#include <video/atmel_lcdc.h>
#include <linux/fb.h>
#include <asm/atmel-mci.h>
#include <linux/io.h>
#include <asm/setup.h>
#include <mach/at32ap700x.h>
#include <mach/board.h>
#include <mach/init.h>
#include <mach/portmux.h>
/* Oscillator frequencies. These are board-specific */
unsigned long at32_board_osc_rates[3] = {
[0] = 32768, /* 32.768 kHz on RTC osc */
[1] = 10000000, /* 10 MHz on osc0 */
[2] = 12000000, /* 12 MHz on osc1 */
};
/* Initialized by bootloader-specific startup code. */
struct tag *bootloader_tags __initdata;
static struct fb_videomode __initdata tx14d14_modes[] = {
{
.name = "640x480 @ 60",
.refresh = 60,
.xres = 640, .yres = 480,
.pixclock = KHZ2PICOS(11666),
.left_margin = 80, .right_margin = 1,
.upper_margin = 13, .lower_margin = 2,
.hsync_len = 64, .vsync_len = 1,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
};
static struct fb_monspecs __initdata mimc200_default_monspecs = {
.manufacturer = "HIT",
.monitor = "TX14D14VM1BAB",
.modedb = tx14d14_modes,
.modedb_len = ARRAY_SIZE(tx14d14_modes),
.hfmin = 14820,
.hfmax = 22230,
.vfmin = 60,
.vfmax = 73.3,
.dclkmax = 25200000,
};
struct atmel_lcdfb_info __initdata mimc200_lcdc_data = {
.default_bpp = 16,
.default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
.default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT
| ATMEL_LCDC_INVCLK
| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
| ATMEL_LCDC_MEMOR_BIG),
.default_monspecs = &mimc200_default_monspecs,
.guard_time = 2,
};
struct eth_addr {
u8 addr[6];
};
static struct eth_addr __initdata hw_addr[2];
static struct eth_platform_data __initdata eth_data[2];
static struct spi_eeprom eeprom_25lc010 = {
.name = "25lc010",
.byte_len = 128,
.page_size = 16,
.flags = EE_ADDR1,
};
static struct spi_board_info spi0_board_info[] __initdata = {
{
.modalias = "rtc-ds1390",
.max_speed_hz = 4000000,
.chip_select = 2,
},
{
.modalias = "at25",
.max_speed_hz = 1000000,
.chip_select = 1,
.mode = SPI_MODE_3,
.platform_data = &eeprom_25lc010,
},
};
static struct mci_platform_data __initdata mci0_data = {
.slot[0] = {
.bus_width = 4,
.detect_pin = GPIO_PIN_PA(26),
.wp_pin = GPIO_PIN_PA(27),
},
};
/*
* The next two functions should go away as the boot loader is
* supposed to initialize the macb address registers with a valid
* ethernet address. But we need to keep it around for a while until
* we can be reasonably sure the boot loader does this.
*
* The phy_id is ignored as the driver will probe for it.
*/
static int __init parse_tag_ethernet(struct tag *tag)
{
int i;
i = tag->u.ethernet.mac_index;
if (i < ARRAY_SIZE(hw_addr))
memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address,
sizeof(hw_addr[i].addr));
return 0;
}
__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
static void __init set_hw_addr(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
const u8 *addr;
void __iomem *regs;
struct clk *pclk;
if (!res)
return;
if (pdev->id >= ARRAY_SIZE(hw_addr))
return;
addr = hw_addr[pdev->id].addr;
if (!is_valid_ether_addr(addr))
return;
/*
* Since this is board-specific code, we'll cheat and use the
* physical address directly as we happen to know that it's
* the same as the virtual address.
*/
regs = (void __iomem __force *)res->start;
pclk = clk_get(&pdev->dev, "pclk");
if (!pclk)
return;
clk_enable(pclk);
__raw_writel((addr[3] << 24) | (addr[2] << 16)
| (addr[1] << 8) | addr[0], regs + 0x98);
__raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);
clk_disable(pclk);
clk_put(pclk);
}
void __init setup_board(void)
{
at32_map_usart(0, 0); /* USART 0: /dev/ttyS0 (TTL --> Altera) */
at32_map_usart(1, 1); /* USART 1: /dev/ttyS1 (RS232) */
at32_map_usart(2, 2); /* USART 2: /dev/ttyS2 (RS485) */
at32_map_usart(3, 3); /* USART 3: /dev/ttyS3 (RS422 Multidrop) */
}
static struct i2c_gpio_platform_data i2c_gpio_data = {
.sda_pin = GPIO_PIN_PA(6),
.scl_pin = GPIO_PIN_PA(7),
.sda_is_open_drain = 1,
.scl_is_open_drain = 1,
.udelay = 2, /* close to 100 kHz */
};
static struct platform_device i2c_gpio_device = {
.name = "i2c-gpio",
.id = 0,
.dev = {
.platform_data = &i2c_gpio_data,
},
};
static struct i2c_board_info __initdata i2c_info[] = {
};
static int __init mimc200_init(void)
{
/*
* MIMC200 uses 16-bit SDRAM interface, so we don't need to
* reserve any pins for it.
*/
at32_add_system_devices();
at32_add_device_usart(0);
at32_add_device_usart(1);
at32_add_device_usart(2);
at32_add_device_usart(3);
set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
set_hw_addr(at32_add_device_eth(1, &eth_data[1]));
at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
at32_add_device_mci(0, &mci0_data);
at32_add_device_usba(0, NULL);
at32_select_periph(GPIO_PIOB_BASE, 1 << 28, 0, AT32_GPIOF_PULLUP);
at32_select_gpio(i2c_gpio_data.sda_pin,
AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
at32_select_gpio(i2c_gpio_data.scl_pin,
AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
platform_device_register(&i2c_gpio_device);
i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info));
at32_add_device_lcdc(0, &mimc200_lcdc_data,
fbmem_start, fbmem_size, 1);
return 0;
}
postcore_initcall(mimc200_init);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -40,6 +40,9 @@ static unsigned int at32_get_speed(unsigned int cpu)
return (unsigned int)((clk_get_rate(cpuclk) + 500) / 1000);
}
static unsigned int ref_freq;
static unsigned long loops_per_jiffy_ref;
static int at32_set_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
......@@ -61,8 +64,19 @@ static int at32_set_target(struct cpufreq_policy *policy,
freqs.cpu = 0;
freqs.flags = 0;
if (!ref_freq) {
ref_freq = freqs.old;
loops_per_jiffy_ref = boot_cpu_data.loops_per_jiffy;
}
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
if (freqs.old < freqs.new)
boot_cpu_data.loops_per_jiffy = cpufreq_scale(
loops_per_jiffy_ref, ref_freq, freqs.new);
clk_set_rate(cpuclk, freq);
if (freqs.new < freqs.old)
boot_cpu_data.loops_per_jiffy = cpufreq_scale(
loops_per_jiffy_ref, ref_freq, freqs.new);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
pr_debug("cpufreq: set frequency %lu Hz\n", freq);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment