
This patch adds generic support for the Samsung s3c2440 processor. Started from patch posted 2009-06-19 by Kevin Morfitt. Then modified for changes in the code that have occurred since.
Signed-off-by: Craig Nauman <cnauman <at> diagraph.com> ---
diff --git a/arch/arm/include/asm/arch-s3c24x0/s3c24x0.h b/arch/arm/include/asm/arch-s3c24x0/s3c24x0.h index 15f53dd..d4abd24 100644 --- a/arch/arm/include/asm/arch-s3c24x0/s3c24x0.h +++ b/arch/arm/include/asm/arch-s3c24x0/s3c24x0.h @@ -82,6 +82,10 @@ struct s3c24x0_interrupt { u32 SUBSRCPND; u32 INTSUBMSK; #endif +#ifdef CONFIG_S3C2440 + u32 SUBSRCPND; + u32 INTSUBMSK; +#endif };
@@ -91,10 +95,16 @@ struct s3c24x0_dma { #ifdef CONFIG_S3C2410 u32 DISRCC; #endif +#ifdef CONFIG_S3C2440 + u32 DISRCC; +#endif u32 DIDST; #ifdef CONFIG_S3C2410 u32 DIDSTC; #endif +#ifdef CONFIG_S3C2440 + u32 DIDSTC; +#endif u32 DCON; u32 DSTAT; u32 DCSRC; @@ -106,6 +116,9 @@ struct s3c24x0_dma { #ifdef CONFIG_S3C2410 u32 res[7]; #endif +#ifdef CONFIG_S3C2440 + u32 res[7]; +#endif };
struct s3c24x0_dmas { @@ -122,6 +135,9 @@ struct s3c24x0_clock_power { u32 CLKCON; u32 CLKSLOW; u32 CLKDIVN; +#if defined(CONFIG_S3C2440) + u32 CAMDIVN; +#endif };
@@ -147,9 +163,16 @@ struct s3c24x0_lcd { u32 LCDINTMSK; u32 LPCSEL; #endif +#ifdef CONFIG_S3C2440 + u32 LCDINTPND; + u32 LCDSRCPND; + u32 LCDINTMSK; + u32 LPCSEL; +#endif };
+#ifdef CONFIG_S3C2410 /* NAND FLASH (see S3C2410 manual chapter 6) */ struct s3c2410_nand { u32 NFCONF; @@ -159,6 +182,23 @@ struct s3c2410_nand { u32 NFSTAT; u32 NFECC; }; +#endif +#ifdef CONFIG_S3C2440 +/* NAND FLASH (see S3C2440 manual chapter 6) */ +struct s3c2440_nand { + u32 NFCONF; + u32 NFCONT; + u32 NFCMD; + u32 NFADDR; + u32 NFDATA; + u32 NFECCD0; + u32 NFECCD1; + u32 NFECCD; + u32 NFSTAT; + u32 NFSTAT0; + u32 NFSTAT1; +}; +#endif
/* UART (see manual chapter 11) */ @@ -447,6 +487,65 @@ struct s3c24x0_gpio { u32 GSTATUS3; u32 GSTATUS4; #endif +#if defined(CONFIG_S3C2440) + u32 GPACON; + u32 GPADAT; + u32 res1[2]; + u32 GPBCON; + u32 GPBDAT; + u32 GPBUP; + u32 res2; + u32 GPCCON; + u32 GPCDAT; + u32 GPCUP; + u32 res3; + u32 GPDCON; + u32 GPDDAT; + u32 GPDUP; + u32 res4; + u32 GPECON; + u32 GPEDAT; + u32 GPEUP; + u32 res5; + u32 GPFCON; + u32 GPFDAT; + u32 GPFUP; + u32 res6; + u32 GPGCON; + u32 GPGDAT; + u32 GPGUP; + u32 res7; + u32 GPHCON; + u32 GPHDAT; + u32 GPHUP; + u32 res8; + + u32 MISCCR; + u32 DCLKCON; + u32 EXTINT0; + u32 EXTINT1; + u32 EXTINT2; + u32 EINTFLT0; + u32 EINTFLT1; + u32 EINTFLT2; + u32 EINTFLT3; + u32 EINTMASK; + u32 EINTPEND; + u32 GSTATUS0; + u32 GSTATUS1; + u32 GSTATUS2; + u32 GSTATUS3; + u32 GSTATUS4; + + u32 res9; + u32 DSC0; + u32 DSC1; + u32 MSLCON; + u32 GPJCON; + u32 GPJDAT; + u32 GPJUP; + u32 res10; +#endif };
diff --git a/arch/arm/include/asm/arch-s3c24x0/s3c24x0_cpu.h b/arch/arm/include/asm/arch-s3c24x0/s3c24x0_cpu.h index c37d4a1..54184c4 100644 --- a/arch/arm/include/asm/arch-s3c24x0/s3c24x0_cpu.h +++ b/arch/arm/include/asm/arch-s3c24x0/s3c24x0_cpu.h @@ -22,6 +22,8 @@ #include <asm/arch/s3c2400.h> #elif defined CONFIG_S3C2410 #include <asm/arch/s3c2410.h> +#elif defined CONFIG_S3C2440 + #include <asm/arch/s3c2440.h> #else #error Please define the s3c24x0 cpu type #endif diff --git a/arch/arm/include/asm/arch-s3c24x0/s3c2440.h b/arch/arm/include/asm/arch-s3c24x0/s3c2440.h new file mode 100644 index 0000000..7e4518e --- /dev/null +++ b/arch/arm/include/asm/arch-s3c24x0/s3c2440.h @@ -0,0 +1,163 @@ +/* + * (C) Copyright 2003 + * David Müller ELSOFT AG Switzerland. d.mueller@elsoft.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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; either version 2 of + * the License, or (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/************************************************ + * NAME : s3c2440.h + * Version : 31.3.2003 + * + * Based on S3C2440 User's manual Rev x.x + ************************************************/ + +#ifndef __S3C2440_H__ +#define __S3C2440_H__ + +#define S3C24X0_UART_CHANNELS 3 +#define S3C24X0_SPI_CHANNELS 2 + +/* S3C2440 only supports 512 Byte HW ECC */ +#define S3C2440_ECCSIZE 512 +#define S3C2440_ECCBYTES 3 + +enum s3c24x0_uarts_nr { + S3C24X0_UART0, + S3C24X0_UART1, + S3C24X0_UART2 +}; + +/* S3C2440 device base addresses */ +#define S3C24X0_MEMCTL_BASE 0x48000000 +#define S3C24X0_USB_HOST_BASE 0x49000000 +#define S3C24X0_INTERRUPT_BASE 0x4A000000 +#define S3C24X0_DMA_BASE 0x4B000000 +#define S3C24X0_CLOCK_POWER_BASE 0x4C000000 +#define S3C24X0_LCD_BASE 0x4D000000 +#define S3C2440_NAND_BASE 0x4E000000 +#define S3C24X0_UART_BASE 0x50000000 +#define S3C24X0_TIMER_BASE 0x51000000 +#define S3C24X0_USB_DEVICE_BASE 0x52000140 +#define S3C24X0_WATCHDOG_BASE 0x53000000 +#define S3C24X0_I2C_BASE 0x54000000 +#define S3C24X0_I2S_BASE 0x55000000 +#define S3C24X0_GPIO_BASE 0x56000000 +#define S3C24X0_RTC_BASE 0x57000000 +#define S3C2440_ADC_BASE 0x58000000 +#define S3C24X0_SPI_BASE 0x59000000 +#define S3C2440_SDI_BASE 0x5A000000 + + +/* include common stuff */ +#include <asm/arch/s3c24x0.h> + + +static inline struct s3c24x0_memctl *s3c24x0_get_base_memctl(void) +{ + return (struct s3c24x0_memctl *)S3C24X0_MEMCTL_BASE; +} + +static inline struct s3c24x0_usb_host *s3c24x0_get_base_usb_host(void) +{ + return (struct s3c24x0_usb_host *)S3C24X0_USB_HOST_BASE; +} + +static inline struct s3c24x0_interrupt *s3c24x0_get_base_interrupt(void) +{ + return (struct s3c24x0_interrupt *)S3C24X0_INTERRUPT_BASE; +} + +static inline struct s3c24x0_dmas *s3c24x0_get_base_dmas(void) +{ + return (struct s3c24x0_dmas *)S3C24X0_DMA_BASE; +} + +static inline struct s3c24x0_clock_power *s3c24x0_get_base_clock_power(void) +{ + return (struct s3c24x0_clock_power *)S3C24X0_CLOCK_POWER_BASE; +} + +static inline struct s3c24x0_lcd *s3c24x0_get_base_lcd(void) +{ + return (struct s3c24x0_lcd *)S3C24X0_LCD_BASE; +} + +static inline struct s3c2440_nand *s3c2440_get_base_nand(void) +{ + return (struct s3c2440_nand *)S3C2440_NAND_BASE; +} + +static inline struct s3c24x0_uart + *s3c24x0_get_base_uart(enum s3c24x0_uarts_nr n) +{ + return (struct s3c24x0_uart *)(S3C24X0_UART_BASE + (n * 0x4000)); +} + +static inline struct s3c24x0_timers *s3c24x0_get_base_timers(void) +{ + return (struct s3c24x0_timers *)S3C24X0_TIMER_BASE; +} + +static inline struct s3c24x0_usb_device *s3c24x0_get_base_usb_device(void) +{ + return (struct s3c24x0_usb_device *)S3C24X0_USB_DEVICE_BASE; +} + +static inline struct s3c24x0_watchdog *s3c24x0_get_base_watchdog(void) +{ + return (struct s3c24x0_watchdog *)S3C24X0_WATCHDOG_BASE; +} + +static inline struct s3c24x0_i2c *s3c24x0_get_base_i2c(void) +{ + return (struct s3c24x0_i2c *)S3C24X0_I2C_BASE; +} + +static inline struct s3c24x0_i2s *s3c24x0_get_base_i2s(void) +{ + return (struct s3c24x0_i2s *)S3C24X0_I2S_BASE; +} + +static inline struct s3c24x0_gpio *s3c24x0_get_base_gpio(void) +{ + return (struct s3c24x0_gpio *)S3C24X0_GPIO_BASE; +} + +static inline struct s3c24x0_rtc *s3c24x0_get_base_rtc(void) +{ + return (struct s3c24x0_rtc *)S3C24X0_RTC_BASE; +} + +static inline struct s3c2440_adc *s3c2440_get_base_adc(void) +{ + return (struct s3c2440_adc *)S3C2440_ADC_BASE; +} + +static inline struct s3c24x0_spi *s3c24x0_get_base_spi(void) +{ + return (struct s3c24x0_spi *)S3C24X0_SPI_BASE; +} + +static inline struct s3c2440_sdi *s3c2440_get_base_sdi(void) +{ + return (struct s3c2440_sdi *)S3C2440_SDI_BASE; +} + +#endif /*__S3C2440_H__*/ diff --git a/arch/arm/cpu/arm920t/s3c24x0/speed.c b/arch/arm/cpu/arm920t/s3c24x0/speed.c index b13283a..0d7136c 100644 --- a/arch/arm/cpu/arm920t/s3c24x0/speed.c +++ b/arch/arm/cpu/arm920t/s3c24x0/speed.c @@ -64,7 +64,18 @@ static ulong get_PLLCLK(int pllreg) p = ((r & 0x003F0) >> 4) + 2; s = r & 0x3;
+#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) return (CONFIG_SYS_CLK_FREQ * m) / (p << s); +#elif defined(CONFIG_S3C2440) + /* To avoid integer overflow, changed the calc order */ + if (pllreg == MPLL) + return ( 2 * m * (CONFIG_SYS_CLK_FREQ / (p << s )) ); + else + return ( m * (CONFIG_SYS_CLK_FREQ / (p << s )) ); +#else +#error "get_PLLCLK not implemented for CPU type" +#endif + }
/* return FCLK frequency */ @@ -77,8 +88,23 @@ ulong get_FCLK(void) ulong get_HCLK(void) { struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); - +#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) return (readl(&clk_power->CLKDIVN) & 2) ? get_FCLK() / 2 : get_FCLK(); +#elif defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442) + switch (readl(&clk_power->CLKDIVN) & 0x6) { + case 0x0: + return get_FCLK(); + case 0x2: + return get_FCLK()/2; + case 0x4: + return (readl(&clk_power->CAMDIVN) & 0x200) ? get_FCLK()/8 : get_FCLK()/4; + case 0x6: + return (readl(&clk_power->CAMDIVN) & 0x100) ? get_FCLK()/6 : get_FCLK()/3; + } + return 0; +#else +#error "get_HCLK not implemented for CPU type" +#endif }
/* return PCLK frequency */