Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Copyright 2008 Openmoko, Inc.
0004 // Copyright 2008 Simtec Electronics
0005 //  Ben Dooks <ben@simtec.co.uk>
0006 //  http://armlinux.simtec.co.uk/
0007 // Copyright 2009 Kwangwoo Lee
0008 //  Kwangwoo Lee <kwangwoo.lee@gmail.com>
0009 
0010 #include <linux/kernel.h>
0011 #include <linux/types.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/list.h>
0014 #include <linux/timer.h>
0015 #include <linux/init.h>
0016 #include <linux/serial_core.h>
0017 #include <linux/serial_s3c.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/io.h>
0020 #include <linux/i2c.h>
0021 #include <linux/fb.h>
0022 #include <linux/gpio.h>
0023 #include <linux/delay.h>
0024 #include <linux/dm9000.h>
0025 
0026 #include <video/platform_lcd.h>
0027 #include <video/samsung_fimd.h>
0028 
0029 #include <asm/mach/arch.h>
0030 #include <asm/mach/map.h>
0031 #include <asm/mach/irq.h>
0032 
0033 #include "map.h"
0034 
0035 #include <asm/irq.h>
0036 #include <asm/mach-types.h>
0037 
0038 #include <linux/platform_data/i2c-s3c2410.h>
0039 #include "fb.h"
0040 
0041 #include "devs.h"
0042 #include "cpu.h"
0043 #include "irqs.h"
0044 #include "regs-gpio.h"
0045 #include "gpio-samsung.h"
0046 
0047 #include "s3c64xx.h"
0048 #include "regs-modem-s3c64xx.h"
0049 
0050 /* DM9000 */
0051 #define ANW6410_PA_DM9000   (0x18000000)
0052 
0053 /* A hardware buffer to control external devices is mapped at 0x30000000.
0054  * It can not be read. So current status must be kept in anw6410_extdev_status.
0055  */
0056 #define ANW6410_VA_EXTDEV   S3C_ADDR(0x02000000)
0057 #define ANW6410_PA_EXTDEV   (0x30000000)
0058 
0059 #define ANW6410_EN_DM9000   (1<<11)
0060 #define ANW6410_EN_LCD      (1<<14)
0061 
0062 static __u32 anw6410_extdev_status;
0063 
0064 static struct s3c2410_uartcfg anw6410_uartcfgs[] __initdata = {
0065     [0] = {
0066         .hwport      = 0,
0067         .flags       = 0,
0068         .ucon        = 0x3c5,
0069         .ulcon       = 0x03,
0070         .ufcon       = 0x51,
0071     },
0072     [1] = {
0073         .hwport      = 1,
0074         .flags       = 0,
0075         .ucon        = 0x3c5,
0076         .ulcon       = 0x03,
0077         .ufcon       = 0x51,
0078     },
0079 };
0080 
0081 /* framebuffer and LCD setup. */
0082 static void __init anw6410_lcd_mode_set(void)
0083 {
0084     u32 tmp;
0085 
0086     /* set the LCD type */
0087     tmp = __raw_readl(S3C64XX_SPCON);
0088     tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
0089     tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
0090     __raw_writel(tmp, S3C64XX_SPCON);
0091 
0092     /* remove the LCD bypass */
0093     tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
0094     tmp &= ~MIFPCON_LCD_BYPASS;
0095     __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
0096 }
0097 
0098 /* GPF1 = LCD panel power
0099  * GPF4 = LCD backlight control
0100  */
0101 static void anw6410_lcd_power_set(struct plat_lcd_data *pd,
0102                    unsigned int power)
0103 {
0104     if (power) {
0105         anw6410_extdev_status |= (ANW6410_EN_LCD << 16);
0106         __raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
0107 
0108         gpio_direction_output(S3C64XX_GPF(1), 1);
0109         gpio_direction_output(S3C64XX_GPF(4), 1);
0110     } else {
0111         anw6410_extdev_status &= ~(ANW6410_EN_LCD << 16);
0112         __raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
0113 
0114         gpio_direction_output(S3C64XX_GPF(1), 0);
0115         gpio_direction_output(S3C64XX_GPF(4), 0);
0116     }
0117 }
0118 
0119 static struct plat_lcd_data anw6410_lcd_power_data = {
0120     .set_power  = anw6410_lcd_power_set,
0121 };
0122 
0123 static struct platform_device anw6410_lcd_powerdev = {
0124     .name           = "platform-lcd",
0125     .dev.parent     = &s3c_device_fb.dev,
0126     .dev.platform_data  = &anw6410_lcd_power_data,
0127 };
0128 
0129 static struct s3c_fb_pd_win anw6410_fb_win0 = {
0130     .max_bpp    = 32,
0131     .default_bpp    = 16,
0132     .xres       = 800,
0133     .yres       = 480,
0134 };
0135 
0136 static struct fb_videomode anw6410_lcd_timing = {
0137     .left_margin    = 8,
0138     .right_margin   = 13,
0139     .upper_margin   = 7,
0140     .lower_margin   = 5,
0141     .hsync_len  = 3,
0142     .vsync_len  = 1,
0143     .xres       = 800,
0144     .yres       = 480,
0145 };
0146 
0147 /* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
0148 static struct s3c_fb_platdata anw6410_lcd_pdata __initdata = {
0149     .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
0150     .vtiming    = &anw6410_lcd_timing,
0151     .win[0]     = &anw6410_fb_win0,
0152     .vidcon0    = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
0153     .vidcon1    = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
0154 };
0155 
0156 /* DM9000AEP 10/100 ethernet controller */
0157 static void __init anw6410_dm9000_enable(void)
0158 {
0159     anw6410_extdev_status |= (ANW6410_EN_DM9000 << 16);
0160     __raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
0161 }
0162 
0163 static struct resource anw6410_dm9000_resource[] = {
0164     [0] = DEFINE_RES_MEM(ANW6410_PA_DM9000, 4),
0165     [1] = DEFINE_RES_MEM(ANW6410_PA_DM9000 + 4, 501),
0166     [2] = DEFINE_RES_NAMED(IRQ_EINT(15), 1, NULL, IORESOURCE_IRQ \
0167                     | IRQF_TRIGGER_HIGH),
0168 };
0169 
0170 static struct dm9000_plat_data anw6410_dm9000_pdata = {
0171     .flags    = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
0172     /* dev_addr can be set to provide hwaddr. */
0173 };
0174 
0175 static struct platform_device anw6410_device_eth = {
0176     .name   = "dm9000",
0177     .id = -1,
0178     .num_resources  = ARRAY_SIZE(anw6410_dm9000_resource),
0179     .resource   = anw6410_dm9000_resource,
0180     .dev    = {
0181         .platform_data  = &anw6410_dm9000_pdata,
0182     },
0183 };
0184 
0185 static struct map_desc anw6410_iodesc[] __initdata = {
0186     {
0187         .virtual    = (unsigned long)ANW6410_VA_EXTDEV,
0188         .pfn        = __phys_to_pfn(ANW6410_PA_EXTDEV),
0189         .length     = SZ_64K,
0190         .type       = MT_DEVICE,
0191     },
0192 };
0193 
0194 static struct platform_device *anw6410_devices[] __initdata = {
0195     &s3c_device_fb,
0196     &anw6410_lcd_powerdev,
0197     &anw6410_device_eth,
0198 };
0199 
0200 static void __init anw6410_map_io(void)
0201 {
0202     s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc));
0203     s3c64xx_set_xtal_freq(12000000);
0204     s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs));
0205     s3c64xx_set_timer_source(S3C64XX_PWM3, S3C64XX_PWM4);
0206 
0207     anw6410_lcd_mode_set();
0208 }
0209 
0210 static void __init anw6410_machine_init(void)
0211 {
0212     s3c_fb_set_platdata(&anw6410_lcd_pdata);
0213 
0214     gpio_request(S3C64XX_GPF(1), "panel power");
0215     gpio_request(S3C64XX_GPF(4), "LCD backlight");
0216 
0217     anw6410_dm9000_enable();
0218 
0219     platform_add_devices(anw6410_devices, ARRAY_SIZE(anw6410_devices));
0220 }
0221 
0222 MACHINE_START(ANW6410, "A&W6410")
0223     /* Maintainer: Kwangwoo Lee <kwangwoo.lee@gmail.com> */
0224     .atag_offset    = 0x100,
0225     .nr_irqs    = S3C64XX_NR_IRQS,
0226     .init_irq   = s3c6410_init_irq,
0227     .map_io     = anw6410_map_io,
0228     .init_machine   = anw6410_machine_init,
0229     .init_time  = s3c64xx_timer_init,
0230 MACHINE_END