Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Copyright 2003-2008 Simtec Electronics
0004 //   Ben Dooks <ben@simtec.co.uk>
0005 //
0006 // http://www.simtec.co.uk/products/EB2410ITX/
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/types.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/list.h>
0012 #include <linux/timer.h>
0013 #include <linux/init.h>
0014 #include <linux/gpio.h>
0015 #include <linux/syscore_ops.h>
0016 #include <linux/serial_core.h>
0017 #include <linux/serial_s3c.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/dm9000.h>
0020 #include <linux/ata_platform.h>
0021 #include <linux/i2c.h>
0022 #include <linux/io.h>
0023 #include <linux/serial_8250.h>
0024 
0025 #include <linux/mtd/mtd.h>
0026 #include <linux/mtd/rawnand.h>
0027 #include <linux/mtd/nand-ecc-sw-hamming.h>
0028 #include <linux/mtd/partitions.h>
0029 
0030 #include <linux/platform_data/asoc-s3c24xx_simtec.h>
0031 #include <linux/platform_data/hwmon-s3c.h>
0032 #include <linux/platform_data/i2c-s3c2410.h>
0033 #include <linux/platform_data/mtd-nand-s3c2410.h>
0034 
0035 #include <net/ax88796.h>
0036 
0037 #include <asm/irq.h>
0038 #include <asm/mach/arch.h>
0039 #include <asm/mach/map.h>
0040 #include <asm/mach/irq.h>
0041 #include <asm/mach-types.h>
0042 
0043 #include <linux/platform_data/fb-s3c2410.h>
0044 #include "regs-gpio.h"
0045 #include "gpio-samsung.h"
0046 
0047 #include "cpu.h"
0048 #include <linux/soc/samsung/s3c-cpu-freq.h>
0049 #include "devs.h"
0050 #include "gpio-cfg.h"
0051 
0052 #include "bast.h"
0053 #include "s3c24xx.h"
0054 #include "simtec.h"
0055 
0056 #define COPYRIGHT ", Copyright 2004-2008 Simtec Electronics"
0057 
0058 /* macros for virtual address mods for the io space entries */
0059 #define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5)
0060 #define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4)
0061 #define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3)
0062 #define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2)
0063 
0064 /* macros to modify the physical addresses for io space */
0065 
0066 #define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
0067 #define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
0068 #define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
0069 #define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
0070 
0071 static struct map_desc bast_iodesc[] __initdata = {
0072   /* ISA IO areas */
0073   {
0074       .virtual  = (u32)S3C24XX_VA_ISA_BYTE,
0075       .pfn      = PA_CS2(BAST_PA_ISAIO),
0076       .length   = SZ_16M,
0077       .type     = MT_DEVICE,
0078   },
0079   /* bast CPLD control registers, and external interrupt controls */
0080   {
0081       .virtual  = (u32)BAST_VA_CTRL1,
0082       .pfn      = __phys_to_pfn(BAST_PA_CTRL1),
0083       .length   = SZ_1M,
0084       .type     = MT_DEVICE,
0085   }, {
0086       .virtual  = (u32)BAST_VA_CTRL2,
0087       .pfn      = __phys_to_pfn(BAST_PA_CTRL2),
0088       .length   = SZ_1M,
0089       .type     = MT_DEVICE,
0090   }, {
0091       .virtual  = (u32)BAST_VA_CTRL3,
0092       .pfn      = __phys_to_pfn(BAST_PA_CTRL3),
0093       .length   = SZ_1M,
0094       .type     = MT_DEVICE,
0095   }, {
0096       .virtual  = (u32)BAST_VA_CTRL4,
0097       .pfn      = __phys_to_pfn(BAST_PA_CTRL4),
0098       .length   = SZ_1M,
0099       .type     = MT_DEVICE,
0100   },
0101   /* PC104 IRQ mux */
0102   {
0103       .virtual  = (u32)BAST_VA_PC104_IRQREQ,
0104       .pfn      = __phys_to_pfn(BAST_PA_PC104_IRQREQ),
0105       .length   = SZ_1M,
0106       .type     = MT_DEVICE,
0107   }, {
0108       .virtual  = (u32)BAST_VA_PC104_IRQRAW,
0109       .pfn      = __phys_to_pfn(BAST_PA_PC104_IRQRAW),
0110       .length   = SZ_1M,
0111       .type     = MT_DEVICE,
0112   }, {
0113       .virtual  = (u32)BAST_VA_PC104_IRQMASK,
0114       .pfn      = __phys_to_pfn(BAST_PA_PC104_IRQMASK),
0115       .length   = SZ_1M,
0116       .type     = MT_DEVICE,
0117   },
0118 
0119   /* peripheral space... one for each of fast/slow/byte/16bit */
0120   /* note, ide is only decoded in word space, even though some registers
0121    * are only 8bit */
0122 
0123   /* slow, byte */
0124   { VA_C2(BAST_VA_ISAIO),   PA_CS2(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
0125   { VA_C2(BAST_VA_ISAMEM),  PA_CS2(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
0126   { VA_C2(BAST_VA_SUPERIO), PA_CS2(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
0127 
0128   /* slow, word */
0129   { VA_C3(BAST_VA_ISAIO),   PA_CS3(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
0130   { VA_C3(BAST_VA_ISAMEM),  PA_CS3(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
0131   { VA_C3(BAST_VA_SUPERIO), PA_CS3(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
0132 
0133   /* fast, byte */
0134   { VA_C4(BAST_VA_ISAIO),   PA_CS4(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
0135   { VA_C4(BAST_VA_ISAMEM),  PA_CS4(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
0136   { VA_C4(BAST_VA_SUPERIO), PA_CS4(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
0137 
0138   /* fast, word */
0139   { VA_C5(BAST_VA_ISAIO),   PA_CS5(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
0140   { VA_C5(BAST_VA_ISAMEM),  PA_CS5(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
0141   { VA_C5(BAST_VA_SUPERIO), PA_CS5(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
0142 };
0143 
0144 #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
0145 #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
0146 #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
0147 
0148 static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
0149     [0] = {
0150         .hwport      = 0,
0151         .flags       = 0,
0152         .ucon        = UCON,
0153         .ulcon       = ULCON,
0154         .ufcon       = UFCON,
0155     },
0156     [1] = {
0157         .hwport      = 1,
0158         .flags       = 0,
0159         .ucon        = UCON,
0160         .ulcon       = ULCON,
0161         .ufcon       = UFCON,
0162     },
0163     /* port 2 is not actually used */
0164     [2] = {
0165         .hwport      = 2,
0166         .flags       = 0,
0167         .ucon        = UCON,
0168         .ulcon       = ULCON,
0169         .ufcon       = UFCON,
0170     }
0171 };
0172 
0173 /* NAND Flash on BAST board */
0174 
0175 #ifdef CONFIG_PM
0176 static int bast_pm_suspend(void)
0177 {
0178     /* ensure that an nRESET is not generated on resume. */
0179     gpio_direction_output(S3C2410_GPA(21), 1);
0180     return 0;
0181 }
0182 
0183 static void bast_pm_resume(void)
0184 {
0185     s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
0186 }
0187 
0188 #else
0189 #define bast_pm_suspend NULL
0190 #define bast_pm_resume NULL
0191 #endif
0192 
0193 static struct syscore_ops bast_pm_syscore_ops = {
0194     .suspend    = bast_pm_suspend,
0195     .resume     = bast_pm_resume,
0196 };
0197 
0198 static int smartmedia_map[] = { 0 };
0199 static int chip0_map[] = { 1 };
0200 static int chip1_map[] = { 2 };
0201 static int chip2_map[] = { 3 };
0202 
0203 static struct mtd_partition __initdata bast_default_nand_part[] = {
0204     [0] = {
0205         .name   = "Boot Agent",
0206         .size   = SZ_16K,
0207         .offset = 0,
0208     },
0209     [1] = {
0210         .name   = "/boot",
0211         .size   = SZ_4M - SZ_16K,
0212         .offset = SZ_16K,
0213     },
0214     [2] = {
0215         .name   = "user",
0216         .offset = SZ_4M,
0217         .size   = MTDPART_SIZ_FULL,
0218     }
0219 };
0220 
0221 /* the bast has 4 selectable slots for nand-flash, the three
0222  * on-board chip areas, as well as the external SmartMedia
0223  * slot.
0224  *
0225  * Note, there is no current hot-plug support for the SmartMedia
0226  * socket.
0227 */
0228 
0229 static struct s3c2410_nand_set __initdata bast_nand_sets[] = {
0230     [0] = {
0231         .name       = "SmartMedia",
0232         .nr_chips   = 1,
0233         .nr_map     = smartmedia_map,
0234         .options        = NAND_SCAN_SILENT_NODEV,
0235         .nr_partitions  = ARRAY_SIZE(bast_default_nand_part),
0236         .partitions = bast_default_nand_part,
0237     },
0238     [1] = {
0239         .name       = "chip0",
0240         .nr_chips   = 1,
0241         .nr_map     = chip0_map,
0242         .nr_partitions  = ARRAY_SIZE(bast_default_nand_part),
0243         .partitions = bast_default_nand_part,
0244     },
0245     [2] = {
0246         .name       = "chip1",
0247         .nr_chips   = 1,
0248         .nr_map     = chip1_map,
0249         .options        = NAND_SCAN_SILENT_NODEV,
0250         .nr_partitions  = ARRAY_SIZE(bast_default_nand_part),
0251         .partitions = bast_default_nand_part,
0252     },
0253     [3] = {
0254         .name       = "chip2",
0255         .nr_chips   = 1,
0256         .nr_map     = chip2_map,
0257         .options        = NAND_SCAN_SILENT_NODEV,
0258         .nr_partitions  = ARRAY_SIZE(bast_default_nand_part),
0259         .partitions = bast_default_nand_part,
0260     }
0261 };
0262 
0263 static void bast_nand_select(struct s3c2410_nand_set *set, int slot)
0264 {
0265     unsigned int tmp;
0266 
0267     slot = set->nr_map[slot] & 3;
0268 
0269     pr_debug("bast_nand: selecting slot %d (set %p,%p)\n",
0270          slot, set, set->nr_map);
0271 
0272     tmp = __raw_readb(BAST_VA_CTRL2);
0273     tmp &= BAST_CPLD_CTLR2_IDERST;
0274     tmp |= slot;
0275     tmp |= BAST_CPLD_CTRL2_WNAND;
0276 
0277     pr_debug("bast_nand: ctrl2 now %02x\n", tmp);
0278 
0279     __raw_writeb(tmp, BAST_VA_CTRL2);
0280 }
0281 
0282 static struct s3c2410_platform_nand __initdata bast_nand_info = {
0283     .tacls      = 30,
0284     .twrph0     = 60,
0285     .twrph1     = 60,
0286     .nr_sets    = ARRAY_SIZE(bast_nand_sets),
0287     .sets       = bast_nand_sets,
0288     .select_chip    = bast_nand_select,
0289     .engine_type    = NAND_ECC_ENGINE_TYPE_SOFT,
0290 };
0291 
0292 /* DM9000 */
0293 
0294 static struct resource bast_dm9k_resource[] = {
0295     [0] = DEFINE_RES_MEM(S3C2410_CS5 + BAST_PA_DM9000, 4),
0296     [1] = DEFINE_RES_MEM(S3C2410_CS5 + BAST_PA_DM9000 + 0x40, 0x40),
0297     [2] = DEFINE_RES_NAMED(BAST_IRQ_DM9000 , 1, NULL, IORESOURCE_IRQ \
0298                     | IORESOURCE_IRQ_HIGHLEVEL),
0299 };
0300 
0301 /* for the moment we limit ourselves to 16bit IO until some
0302  * better IO routines can be written and tested
0303 */
0304 
0305 static struct dm9000_plat_data bast_dm9k_platdata = {
0306     .flags      = DM9000_PLATF_16BITONLY,
0307 };
0308 
0309 static struct platform_device bast_device_dm9k = {
0310     .name       = "dm9000",
0311     .id     = 0,
0312     .num_resources  = ARRAY_SIZE(bast_dm9k_resource),
0313     .resource   = bast_dm9k_resource,
0314     .dev        = {
0315         .platform_data = &bast_dm9k_platdata,
0316     }
0317 };
0318 
0319 /* serial devices */
0320 
0321 #define SERIAL_BASE  (S3C2410_CS2 + BAST_PA_SUPERIO)
0322 #define SERIAL_FLAGS (UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SHARE_IRQ)
0323 #define SERIAL_CLK   (1843200)
0324 
0325 static struct plat_serial8250_port bast_sio_data[] = {
0326     [0] = {
0327         .mapbase    = SERIAL_BASE + 0x2f8,
0328         .irq        = BAST_IRQ_PCSERIAL1,
0329         .flags      = SERIAL_FLAGS,
0330         .iotype     = UPIO_MEM,
0331         .regshift   = 0,
0332         .uartclk    = SERIAL_CLK,
0333     },
0334     [1] = {
0335         .mapbase    = SERIAL_BASE + 0x3f8,
0336         .irq        = BAST_IRQ_PCSERIAL2,
0337         .flags      = SERIAL_FLAGS,
0338         .iotype     = UPIO_MEM,
0339         .regshift   = 0,
0340         .uartclk    = SERIAL_CLK,
0341     },
0342     { }
0343 };
0344 
0345 static struct platform_device bast_sio = {
0346     .name           = "serial8250",
0347     .id         = PLAT8250_DEV_PLATFORM,
0348     .dev            = {
0349         .platform_data  = &bast_sio_data,
0350     },
0351 };
0352 
0353 /* we have devices on the bus which cannot work much over the
0354  * standard 100KHz i2c bus frequency
0355 */
0356 
0357 static struct s3c2410_platform_i2c __initdata bast_i2c_info = {
0358     .flags      = 0,
0359     .slave_addr = 0x10,
0360     .frequency  = 100*1000,
0361 };
0362 
0363 /* Asix AX88796 10/100 ethernet controller */
0364 
0365 static struct ax_plat_data bast_asix_platdata = {
0366     .flags      = AXFLG_MAC_FROMDEV,
0367     .wordlength = 2,
0368     .dcr_val    = 0x48,
0369     .rcr_val    = 0x40,
0370 };
0371 
0372 static struct resource bast_asix_resource[] = {
0373     [0] = DEFINE_RES_MEM(S3C2410_CS5 + BAST_PA_ASIXNET, 0x18 * 0x20),
0374     [1] = DEFINE_RES_MEM(S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20), 1),
0375     [2] = DEFINE_RES_IRQ(BAST_IRQ_ASIX),
0376 };
0377 
0378 static struct platform_device bast_device_asix = {
0379     .name       = "ax88796",
0380     .id     = 0,
0381     .num_resources  = ARRAY_SIZE(bast_asix_resource),
0382     .resource   = bast_asix_resource,
0383     .dev        = {
0384         .platform_data = &bast_asix_platdata
0385     }
0386 };
0387 
0388 /* Asix AX88796 10/100 ethernet controller parallel port */
0389 
0390 static struct resource bast_asixpp_resource[] = {
0391     [0] = DEFINE_RES_MEM(S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20), \
0392                     0x30 * 0x20),
0393 };
0394 
0395 static struct platform_device bast_device_axpp = {
0396     .name       = "ax88796-pp",
0397     .id     = 0,
0398     .num_resources  = ARRAY_SIZE(bast_asixpp_resource),
0399     .resource   = bast_asixpp_resource,
0400 };
0401 
0402 /* LCD/VGA controller */
0403 
0404 static struct s3c2410fb_display __initdata bast_lcd_info[] = {
0405     {
0406         .type       = S3C2410_LCDCON1_TFT,
0407         .width      = 640,
0408         .height     = 480,
0409 
0410         .pixclock   = 33333,
0411         .xres       = 640,
0412         .yres       = 480,
0413         .bpp        = 4,
0414         .left_margin    = 40,
0415         .right_margin   = 20,
0416         .hsync_len  = 88,
0417         .upper_margin   = 30,
0418         .lower_margin   = 32,
0419         .vsync_len  = 3,
0420 
0421         .lcdcon5    = 0x00014b02,
0422     },
0423     {
0424         .type       = S3C2410_LCDCON1_TFT,
0425         .width      = 640,
0426         .height     = 480,
0427 
0428         .pixclock   = 33333,
0429         .xres       = 640,
0430         .yres       = 480,
0431         .bpp        = 8,
0432         .left_margin    = 40,
0433         .right_margin   = 20,
0434         .hsync_len  = 88,
0435         .upper_margin   = 30,
0436         .lower_margin   = 32,
0437         .vsync_len  = 3,
0438 
0439         .lcdcon5    = 0x00014b02,
0440     },
0441     {
0442         .type       = S3C2410_LCDCON1_TFT,
0443         .width      = 640,
0444         .height     = 480,
0445 
0446         .pixclock   = 33333,
0447         .xres       = 640,
0448         .yres       = 480,
0449         .bpp        = 16,
0450         .left_margin    = 40,
0451         .right_margin   = 20,
0452         .hsync_len  = 88,
0453         .upper_margin   = 30,
0454         .lower_margin   = 32,
0455         .vsync_len  = 3,
0456 
0457         .lcdcon5    = 0x00014b02,
0458     },
0459 };
0460 
0461 /* LCD/VGA controller */
0462 
0463 static struct s3c2410fb_mach_info __initdata bast_fb_info = {
0464 
0465     .displays = bast_lcd_info,
0466     .num_displays = ARRAY_SIZE(bast_lcd_info),
0467     .default_display = 1,
0468 };
0469 
0470 /* I2C devices fitted. */
0471 
0472 static struct i2c_board_info bast_i2c_devs[] __initdata = {
0473     {
0474         I2C_BOARD_INFO("tlv320aic23", 0x1a),
0475     }, {
0476         I2C_BOARD_INFO("simtec-pmu", 0x6b),
0477     }, {
0478         I2C_BOARD_INFO("ch7013", 0x75),
0479     },
0480 };
0481 
0482 static struct s3c_hwmon_pdata bast_hwmon_info = {
0483     /* LCD contrast (0-6.6V) */
0484     .in[0] = &(struct s3c_hwmon_chcfg) {
0485         .name       = "lcd-contrast",
0486         .mult       = 3300,
0487         .div        = 512,
0488     },
0489     /* LED current feedback */
0490     .in[1] = &(struct s3c_hwmon_chcfg) {
0491         .name       = "led-feedback",
0492         .mult       = 3300,
0493         .div        = 1024,
0494     },
0495     /* LCD feedback (0-6.6V) */
0496     .in[2] = &(struct s3c_hwmon_chcfg) {
0497         .name       = "lcd-feedback",
0498         .mult       = 3300,
0499         .div        = 512,
0500     },
0501     /* Vcore (1.8-2.0V), Vref 3.3V  */
0502     .in[3] = &(struct s3c_hwmon_chcfg) {
0503         .name       = "vcore",
0504         .mult       = 3300,
0505         .div        = 1024,
0506     },
0507 };
0508 
0509 /* Standard BAST devices */
0510 // cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0
0511 
0512 static struct platform_device *bast_devices[] __initdata = {
0513     &s3c2410_device_dclk,
0514     &s3c_device_ohci,
0515     &s3c_device_lcd,
0516     &s3c_device_wdt,
0517     &s3c_device_i2c0,
0518     &s3c_device_rtc,
0519     &s3c_device_nand,
0520     &s3c_device_adc,
0521     &s3c_device_hwmon,
0522     &bast_device_dm9k,
0523     &bast_device_asix,
0524     &bast_device_axpp,
0525     &bast_sio,
0526 };
0527 
0528 static struct s3c_cpufreq_board __initdata bast_cpufreq = {
0529     .refresh    = 7800, /* 7.8usec */
0530     .auto_io    = 1,
0531     .need_io    = 1,
0532 };
0533 
0534 static struct s3c24xx_audio_simtec_pdata __initdata bast_audio = {
0535     .have_mic   = 1,
0536     .have_lout  = 1,
0537 };
0538 
0539 static void __init bast_map_io(void)
0540 {
0541     s3c_hwmon_set_platdata(&bast_hwmon_info);
0542 
0543     s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
0544     s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
0545     s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4);
0546 }
0547 
0548 static void __init bast_init_time(void)
0549 {
0550     s3c2410_init_clocks(12000000);
0551     s3c24xx_timer_init();
0552 }
0553 
0554 static void __init bast_init(void)
0555 {
0556     register_syscore_ops(&bast_pm_syscore_ops);
0557 
0558     s3c_i2c0_set_platdata(&bast_i2c_info);
0559     s3c_nand_set_platdata(&bast_nand_info);
0560     s3c24xx_fb_set_platdata(&bast_fb_info);
0561     platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices));
0562 
0563     i2c_register_board_info(0, bast_i2c_devs,
0564                 ARRAY_SIZE(bast_i2c_devs));
0565 
0566     usb_simtec_init();
0567     nor_simtec_init();
0568     simtec_audio_add(NULL, true, &bast_audio);
0569 
0570     WARN_ON(gpio_request(S3C2410_GPA(21), "bast nreset"));
0571     
0572     s3c_cpufreq_setboard(&bast_cpufreq);
0573 }
0574 
0575 MACHINE_START(BAST, "Simtec-BAST")
0576     /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
0577     .atag_offset    = 0x100,
0578     .nr_irqs    = NR_IRQS_S3C2410,
0579     .map_io     = bast_map_io,
0580     .init_irq   = s3c2410_init_irq,
0581     .init_machine   = bast_init,
0582     .init_time  = bast_init_time,
0583 MACHINE_END