2010-02-05 11:15:07 +00:00
/*
* G4EVM board support
*
* Copyright ( C ) 2010 Magnus Damm
* Copyright ( C ) 2008 Yoshihiro Shimoda
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; version 2 of the License .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/interrupt.h>
# include <linux/irq.h>
# include <linux/platform_device.h>
# include <linux/delay.h>
# include <linux/mtd/mtd.h>
# include <linux/mtd/partitions.h>
# include <linux/mtd/physmap.h>
2010-02-12 08:11:18 +00:00
# include <linux/usb/r8a66597.h>
2010-02-05 11:15:07 +00:00
# include <linux/io.h>
2010-02-23 10:55:10 +00:00
# include <linux/input.h>
# include <linux/input/sh_keysc.h>
2011-01-06 10:41:09 +00:00
# include <linux/mmc/host.h>
2011-03-09 11:27:56 +01:00
# include <linux/mmc/sh_mobile_sdhi.h>
2010-02-12 08:10:06 +00:00
# include <linux/gpio.h>
# include <mach/sh7377.h>
2010-02-05 11:15:07 +00:00
# include <mach/common.h>
# include <asm/mach-types.h>
# include <asm/mach/arch.h>
# include <asm/mach/map.h>
2010-05-21 05:19:34 +00:00
# include <asm/mach/time.h>
2010-02-05 11:15:07 +00:00
2010-03-29 06:31:36 +00:00
/*
* SDHI
*
* SDHI0 : card detection is possible
* SDHI1 : card detection is impossible
*
* [ G4 - MAIN - BOARD ]
* JP74 : short # DBG_2V8A for SDHI0
* JP75 : NC # DBG_3V3A for SDHI0
* JP76 : NC # DBG_3V3A_SD for SDHI0
* JP77 : NC # 3 V3A_SDIO for SDHI1
* JP78 : short # DBG_2V8A for SDHI1
* JP79 : NC # DBG_3V3A for SDHI1
* JP80 : NC # DBG_3V3A_SD for SDHI1
*
* [ G4 - CORE - BOARD ]
* S32 : all off # to dissever from G3 - CORE_DBG board
* S33 : all off # to dissever from G3 - CORE_DBG board
*
* [ G3 - CORE_DBG - BOARD ]
* S1 : all off # to dissever from G3 - CORE_DBG board
* S3 : all off # to dissever from G3 - CORE_DBG board
* S4 : all off # to dissever from G3 - CORE_DBG board
*/
2010-02-05 11:15:07 +00:00
static struct mtd_partition nor_flash_partitions [ ] = {
{
. name = " loader " ,
. offset = 0x00000000 ,
. size = 512 * 1024 ,
} ,
{
. name = " bootenv " ,
. offset = MTDPART_OFS_APPEND ,
. size = 512 * 1024 ,
} ,
{
. name = " kernel_ro " ,
. offset = MTDPART_OFS_APPEND ,
. size = 8 * 1024 * 1024 ,
. mask_flags = MTD_WRITEABLE ,
} ,
{
. name = " kernel " ,
. offset = MTDPART_OFS_APPEND ,
. size = 8 * 1024 * 1024 ,
} ,
{
. name = " data " ,
. offset = MTDPART_OFS_APPEND ,
. size = MTDPART_SIZ_FULL ,
} ,
} ;
static struct physmap_flash_data nor_flash_data = {
. width = 2 ,
. parts = nor_flash_partitions ,
. nr_parts = ARRAY_SIZE ( nor_flash_partitions ) ,
} ;
static struct resource nor_flash_resources [ ] = {
[ 0 ] = {
. start = 0x00000000 ,
. end = 0x08000000 - 1 ,
. flags = IORESOURCE_MEM ,
}
} ;
static struct platform_device nor_flash_device = {
. name = " physmap-flash " ,
. dev = {
. platform_data = & nor_flash_data ,
} ,
. num_resources = ARRAY_SIZE ( nor_flash_resources ) ,
. resource = nor_flash_resources ,
} ;
2010-02-12 08:11:18 +00:00
/* USBHS */
2010-06-02 00:25:14 +00:00
static void usb_host_port_power ( int port , int power )
2010-02-12 08:11:18 +00:00
{
if ( ! power ) /* only power-on supported for now */
return ;
/* set VBOUT/PWEN and EXTLP0 in DVSTCTR */
__raw_writew ( __raw_readw ( 0xe6890008 ) | 0x600 , 0xe6890008 ) ;
}
static struct r8a66597_platdata usb_host_data = {
. on_chip = 1 ,
. port_power = usb_host_port_power ,
} ;
static struct resource usb_host_resources [ ] = {
[ 0 ] = {
. name = " USBHS " ,
. start = 0xe6890000 ,
. end = 0xe68900e5 ,
. flags = IORESOURCE_MEM ,
} ,
[ 1 ] = {
2010-05-20 14:39:21 +00:00
. start = evt2irq ( 0x0a20 ) , /* USBHS_USHI0 */
2010-02-12 08:11:18 +00:00
. flags = IORESOURCE_IRQ ,
} ,
} ;
static struct platform_device usb_host_device = {
. name = " r8a66597_hcd " ,
. id = 0 ,
. dev = {
. platform_data = & usb_host_data ,
. dma_mask = NULL ,
. coherent_dma_mask = 0xffffffff ,
} ,
. num_resources = ARRAY_SIZE ( usb_host_resources ) ,
. resource = usb_host_resources ,
} ;
2010-02-05 11:15:07 +00:00
2010-02-23 10:55:10 +00:00
/* KEYSC */
static struct sh_keysc_info keysc_info = {
. mode = SH_KEYSC_MODE_5 ,
. scan_timing = 3 ,
. delay = 100 ,
. keycodes = {
KEY_A , KEY_B , KEY_C , KEY_D , KEY_E , KEY_F ,
KEY_G , KEY_H , KEY_I , KEY_J , KEY_K , KEY_L ,
KEY_M , KEY_N , KEY_U , KEY_P , KEY_Q , KEY_R ,
KEY_S , KEY_T , KEY_U , KEY_V , KEY_W , KEY_X ,
KEY_Y , KEY_Z , KEY_HOME , KEY_SLEEP , KEY_WAKEUP , KEY_COFFEE ,
KEY_0 , KEY_1 , KEY_2 , KEY_3 , KEY_4 , KEY_5 ,
KEY_6 , KEY_7 , KEY_8 , KEY_9 , KEY_STOP , KEY_COMPUTER ,
} ,
} ;
static struct resource keysc_resources [ ] = {
[ 0 ] = {
. name = " KEYSC " ,
. start = 0xe61b0000 ,
. end = 0xe61b000f ,
. flags = IORESOURCE_MEM ,
} ,
[ 1 ] = {
2010-05-20 14:39:21 +00:00
. start = evt2irq ( 0x0be0 ) , /* KEYSC_KEY */
2010-02-23 10:55:10 +00:00
. flags = IORESOURCE_IRQ ,
} ,
} ;
static struct platform_device keysc_device = {
. name = " sh_keysc " ,
. id = 0 , /* keysc0 clock */
. num_resources = ARRAY_SIZE ( keysc_resources ) ,
. resource = keysc_resources ,
. dev = {
. platform_data = & keysc_info ,
} ,
} ;
2010-03-29 06:31:36 +00:00
/* SDHI */
2011-01-06 10:41:09 +00:00
static struct sh_mobile_sdhi_info sdhi0_info = {
. tmio_caps = MMC_CAP_SDIO_IRQ ,
} ;
2010-03-29 06:31:36 +00:00
static struct resource sdhi0_resources [ ] = {
[ 0 ] = {
. name = " SDHI0 " ,
. start = 0xe6d50000 ,
2011-05-25 14:54:30 +09:00
. end = 0xe6d500ff ,
2010-03-29 06:31:36 +00:00
. flags = IORESOURCE_MEM ,
} ,
[ 1 ] = {
2010-05-20 14:39:21 +00:00
. start = evt2irq ( 0x0e00 ) , /* SDHI0 */
2010-03-29 06:31:36 +00:00
. flags = IORESOURCE_IRQ ,
} ,
} ;
static struct platform_device sdhi0_device = {
. name = " sh_mobile_sdhi " ,
. num_resources = ARRAY_SIZE ( sdhi0_resources ) ,
. resource = sdhi0_resources ,
. id = 0 ,
2011-01-06 10:41:09 +00:00
. dev = {
. platform_data = & sdhi0_info ,
} ,
} ;
static struct sh_mobile_sdhi_info sdhi1_info = {
. tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ ,
2010-03-29 06:31:36 +00:00
} ;
static struct resource sdhi1_resources [ ] = {
[ 0 ] = {
. name = " SDHI1 " ,
. start = 0xe6d60000 ,
2011-03-09 13:09:27 +01:00
. end = 0xe6d600ff ,
2010-03-29 06:31:36 +00:00
. flags = IORESOURCE_MEM ,
} ,
[ 1 ] = {
2010-05-20 14:39:21 +00:00
. start = evt2irq ( 0x0e80 ) , /* SDHI1 */
2010-03-29 06:31:36 +00:00
. flags = IORESOURCE_IRQ ,
} ,
} ;
static struct platform_device sdhi1_device = {
. name = " sh_mobile_sdhi " ,
. num_resources = ARRAY_SIZE ( sdhi1_resources ) ,
. resource = sdhi1_resources ,
. id = 1 ,
2011-01-06 10:41:09 +00:00
. dev = {
. platform_data = & sdhi1_info ,
} ,
2010-03-29 06:31:36 +00:00
} ;
2010-02-05 11:15:07 +00:00
static struct platform_device * g4evm_devices [ ] __initdata = {
& nor_flash_device ,
2010-02-12 08:11:18 +00:00
& usb_host_device ,
2010-02-23 10:55:10 +00:00
& keysc_device ,
2010-03-29 06:31:36 +00:00
& sdhi0_device ,
& sdhi1_device ,
2010-02-05 11:15:07 +00:00
} ;
static struct map_desc g4evm_io_desc [ ] __initdata = {
/* create a 1:1 entity map for 0xe6xxxxxx
* used by CPGA , INTC and PFC .
*/
{
. virtual = 0xe6000000 ,
. pfn = __phys_to_pfn ( 0xe6000000 ) ,
. length = 256 < < 20 ,
. type = MT_DEVICE_NONSHARED
} ,
} ;
static void __init g4evm_map_io ( void )
{
iotable_init ( g4evm_io_desc , ARRAY_SIZE ( g4evm_io_desc ) ) ;
2010-05-21 05:19:34 +00:00
/* setup early devices and console here as well */
2010-02-05 11:15:07 +00:00
sh7377_add_early_devices ( ) ;
2010-02-08 11:02:54 +00:00
shmobile_setup_console ( ) ;
2010-02-05 11:15:07 +00:00
}
2010-03-29 06:31:36 +00:00
# define GPIO_SDHID0_D0 0xe60520fc
# define GPIO_SDHID0_D1 0xe60520fd
# define GPIO_SDHID0_D2 0xe60520fe
# define GPIO_SDHID0_D3 0xe60520ff
# define GPIO_SDHICMD0 0xe6052100
# define GPIO_SDHID1_D0 0xe6052103
# define GPIO_SDHID1_D1 0xe6052104
# define GPIO_SDHID1_D2 0xe6052105
# define GPIO_SDHID1_D3 0xe6052106
# define GPIO_SDHICMD1 0xe6052107
/*
* FIXME ! !
*
* gpio_pull_up is quick_hack .
*
* current gpio frame work doesn ' t have
* the method to control only pull up / down / free .
* this function should be replaced by correct gpio function
*/
static void __init gpio_pull_up ( u32 addr )
{
u8 data = __raw_readb ( addr ) ;
data & = 0x0F ;
data | = 0xC0 ;
__raw_writeb ( data , addr ) ;
}
2010-02-05 11:15:07 +00:00
static void __init g4evm_init ( void )
{
2010-02-12 08:10:06 +00:00
sh7377_pinmux_init ( ) ;
/* Lit DS14 LED */
gpio_request ( GPIO_PORT109 , NULL ) ;
gpio_direction_output ( GPIO_PORT109 , 1 ) ;
gpio_export ( GPIO_PORT109 , 1 ) ;
/* Lit DS15 LED */
gpio_request ( GPIO_PORT110 , NULL ) ;
gpio_direction_output ( GPIO_PORT110 , 1 ) ;
gpio_export ( GPIO_PORT110 , 1 ) ;
/* Lit DS16 LED */
gpio_request ( GPIO_PORT112 , NULL ) ;
gpio_direction_output ( GPIO_PORT112 , 1 ) ;
gpio_export ( GPIO_PORT112 , 1 ) ;
/* Lit DS17 LED */
gpio_request ( GPIO_PORT113 , NULL ) ;
gpio_direction_output ( GPIO_PORT113 , 1 ) ;
gpio_export ( GPIO_PORT113 , 1 ) ;
2010-02-12 08:11:18 +00:00
/* USBHS */
gpio_request ( GPIO_FN_VBUS_0 , NULL ) ;
gpio_request ( GPIO_FN_PWEN , NULL ) ;
gpio_request ( GPIO_FN_OVCN , NULL ) ;
gpio_request ( GPIO_FN_OVCN2 , NULL ) ;
gpio_request ( GPIO_FN_EXTLP , NULL ) ;
gpio_request ( GPIO_FN_IDIN , NULL ) ;
/* setup USB phy */
__raw_writew ( 0x0200 , 0xe605810a ) ; /* USBCR1 */
__raw_writew ( 0x00e0 , 0xe60581c0 ) ; /* CPFCH */
__raw_writew ( 0x6010 , 0xe60581c6 ) ; /* CGPOSR */
__raw_writew ( 0x8a0a , 0xe605810c ) ; /* USBCR2 */
2010-02-23 10:55:10 +00:00
/* KEYSC @ CN31 */
gpio_request ( GPIO_FN_PORT60_KEYOUT5 , NULL ) ;
gpio_request ( GPIO_FN_PORT61_KEYOUT4 , NULL ) ;
gpio_request ( GPIO_FN_PORT62_KEYOUT3 , NULL ) ;
gpio_request ( GPIO_FN_PORT63_KEYOUT2 , NULL ) ;
gpio_request ( GPIO_FN_PORT64_KEYOUT1 , NULL ) ;
gpio_request ( GPIO_FN_PORT65_KEYOUT0 , NULL ) ;
gpio_request ( GPIO_FN_PORT66_KEYIN0_PU , NULL ) ;
gpio_request ( GPIO_FN_PORT67_KEYIN1_PU , NULL ) ;
gpio_request ( GPIO_FN_PORT68_KEYIN2_PU , NULL ) ;
gpio_request ( GPIO_FN_PORT69_KEYIN3_PU , NULL ) ;
gpio_request ( GPIO_FN_PORT70_KEYIN4_PU , NULL ) ;
gpio_request ( GPIO_FN_PORT71_KEYIN5_PU , NULL ) ;
gpio_request ( GPIO_FN_PORT72_KEYIN6_PU , NULL ) ;
2010-03-29 06:31:36 +00:00
/* SDHI0 */
gpio_request ( GPIO_FN_SDHICLK0 , NULL ) ;
gpio_request ( GPIO_FN_SDHICD0 , NULL ) ;
gpio_request ( GPIO_FN_SDHID0_0 , NULL ) ;
gpio_request ( GPIO_FN_SDHID0_1 , NULL ) ;
gpio_request ( GPIO_FN_SDHID0_2 , NULL ) ;
gpio_request ( GPIO_FN_SDHID0_3 , NULL ) ;
gpio_request ( GPIO_FN_SDHICMD0 , NULL ) ;
gpio_request ( GPIO_FN_SDHIWP0 , NULL ) ;
gpio_pull_up ( GPIO_SDHID0_D0 ) ;
gpio_pull_up ( GPIO_SDHID0_D1 ) ;
gpio_pull_up ( GPIO_SDHID0_D2 ) ;
gpio_pull_up ( GPIO_SDHID0_D3 ) ;
gpio_pull_up ( GPIO_SDHICMD0 ) ;
/* SDHI1 */
gpio_request ( GPIO_FN_SDHICLK1 , NULL ) ;
gpio_request ( GPIO_FN_SDHID1_0 , NULL ) ;
gpio_request ( GPIO_FN_SDHID1_1 , NULL ) ;
gpio_request ( GPIO_FN_SDHID1_2 , NULL ) ;
gpio_request ( GPIO_FN_SDHID1_3 , NULL ) ;
gpio_request ( GPIO_FN_SDHICMD1 , NULL ) ;
gpio_pull_up ( GPIO_SDHID1_D0 ) ;
gpio_pull_up ( GPIO_SDHID1_D1 ) ;
gpio_pull_up ( GPIO_SDHID1_D2 ) ;
gpio_pull_up ( GPIO_SDHID1_D3 ) ;
gpio_pull_up ( GPIO_SDHICMD1 ) ;
2010-02-05 11:15:07 +00:00
sh7377_add_standard_devices ( ) ;
platform_add_devices ( g4evm_devices , ARRAY_SIZE ( g4evm_devices ) ) ;
}
2010-05-21 05:19:34 +00:00
static void __init g4evm_timer_init ( void )
{
sh7377_clock_init ( ) ;
shmobile_timer . init ( ) ;
}
static struct sys_timer g4evm_timer = {
. init = g4evm_timer_init ,
} ;
2010-02-05 11:15:07 +00:00
MACHINE_START ( G4EVM , " g4evm " )
. map_io = g4evm_map_io ,
. init_irq = sh7377_init_irq ,
2010-12-28 08:27:01 +00:00
. handle_irq = shmobile_handle_irq_intc ,
2010-02-05 11:15:07 +00:00
. init_machine = g4evm_init ,
2010-05-21 05:19:34 +00:00
. timer = & g4evm_timer ,
2010-02-05 11:15:07 +00:00
MACHINE_END