cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mach-anubis.c (9881B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// Copyright 2003-2009 Simtec Electronics
      4//	http://armlinux.simtec.co.uk/
      5//	Ben Dooks <ben@simtec.co.uk>
      6
      7#include <linux/kernel.h>
      8#include <linux/types.h>
      9#include <linux/interrupt.h>
     10#include <linux/list.h>
     11#include <linux/timer.h>
     12#include <linux/init.h>
     13#include <linux/gpio.h>
     14#include <linux/serial_core.h>
     15#include <linux/serial_s3c.h>
     16#include <linux/platform_device.h>
     17#include <linux/ata_platform.h>
     18#include <linux/i2c.h>
     19#include <linux/io.h>
     20#include <linux/sm501.h>
     21#include <linux/sm501-regs.h>
     22
     23#include <asm/mach/arch.h>
     24#include <asm/mach/map.h>
     25#include <asm/mach/irq.h>
     26
     27#include <asm/irq.h>
     28#include <asm/mach-types.h>
     29
     30#include "regs-gpio.h"
     31#include "gpio-samsung.h"
     32#include <linux/platform_data/mtd-nand-s3c2410.h>
     33#include <linux/platform_data/i2c-s3c2410.h>
     34
     35#include <linux/mtd/mtd.h>
     36#include <linux/mtd/rawnand.h>
     37#include <linux/mtd/nand-ecc-sw-hamming.h>
     38#include <linux/mtd/partitions.h>
     39
     40#include <net/ax88796.h>
     41
     42#include "devs.h"
     43#include "cpu.h"
     44#include <linux/platform_data/asoc-s3c24xx_simtec.h>
     45
     46#include "anubis.h"
     47#include "s3c24xx.h"
     48#include "simtec.h"
     49
     50#define COPYRIGHT ", Copyright 2005-2009 Simtec Electronics"
     51
     52static struct map_desc anubis_iodesc[] __initdata = {
     53  /* ISA IO areas */
     54
     55  {
     56	.virtual	= (u32)S3C24XX_VA_ISA_BYTE,
     57	.pfn		= __phys_to_pfn(0x0),
     58	.length		= SZ_4M,
     59	.type		= MT_DEVICE,
     60  },
     61
     62  /* we could possibly compress the next set down into a set of smaller tables
     63   * pagetables, but that would mean using an L2 section, and it still means
     64   * we cannot actually feed the same register to an LDR due to 16K spacing
     65   */
     66
     67  /* CPLD control registers */
     68
     69  {
     70	.virtual	= (u32)ANUBIS_VA_CTRL1,
     71	.pfn		= __phys_to_pfn(ANUBIS_PA_CTRL1),
     72	.length		= SZ_4K,
     73	.type		= MT_DEVICE,
     74  }, {
     75	.virtual	= (u32)ANUBIS_VA_IDREG,
     76	.pfn		= __phys_to_pfn(ANUBIS_PA_IDREG),
     77	.length		= SZ_4K,
     78	.type		= MT_DEVICE,
     79  },
     80};
     81
     82#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
     83#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
     84#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
     85
     86static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
     87	[0] = {
     88		.hwport	     = 0,
     89		.flags	     = 0,
     90		.ucon	     = UCON,
     91		.ulcon	     = ULCON,
     92		.ufcon	     = UFCON,
     93		.clk_sel	= S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
     94	},
     95	[1] = {
     96		.hwport	     = 2,
     97		.flags	     = 0,
     98		.ucon	     = UCON,
     99		.ulcon	     = ULCON,
    100		.ufcon	     = UFCON,
    101		.clk_sel	= S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
    102	},
    103};
    104
    105/* NAND Flash on Anubis board */
    106
    107static int external_map[]   = { 2 };
    108static int chip0_map[]      = { 0 };
    109static int chip1_map[]      = { 1 };
    110
    111static struct mtd_partition __initdata anubis_default_nand_part[] = {
    112	[0] = {
    113		.name	= "Boot Agent",
    114		.size	= SZ_16K,
    115		.offset	= 0,
    116	},
    117	[1] = {
    118		.name	= "/boot",
    119		.size	= SZ_4M - SZ_16K,
    120		.offset	= SZ_16K,
    121	},
    122	[2] = {
    123		.name	= "user1",
    124		.offset	= SZ_4M,
    125		.size	= SZ_32M - SZ_4M,
    126	},
    127	[3] = {
    128		.name	= "user2",
    129		.offset	= SZ_32M,
    130		.size	= MTDPART_SIZ_FULL,
    131	}
    132};
    133
    134static struct mtd_partition __initdata anubis_default_nand_part_large[] = {
    135	[0] = {
    136		.name	= "Boot Agent",
    137		.size	= SZ_128K,
    138		.offset	= 0,
    139	},
    140	[1] = {
    141		.name	= "/boot",
    142		.size	= SZ_4M - SZ_128K,
    143		.offset	= SZ_128K,
    144	},
    145	[2] = {
    146		.name	= "user1",
    147		.offset	= SZ_4M,
    148		.size	= SZ_32M - SZ_4M,
    149	},
    150	[3] = {
    151		.name	= "user2",
    152		.offset	= SZ_32M,
    153		.size	= MTDPART_SIZ_FULL,
    154	}
    155};
    156
    157/* the Anubis has 3 selectable slots for nand-flash, the two
    158 * on-board chip areas, as well as the external slot.
    159 *
    160 * Note, there is no current hot-plug support for the External
    161 * socket.
    162*/
    163
    164static struct s3c2410_nand_set __initdata anubis_nand_sets[] = {
    165	[1] = {
    166		.name		= "External",
    167		.nr_chips	= 1,
    168		.nr_map		= external_map,
    169		.nr_partitions	= ARRAY_SIZE(anubis_default_nand_part),
    170		.partitions	= anubis_default_nand_part,
    171	},
    172	[0] = {
    173		.name		= "chip0",
    174		.nr_chips	= 1,
    175		.nr_map		= chip0_map,
    176		.nr_partitions	= ARRAY_SIZE(anubis_default_nand_part),
    177		.partitions	= anubis_default_nand_part,
    178	},
    179	[2] = {
    180		.name		= "chip1",
    181		.nr_chips	= 1,
    182		.nr_map		= chip1_map,
    183		.nr_partitions	= ARRAY_SIZE(anubis_default_nand_part),
    184		.partitions	= anubis_default_nand_part,
    185	},
    186};
    187
    188static void anubis_nand_select(struct s3c2410_nand_set *set, int slot)
    189{
    190	unsigned int tmp;
    191
    192	slot = set->nr_map[slot] & 3;
    193
    194	pr_debug("anubis_nand: selecting slot %d (set %p,%p)\n",
    195		 slot, set, set->nr_map);
    196
    197	tmp = __raw_readb(ANUBIS_VA_CTRL1);
    198	tmp &= ~ANUBIS_CTRL1_NANDSEL;
    199	tmp |= slot;
    200
    201	pr_debug("anubis_nand: ctrl1 now %02x\n", tmp);
    202
    203	__raw_writeb(tmp, ANUBIS_VA_CTRL1);
    204}
    205
    206static struct s3c2410_platform_nand __initdata anubis_nand_info = {
    207	.tacls		= 25,
    208	.twrph0		= 55,
    209	.twrph1		= 40,
    210	.nr_sets	= ARRAY_SIZE(anubis_nand_sets),
    211	.sets		= anubis_nand_sets,
    212	.select_chip	= anubis_nand_select,
    213	.engine_type	= NAND_ECC_ENGINE_TYPE_SOFT,
    214};
    215
    216/* IDE channels */
    217
    218static struct pata_platform_info anubis_ide_platdata = {
    219	.ioport_shift	= 5,
    220};
    221
    222static struct resource anubis_ide0_resource[] = {
    223	[0] = DEFINE_RES_MEM(S3C2410_CS3, 8 * 32),
    224	[2] = DEFINE_RES_MEM(S3C2410_CS3 + (1 << 26) + (6 * 32), 32),
    225	[3] = DEFINE_RES_IRQ(ANUBIS_IRQ_IDE0),
    226};
    227
    228static struct platform_device anubis_device_ide0 = {
    229	.name		= "pata_platform",
    230	.id		= 0,
    231	.num_resources	= ARRAY_SIZE(anubis_ide0_resource),
    232	.resource	= anubis_ide0_resource,
    233	.dev	= {
    234		.platform_data = &anubis_ide_platdata,
    235		.coherent_dma_mask = ~0,
    236	},
    237};
    238
    239static struct resource anubis_ide1_resource[] = {
    240	[0] = DEFINE_RES_MEM(S3C2410_CS4, 8 * 32),
    241	[1] = DEFINE_RES_MEM(S3C2410_CS4 + (1 << 26) + (6 * 32), 32),
    242	[2] = DEFINE_RES_IRQ(ANUBIS_IRQ_IDE0),
    243};
    244
    245static struct platform_device anubis_device_ide1 = {
    246	.name		= "pata_platform",
    247	.id		= 1,
    248	.num_resources	= ARRAY_SIZE(anubis_ide1_resource),
    249	.resource	= anubis_ide1_resource,
    250	.dev	= {
    251		.platform_data = &anubis_ide_platdata,
    252		.coherent_dma_mask = ~0,
    253	},
    254};
    255
    256/* Asix AX88796 10/100 ethernet controller */
    257
    258static struct ax_plat_data anubis_asix_platdata = {
    259	.flags		= AXFLG_MAC_FROMDEV,
    260	.wordlength	= 2,
    261	.dcr_val	= 0x48,
    262	.rcr_val	= 0x40,
    263};
    264
    265static struct resource anubis_asix_resource[] = {
    266	[0] = DEFINE_RES_MEM(S3C2410_CS5, 0x20 * 0x20),
    267	[1] = DEFINE_RES_IRQ(ANUBIS_IRQ_ASIX),
    268};
    269
    270static struct platform_device anubis_device_asix = {
    271	.name		= "ax88796",
    272	.id		= 0,
    273	.num_resources	= ARRAY_SIZE(anubis_asix_resource),
    274	.resource	= anubis_asix_resource,
    275	.dev		= {
    276		.platform_data = &anubis_asix_platdata,
    277	}
    278};
    279
    280/* SM501 */
    281
    282static struct resource anubis_sm501_resource[] = {
    283	[0] = DEFINE_RES_MEM(S3C2410_CS2, SZ_8M),
    284	[1] = DEFINE_RES_MEM(S3C2410_CS2 + SZ_64M - SZ_2M, SZ_2M),
    285	[2] = DEFINE_RES_IRQ(IRQ_EINT0),
    286};
    287
    288static struct sm501_initdata anubis_sm501_initdata = {
    289	.gpio_high	= {
    290		.set	= 0x3F000000,		/* 24bit panel */
    291		.mask	= 0x0,
    292	},
    293	.misc_timing	= {
    294		.set	= 0x010100,		/* SDRAM timing */
    295		.mask	= 0x1F1F00,
    296	},
    297	.misc_control	= {
    298		.set	= SM501_MISC_PNL_24BIT,
    299		.mask	= 0,
    300	},
    301
    302	.devices	= SM501_USE_GPIO,
    303
    304	/* set the SDRAM and bus clocks */
    305	.mclk		= 72 * MHZ,
    306	.m1xclk		= 144 * MHZ,
    307};
    308
    309static struct sm501_platdata_gpio_i2c anubis_sm501_gpio_i2c[] = {
    310	[0] = {
    311		.bus_num	= 1,
    312		.pin_scl	= 44,
    313		.pin_sda	= 45,
    314	},
    315	[1] = {
    316		.bus_num	= 2,
    317		.pin_scl	= 40,
    318		.pin_sda	= 41,
    319	},
    320};
    321
    322static struct sm501_platdata anubis_sm501_platdata = {
    323	.init		= &anubis_sm501_initdata,
    324	.gpio_base	= -1,
    325	.gpio_i2c	= anubis_sm501_gpio_i2c,
    326	.gpio_i2c_nr	= ARRAY_SIZE(anubis_sm501_gpio_i2c),
    327};
    328
    329static struct platform_device anubis_device_sm501 = {
    330	.name		= "sm501",
    331	.id		= 0,
    332	.num_resources	= ARRAY_SIZE(anubis_sm501_resource),
    333	.resource	= anubis_sm501_resource,
    334	.dev		= {
    335		.platform_data = &anubis_sm501_platdata,
    336	},
    337};
    338
    339/* Standard Anubis devices */
    340
    341static struct platform_device *anubis_devices[] __initdata = {
    342	&s3c2410_device_dclk,
    343	&s3c_device_ohci,
    344	&s3c_device_wdt,
    345	&s3c_device_adc,
    346	&s3c_device_i2c0,
    347 	&s3c_device_rtc,
    348	&s3c_device_nand,
    349	&anubis_device_ide0,
    350	&anubis_device_ide1,
    351	&anubis_device_asix,
    352	&anubis_device_sm501,
    353};
    354
    355/* I2C devices. */
    356
    357static struct i2c_board_info anubis_i2c_devs[] __initdata = {
    358	{
    359		I2C_BOARD_INFO("tps65011", 0x48),
    360		.irq	= IRQ_EINT20,
    361	}
    362};
    363
    364/* Audio setup */
    365static struct s3c24xx_audio_simtec_pdata __initdata anubis_audio = {
    366	.have_mic	= 1,
    367	.have_lout	= 1,
    368	.output_cdclk	= 1,
    369	.use_mpllin	= 1,
    370	.amp_gpio	= S3C2410_GPB(2),
    371	.amp_gain[0]	= S3C2410_GPD(10),
    372	.amp_gain[1]	= S3C2410_GPD(11),
    373};
    374
    375static void __init anubis_map_io(void)
    376{
    377	s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
    378	s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
    379	s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4);
    380
    381	/* check for the newer revision boards with large page nand */
    382
    383	if ((__raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK) >= 4) {
    384		printk(KERN_INFO "ANUBIS-B detected (revision %d)\n",
    385		       __raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK);
    386		anubis_nand_sets[0].partitions = anubis_default_nand_part_large;
    387		anubis_nand_sets[0].nr_partitions = ARRAY_SIZE(anubis_default_nand_part_large);
    388	} else {
    389		/* ensure that the GPIO is setup */
    390		gpio_request_one(S3C2410_GPA(0), GPIOF_OUT_INIT_HIGH, NULL);
    391		gpio_free(S3C2410_GPA(0));
    392	}
    393}
    394
    395static void __init anubis_init_time(void)
    396{
    397	s3c2440_init_clocks(12000000);
    398	s3c24xx_timer_init();
    399}
    400
    401static void __init anubis_init(void)
    402{
    403	s3c_i2c0_set_platdata(NULL);
    404	s3c_nand_set_platdata(&anubis_nand_info);
    405	simtec_audio_add(NULL, false, &anubis_audio);
    406
    407	platform_add_devices(anubis_devices, ARRAY_SIZE(anubis_devices));
    408
    409	i2c_register_board_info(0, anubis_i2c_devs,
    410				ARRAY_SIZE(anubis_i2c_devs));
    411}
    412
    413
    414MACHINE_START(ANUBIS, "Simtec-Anubis")
    415	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
    416	.atag_offset	= 0x100,
    417	.nr_irqs	= NR_IRQS_S3C2440,
    418	.map_io		= anubis_map_io,
    419	.init_machine	= anubis_init,
    420	.init_irq	= s3c2440_init_irq,
    421	.init_time	= anubis_init_time,
    422MACHINE_END