2010-09-02 21:58:07 +04:00
/*
* Critical Link MityOMAP - L138 SoM
*
* Copyright ( C ) 2010 Critical Link LLC - http : //www.criticallink.com
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed " as is " without any warranty of
* any kind , whether express or implied .
*/
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/console.h>
# include <linux/platform_device.h>
# include <linux/mtd/partitions.h>
2010-09-05 21:29:39 +04:00
# include <linux/regulator/machine.h>
# include <linux/i2c.h>
2010-09-17 17:56:06 +04:00
# include <linux/i2c/at24.h>
# include <linux/etherdevice.h>
2011-02-24 07:52:47 +03:00
# include <linux/spi/spi.h>
# include <linux/spi/flash.h>
2010-09-02 21:58:07 +04:00
# include <asm/mach-types.h>
# include <asm/mach/arch.h>
# include <mach/common.h>
# include <mach/cp_intc.h>
# include <mach/da8xx.h>
# include <mach/nand.h>
# include <mach/mux.h>
2011-02-24 07:52:47 +03:00
# include <mach/spi.h>
2010-09-02 21:58:07 +04:00
2010-09-15 18:11:25 +04:00
# define MITYOMAPL138_PHY_ID "0:03"
2010-09-17 17:56:06 +04:00
# define FACTORY_CONFIG_MAGIC 0x012C0138
# define FACTORY_CONFIG_VERSION 0x00010001
/* Data Held in On-Board I2C device */
struct factory_config {
u32 magic ;
u32 version ;
u8 mac [ 6 ] ;
u32 fpga_type ;
u32 spare ;
u32 serialnumber ;
char partnum [ 32 ] ;
} ;
static struct factory_config factory_config ;
2011-01-04 15:50:23 +03:00
struct part_no_info {
const char * part_no ; /* part number string of interest */
int max_freq ; /* khz */
} ;
static struct part_no_info mityomapl138_pn_info [ ] = {
{
. part_no = " L138-C " ,
. max_freq = 300000 ,
} ,
{
. part_no = " L138-D " ,
. max_freq = 375000 ,
} ,
{
. part_no = " L138-F " ,
. max_freq = 456000 ,
} ,
{
. part_no = " 1808-C " ,
. max_freq = 300000 ,
} ,
{
. part_no = " 1808-D " ,
. max_freq = 375000 ,
} ,
{
. part_no = " 1808-F " ,
. max_freq = 456000 ,
} ,
{
. part_no = " 1810-D " ,
. max_freq = 375000 ,
} ,
} ;
# ifdef CONFIG_CPU_FREQ
static void mityomapl138_cpufreq_init ( const char * partnum )
{
int i , ret ;
for ( i = 0 ; partnum & & i < ARRAY_SIZE ( mityomapl138_pn_info ) ; i + + ) {
/*
* the part number has additional characters beyond what is
* stored in the table . This information is not needed for
* determining the speed grade , and would require several
* more table entries . Only check the first N characters
* for a match .
*/
if ( ! strncmp ( partnum , mityomapl138_pn_info [ i ] . part_no ,
strlen ( mityomapl138_pn_info [ i ] . part_no ) ) ) {
da850_max_speed = mityomapl138_pn_info [ i ] . max_freq ;
break ;
}
}
ret = da850_register_cpufreq ( " pll0_sysclk3 " ) ;
if ( ret )
pr_warning ( " cpufreq registration failed: %d \n " , ret ) ;
}
# else
static void mityomapl138_cpufreq_init ( const char * partnum ) { }
# endif
2010-09-17 17:56:06 +04:00
static void read_factory_config ( struct memory_accessor * a , void * context )
{
int ret ;
2011-01-04 15:50:23 +03:00
const char * partnum = NULL ;
2010-09-17 17:56:06 +04:00
struct davinci_soc_info * soc_info = & davinci_soc_info ;
ret = a - > read ( a , ( char * ) & factory_config , 0 , sizeof ( factory_config ) ) ;
if ( ret ! = sizeof ( struct factory_config ) ) {
pr_warning ( " MityOMAPL138: Read Factory Config Failed: %d \n " ,
ret ) ;
2011-01-04 15:50:23 +03:00
goto bad_config ;
2010-09-17 17:56:06 +04:00
}
if ( factory_config . magic ! = FACTORY_CONFIG_MAGIC ) {
pr_warning ( " MityOMAPL138: Factory Config Magic Wrong (%X) \n " ,
factory_config . magic ) ;
2011-01-04 15:50:23 +03:00
goto bad_config ;
2010-09-17 17:56:06 +04:00
}
if ( factory_config . version ! = FACTORY_CONFIG_VERSION ) {
pr_warning ( " MityOMAPL138: Factory Config Version Wrong (%X) \n " ,
factory_config . version ) ;
2011-01-04 15:50:23 +03:00
goto bad_config ;
2010-09-17 17:56:06 +04:00
}
pr_info ( " MityOMAPL138: Found MAC = %pM \n " , factory_config . mac ) ;
if ( is_valid_ether_addr ( factory_config . mac ) )
memcpy ( soc_info - > emac_pdata - > mac_addr ,
factory_config . mac , ETH_ALEN ) ;
else
pr_warning ( " MityOMAPL138: Invalid MAC found "
" in factory config block \n " ) ;
2011-01-04 15:50:23 +03:00
partnum = factory_config . partnum ;
pr_info ( " MityOMAPL138: Part Number = %s \n " , partnum ) ;
bad_config :
/* default maximum speed is valid for all platforms */
mityomapl138_cpufreq_init ( partnum ) ;
2010-09-17 17:56:06 +04:00
}
static struct at24_platform_data mityomapl138_fd_chip = {
. byte_len = 256 ,
. page_size = 8 ,
. flags = AT24_FLAG_READONLY | AT24_FLAG_IRUGO ,
. setup = read_factory_config ,
. context = NULL ,
} ;
2010-09-05 21:29:39 +04:00
static struct davinci_i2c_platform_data mityomap_i2c_0_pdata = {
. bus_freq = 100 , /* kHz */
. bus_delay = 0 , /* usec */
} ;
/* TPS65023 voltage regulator support */
/* 1.2V Core */
2010-10-12 08:55:22 +04:00
static struct regulator_consumer_supply tps65023_dcdc1_consumers [ ] = {
2010-09-05 21:29:39 +04:00
{
. supply = " cvdd " ,
} ,
} ;
/* 1.8V */
2010-10-12 08:55:22 +04:00
static struct regulator_consumer_supply tps65023_dcdc2_consumers [ ] = {
2010-09-05 21:29:39 +04:00
{
. supply = " usb0_vdda18 " ,
} ,
{
. supply = " usb1_vdda18 " ,
} ,
{
. supply = " ddr_dvdd18 " ,
} ,
{
. supply = " sata_vddr " ,
} ,
} ;
/* 1.2V */
2010-10-12 08:55:22 +04:00
static struct regulator_consumer_supply tps65023_dcdc3_consumers [ ] = {
2010-09-05 21:29:39 +04:00
{
. supply = " sata_vdd " ,
} ,
{
. supply = " usb_cvdd " ,
} ,
{
. supply = " pll0_vdda " ,
} ,
{
. supply = " pll1_vdda " ,
} ,
} ;
/* 1.8V Aux LDO, not used */
2010-10-12 08:55:22 +04:00
static struct regulator_consumer_supply tps65023_ldo1_consumers [ ] = {
2010-09-05 21:29:39 +04:00
{
. supply = " 1.8v_aux " ,
} ,
} ;
/* FPGA VCC Aux (2.5 or 3.3) LDO */
2010-10-12 08:55:22 +04:00
static struct regulator_consumer_supply tps65023_ldo2_consumers [ ] = {
2010-09-05 21:29:39 +04:00
{
. supply = " vccaux " ,
} ,
} ;
2010-10-12 08:55:22 +04:00
static struct regulator_init_data tps65023_regulator_data [ ] = {
2010-09-05 21:29:39 +04:00
/* dcdc1 */
{
. constraints = {
. min_uV = 1150000 ,
. max_uV = 1350000 ,
. valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
REGULATOR_CHANGE_STATUS ,
. boot_on = 1 ,
} ,
. num_consumer_supplies = ARRAY_SIZE ( tps65023_dcdc1_consumers ) ,
. consumer_supplies = tps65023_dcdc1_consumers ,
} ,
/* dcdc2 */
{
. constraints = {
. min_uV = 1800000 ,
. max_uV = 1800000 ,
. valid_ops_mask = REGULATOR_CHANGE_STATUS ,
. boot_on = 1 ,
} ,
. num_consumer_supplies = ARRAY_SIZE ( tps65023_dcdc2_consumers ) ,
. consumer_supplies = tps65023_dcdc2_consumers ,
} ,
/* dcdc3 */
{
. constraints = {
. min_uV = 1200000 ,
. max_uV = 1200000 ,
. valid_ops_mask = REGULATOR_CHANGE_STATUS ,
. boot_on = 1 ,
} ,
. num_consumer_supplies = ARRAY_SIZE ( tps65023_dcdc3_consumers ) ,
. consumer_supplies = tps65023_dcdc3_consumers ,
} ,
/* ldo1 */
{
. constraints = {
. min_uV = 1800000 ,
. max_uV = 1800000 ,
. valid_ops_mask = REGULATOR_CHANGE_STATUS ,
. boot_on = 1 ,
} ,
. num_consumer_supplies = ARRAY_SIZE ( tps65023_ldo1_consumers ) ,
. consumer_supplies = tps65023_ldo1_consumers ,
} ,
/* ldo2 */
{
. constraints = {
. min_uV = 2500000 ,
. max_uV = 3300000 ,
. valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
REGULATOR_CHANGE_STATUS ,
. boot_on = 1 ,
} ,
. num_consumer_supplies = ARRAY_SIZE ( tps65023_ldo2_consumers ) ,
. consumer_supplies = tps65023_ldo2_consumers ,
} ,
} ;
static struct i2c_board_info __initdata mityomap_tps65023_info [ ] = {
{
I2C_BOARD_INFO ( " tps65023 " , 0x48 ) ,
. platform_data = & tps65023_regulator_data [ 0 ] ,
} ,
{
I2C_BOARD_INFO ( " 24c02 " , 0x50 ) ,
2010-09-17 17:56:06 +04:00
. platform_data = & mityomapl138_fd_chip ,
2010-09-05 21:29:39 +04:00
} ,
} ;
static int __init pmic_tps65023_init ( void )
{
return i2c_register_board_info ( 1 , mityomap_tps65023_info ,
ARRAY_SIZE ( mityomap_tps65023_info ) ) ;
}
2011-02-24 07:52:47 +03:00
/*
* SPI Devices :
* SPI1_CS0 : 8 M Flash ST - M25P64 - VME6G
*/
static struct mtd_partition spi_flash_partitions [ ] = {
[ 0 ] = {
. name = " ubl " ,
. offset = 0 ,
. size = SZ_64K ,
. mask_flags = MTD_WRITEABLE ,
} ,
[ 1 ] = {
. name = " u-boot " ,
. offset = MTDPART_OFS_APPEND ,
. size = SZ_512K ,
. mask_flags = MTD_WRITEABLE ,
} ,
[ 2 ] = {
. name = " u-boot-env " ,
. offset = MTDPART_OFS_APPEND ,
. size = SZ_64K ,
. mask_flags = MTD_WRITEABLE ,
} ,
[ 3 ] = {
. name = " periph-config " ,
. offset = MTDPART_OFS_APPEND ,
. size = SZ_64K ,
. mask_flags = MTD_WRITEABLE ,
} ,
[ 4 ] = {
. name = " reserved " ,
. offset = MTDPART_OFS_APPEND ,
. size = SZ_256K + SZ_64K ,
} ,
[ 5 ] = {
. name = " kernel " ,
. offset = MTDPART_OFS_APPEND ,
. size = SZ_2M + SZ_1M ,
} ,
[ 6 ] = {
. name = " fpga " ,
. offset = MTDPART_OFS_APPEND ,
. size = SZ_2M ,
} ,
[ 7 ] = {
. name = " spare " ,
. offset = MTDPART_OFS_APPEND ,
. size = MTDPART_SIZ_FULL ,
} ,
} ;
static struct flash_platform_data mityomapl138_spi_flash_data = {
. name = " m25p80 " ,
. parts = spi_flash_partitions ,
. nr_parts = ARRAY_SIZE ( spi_flash_partitions ) ,
. type = " m24p64 " ,
} ;
static struct davinci_spi_config spi_eprom_config = {
. io_type = SPI_IO_TYPE_DMA ,
. c2tdelay = 8 ,
. t2cdelay = 8 ,
} ;
static struct spi_board_info mityomapl138_spi_flash_info [ ] = {
{
. modalias = " m25p80 " ,
. platform_data = & mityomapl138_spi_flash_data ,
. controller_data = & spi_eprom_config ,
. mode = SPI_MODE_0 ,
. max_speed_hz = 30000000 ,
. bus_num = 1 ,
. chip_select = 0 ,
} ,
} ;
2010-09-02 21:58:07 +04:00
/*
* MityDSP - L138 includes a 256 MByte large - page NAND flash
* ( 128 K blocks ) .
*/
2010-10-12 08:55:22 +04:00
static struct mtd_partition mityomapl138_nandflash_partition [ ] = {
2010-09-02 21:58:07 +04:00
{
. name = " rootfs " ,
. offset = 0 ,
. size = SZ_128M ,
. mask_flags = 0 , /* MTD_WRITEABLE, */
} ,
{
. name = " homefs " ,
. offset = MTDPART_OFS_APPEND ,
. size = MTDPART_SIZ_FULL ,
. mask_flags = 0 ,
} ,
} ;
static struct davinci_nand_pdata mityomapl138_nandflash_data = {
. parts = mityomapl138_nandflash_partition ,
. nr_parts = ARRAY_SIZE ( mityomapl138_nandflash_partition ) ,
. ecc_mode = NAND_ECC_HW ,
. options = NAND_USE_FLASH_BBT | NAND_BUSWIDTH_16 ,
. ecc_bits = 1 , /* 4 bit mode is not supported with 16 bit NAND */
} ;
static struct resource mityomapl138_nandflash_resource [ ] = {
{
. start = DA8XX_AEMIF_CS3_BASE ,
. end = DA8XX_AEMIF_CS3_BASE + SZ_512K + 2 * SZ_1K - 1 ,
. flags = IORESOURCE_MEM ,
} ,
{
. start = DA8XX_AEMIF_CTL_BASE ,
. end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1 ,
. flags = IORESOURCE_MEM ,
} ,
} ;
static struct platform_device mityomapl138_nandflash_device = {
. name = " davinci_nand " ,
. id = 0 ,
. dev = {
. platform_data = & mityomapl138_nandflash_data ,
} ,
. num_resources = ARRAY_SIZE ( mityomapl138_nandflash_resource ) ,
. resource = mityomapl138_nandflash_resource ,
} ;
static struct platform_device * mityomapl138_devices [ ] __initdata = {
& mityomapl138_nandflash_device ,
} ;
static void __init mityomapl138_setup_nand ( void )
{
platform_add_devices ( mityomapl138_devices ,
ARRAY_SIZE ( mityomapl138_devices ) ) ;
}
static struct davinci_uart_config mityomapl138_uart_config __initdata = {
. enabled_uarts = 0x7 ,
} ;
static const short mityomap_mii_pins [ ] = {
DA850_MII_TXEN , DA850_MII_TXCLK , DA850_MII_COL , DA850_MII_TXD_3 ,
DA850_MII_TXD_2 , DA850_MII_TXD_1 , DA850_MII_TXD_0 , DA850_MII_RXER ,
DA850_MII_CRS , DA850_MII_RXCLK , DA850_MII_RXDV , DA850_MII_RXD_3 ,
DA850_MII_RXD_2 , DA850_MII_RXD_1 , DA850_MII_RXD_0 , DA850_MDIO_CLK ,
DA850_MDIO_D ,
- 1
} ;
static const short mityomap_rmii_pins [ ] = {
DA850_RMII_TXD_0 , DA850_RMII_TXD_1 , DA850_RMII_TXEN ,
DA850_RMII_CRS_DV , DA850_RMII_RXD_0 , DA850_RMII_RXD_1 ,
DA850_RMII_RXER , DA850_RMII_MHZ_50_CLK , DA850_MDIO_CLK ,
DA850_MDIO_D ,
- 1
} ;
static void __init mityomapl138_config_emac ( void )
{
void __iomem * cfg_chip3_base ;
int ret ;
u32 val ;
struct davinci_soc_info * soc_info = & davinci_soc_info ;
soc_info - > emac_pdata - > rmii_en = 0 ; /* hardcoded for now */
cfg_chip3_base = DA8XX_SYSCFG0_VIRT ( DA8XX_CFGCHIP3_REG ) ;
val = __raw_readl ( cfg_chip3_base ) ;
if ( soc_info - > emac_pdata - > rmii_en ) {
val | = BIT ( 8 ) ;
ret = davinci_cfg_reg_list ( mityomap_rmii_pins ) ;
pr_info ( " RMII PHY configured \n " ) ;
} else {
val & = ~ BIT ( 8 ) ;
ret = davinci_cfg_reg_list ( mityomap_mii_pins ) ;
pr_info ( " MII PHY configured \n " ) ;
}
if ( ret ) {
pr_warning ( " mii/rmii mux setup failed: %d \n " , ret ) ;
return ;
}
/* configure the CFGCHIP3 register for RMII or MII */
__raw_writel ( val , cfg_chip3_base ) ;
2010-09-15 18:11:25 +04:00
soc_info - > emac_pdata - > phy_id = MITYOMAPL138_PHY_ID ;
2010-09-02 21:58:07 +04:00
ret = da8xx_register_emac ( ) ;
if ( ret )
pr_warning ( " emac registration failed: %d \n " , ret ) ;
}
static struct davinci_pm_config da850_pm_pdata = {
. sleepcount = 128 ,
} ;
static struct platform_device da850_pm_device = {
. name = " pm-davinci " ,
. dev = {
. platform_data = & da850_pm_pdata ,
} ,
. id = - 1 ,
} ;
static void __init mityomapl138_init ( void )
{
int ret ;
/* for now, no special EDMA channels are reserved */
ret = da850_register_edma ( NULL ) ;
if ( ret )
pr_warning ( " edma registration failed: %d \n " , ret ) ;
ret = da8xx_register_watchdog ( ) ;
if ( ret )
pr_warning ( " watchdog registration failed: %d \n " , ret ) ;
davinci_serial_init ( & mityomapl138_uart_config ) ;
2010-09-05 21:29:39 +04:00
ret = da8xx_register_i2c ( 0 , & mityomap_i2c_0_pdata ) ;
if ( ret )
pr_warning ( " i2c0 registration failed: %d \n " , ret ) ;
ret = pmic_tps65023_init ( ) ;
if ( ret )
pr_warning ( " TPS65023 PMIC init failed: %d \n " , ret ) ;
2010-09-02 21:58:07 +04:00
mityomapl138_setup_nand ( ) ;
2011-02-24 07:52:47 +03:00
ret = da8xx_register_spi ( 1 , mityomapl138_spi_flash_info ,
ARRAY_SIZE ( mityomapl138_spi_flash_info ) ) ;
if ( ret )
pr_warning ( " spi 1 registration failed: %d \n " , ret ) ;
2010-09-02 21:58:07 +04:00
mityomapl138_config_emac ( ) ;
ret = da8xx_register_rtc ( ) ;
if ( ret )
pr_warning ( " rtc setup failed: %d \n " , ret ) ;
ret = da8xx_register_cpuidle ( ) ;
if ( ret )
pr_warning ( " cpuidle registration failed: %d \n " , ret ) ;
ret = da850_register_pm ( & da850_pm_device ) ;
if ( ret )
pr_warning ( " da850_evm_init: suspend registration failed: %d \n " ,
ret ) ;
}
# ifdef CONFIG_SERIAL_8250_CONSOLE
static int __init mityomapl138_console_init ( void )
{
if ( ! machine_is_mityomapl138 ( ) )
return 0 ;
return add_preferred_console ( " ttyS " , 1 , " 115200 " ) ;
}
console_initcall ( mityomapl138_console_init ) ;
# endif
static void __init mityomapl138_map_io ( void )
{
da850_init ( ) ;
}
MACHINE_START ( MITYOMAPL138 , " MityDSP-L138/MityARM-1808 " )
. boot_params = ( DA8XX_DDR_BASE + 0x100 ) ,
. map_io = mityomapl138_map_io ,
. init_irq = cp_intc_init ,
. timer = & davinci_timer ,
. init_machine = mityomapl138_init ,
MACHINE_END