diff options
Diffstat (limited to 'arch/arm/mach-s3c64xx')
57 files changed, 1563 insertions, 2802 deletions
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index dd20c66cd70..26ca2427e53 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -3,16 +3,7 @@ # # Licensed under GPLv2 -# temporary until we can eliminate all drivers using it. -config PLAT_S3C64XX - bool - depends on ARCH_S3C64XX - select SAMSUNG_WAKEMASK - select PM_GENERIC_DOMAINS - default y - help - Base platform code for any Samsung S3C64XX device - +if ARCH_S3C64XX # Configuration options for the S3C6410 CPU @@ -26,13 +17,14 @@ config CPU_S3C6410 help Enable S3C6410 CPU support -config S3C64XX_DMA - bool "S3C64XX DMA" - select S3C_DMA +config S3C64XX_PL080 + def_bool DMADEVICES + select ARM_AMBA + select AMBA_PL08X config S3C64XX_SETUP_SDHCI - select S3C64XX_SETUP_SDHCI_GPIO bool + select S3C64XX_SETUP_SDHCI_GPIO help Internal configuration for default SDHCI setup for S3C6400 and S3C6410 SoCs. @@ -83,14 +75,18 @@ config S3C64XX_SETUP_SPI help Common setup code for SPI GPIO configurations +config S3C64XX_SETUP_USB_PHY + bool + help + Common setup code for USB PHY controller + # S36400 Macchine support config MACH_SMDK6400 bool "SMDK6400" select CPU_S3C6400 - select S3C_DEV_HSMMC - select S3C_DEV_NAND select S3C64XX_SETUP_SDHCI + select S3C_DEV_HSMMC1 help Machine support for the Samsung SMDK6400 @@ -99,21 +95,21 @@ config MACH_SMDK6400 config MACH_ANW6410 bool "A&W6410" select CPU_S3C6410 - select S3C_DEV_FB select S3C64XX_SETUP_FB_24BPP + select S3C_DEV_FB help Machine support for the A&W6410 config MACH_MINI6410 bool "MINI6410" select CPU_S3C6410 + select S3C64XX_SETUP_FB_24BPP + select S3C64XX_SETUP_SDHCI + select S3C_DEV_FB select S3C_DEV_HSMMC select S3C_DEV_HSMMC1 - select S3C64XX_SETUP_SDHCI - select S3C_DEV_USB_HOST select S3C_DEV_NAND - select S3C_DEV_FB - select S3C64XX_SETUP_FB_24BPP + select S3C_DEV_USB_HOST select SAMSUNG_DEV_ADC select SAMSUNG_DEV_TS help @@ -122,41 +118,42 @@ config MACH_MINI6410 config MACH_REAL6410 bool "REAL6410" select CPU_S3C6410 - select S3C_DEV_HSMMC - select S3C_DEV_HSMMC1 + select S3C64XX_SETUP_FB_24BPP select S3C64XX_SETUP_SDHCI select S3C_DEV_FB - select S3C64XX_SETUP_FB_24BPP + select S3C_DEV_HSMMC + select S3C_DEV_HSMMC1 select S3C_DEV_NAND + select S3C_DEV_USB_HOST select SAMSUNG_DEV_ADC select SAMSUNG_DEV_TS - select S3C_DEV_USB_HOST help Machine support for the CoreWind REAL6410 config MACH_SMDK6410 bool "SMDK6410" select CPU_S3C6410 - select SAMSUNG_DEV_ADC + select HAVE_S3C2410_WATCHDOG if WATCHDOG + select S3C64XX_SETUP_FB_24BPP + select S3C64XX_SETUP_I2C1 + select S3C64XX_SETUP_IDE + select S3C64XX_SETUP_KEYPAD + select S3C64XX_SETUP_SDHCI + select S3C64XX_SETUP_USB_PHY + select S3C_DEV_FB select S3C_DEV_HSMMC select S3C_DEV_HSMMC1 select S3C_DEV_I2C1 - select SAMSUNG_DEV_IDE - select S3C_DEV_FB select S3C_DEV_RTC - select SAMSUNG_DEV_TS select S3C_DEV_USB_HOST select S3C_DEV_USB_HSOTG select S3C_DEV_WDT + select SAMSUNG_DEV_ADC select SAMSUNG_DEV_BACKLIGHT + select SAMSUNG_DEV_IDE select SAMSUNG_DEV_KEYPAD select SAMSUNG_DEV_PWM - select HAVE_S3C2410_WATCHDOG if WATCHDOG - select S3C64XX_SETUP_SDHCI - select S3C64XX_SETUP_I2C1 - select S3C64XX_SETUP_IDE - select S3C64XX_SETUP_FB_24BPP - select S3C64XX_SETUP_KEYPAD + select SAMSUNG_DEV_TS help Machine support for the Samsung SMDK6410 @@ -192,53 +189,48 @@ endchoice config SMDK6410_WM1190_EV1 bool "Support Wolfson Microelectronics 1190-EV1 PMIC card" depends on MACH_SMDK6410 + select MFD_WM8350_I2C select REGULATOR select REGULATOR_WM8350 - select SAMSUNG_GPIO_EXTRA64 - select MFD_WM8350_I2C - select MFD_WM8350_CONFIG_MODE_0 - select MFD_WM8350_CONFIG_MODE_3 - select MFD_WM8352_CONFIG_MODE_0 help The Wolfson Microelectronics 1190-EV1 is a WM835x based PMIC and audio daughtercard for the Samsung SMDK6410 reference platform. Enabling this option will build support for this module into the kernel. The presence of the module will be - detected at runtime so the the resulting kernel can be used + detected at runtime so the resulting kernel can be used with or without the 1190-EV1 fitted. config SMDK6410_WM1192_EV1 bool "Support Wolfson Microelectronics 1192-EV1 PMIC card" depends on MACH_SMDK6410 - select REGULATOR - select REGULATOR_WM831X - select SAMSUNG_GPIO_EXTRA64 select MFD_WM831X select MFD_WM831X_I2C + select REGULATOR + select REGULATOR_WM831X help The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC daughtercard for the Samsung SMDK6410 reference platform. Enabling this option will build support for this module into the kernel. The presence of the daughtercard will be - detected at runtime so the the resulting kernel can be used + detected at runtime so the resulting kernel can be used with or without the 1192-EV1 fitted. config MACH_NCP bool "NCP" select CPU_S3C6410 - select S3C_DEV_I2C1 - select S3C_DEV_HSMMC1 select S3C64XX_SETUP_I2C1 + select S3C_DEV_HSMMC1 + select S3C_DEV_I2C1 help Machine support for the Samsung NCP config MACH_HMT bool "Airgoo HMT" select CPU_S3C6410 + select S3C64XX_SETUP_FB_24BPP select S3C_DEV_FB select S3C_DEV_NAND select S3C_DEV_USB_HOST - select S3C64XX_SETUP_FB_24BPP select SAMSUNG_DEV_PWM help Machine support for the Airgoo HMT @@ -246,16 +238,17 @@ config MACH_HMT config MACH_SMARTQ bool select CPU_S3C6410 + select S3C64XX_SETUP_FB_24BPP + select S3C64XX_SETUP_SDHCI + select S3C64XX_SETUP_USB_PHY + select S3C_DEV_FB select S3C_DEV_HSMMC select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC2 - select S3C_DEV_FB select S3C_DEV_HWMON select S3C_DEV_RTC - select S3C_DEV_USB_HSOTG select S3C_DEV_USB_HOST - select S3C64XX_SETUP_SDHCI - select S3C64XX_SETUP_FB_24BPP + select S3C_DEV_USB_HSOTG select SAMSUNG_DEV_ADC select SAMSUNG_DEV_PWM select SAMSUNG_DEV_TS @@ -277,24 +270,45 @@ config MACH_SMARTQ7 config MACH_WLF_CRAGG_6410 bool "Wolfson Cragganmore 6410" select CPU_S3C6410 - select S3C64XX_SETUP_SDHCI + select I2C + select LEDS_GPIO_REGISTER + select S3C64XX_DEV_SPI0 + select S3C64XX_SETUP_FB_24BPP select S3C64XX_SETUP_I2C1 select S3C64XX_SETUP_IDE - select S3C64XX_SETUP_FB_24BPP select S3C64XX_SETUP_KEYPAD + select S3C64XX_SETUP_SDHCI select S3C64XX_SETUP_SPI - select SAMSUNG_DEV_ADC - select SAMSUNG_DEV_KEYPAD - select S3C_DEV_USB_HOST - select S3C_DEV_USB_HSOTG + select S3C64XX_SETUP_USB_PHY + select S3C_DEV_FB select S3C_DEV_HSMMC select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC2 select S3C_DEV_I2C1 - select S3C_DEV_WDT select S3C_DEV_RTC - select S3C64XX_DEV_SPI0 - select SAMSUNG_GPIO_EXTRA128 - select I2C + select S3C_DEV_USB_HOST + select S3C_DEV_USB_HSOTG + select S3C_DEV_WDT + select SAMSUNG_DEV_ADC + select SAMSUNG_DEV_KEYPAD + select SAMSUNG_DEV_PWM help Machine support for the Wolfson Cragganmore S3C6410 variant. + +config MACH_S3C64XX_DT + bool "Samsung S3C6400/S3C6410 machine using Device Tree" + select CLKSRC_OF + select CPU_S3C6400 + select CPU_S3C6410 + select PINCTRL + select PINCTRL_S3C64XX + select USE_OF + help + Machine support for Samsung S3C6400/S3C6410 machines with Device Tree + enabled. + Select this if a fdt blob is available for your S3C64XX SoC based + board. + Note: This is under development and not all peripherals can be + supported with this machine file. + +endif diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index 1822ac2eba3..58069a702a4 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -12,7 +12,7 @@ obj- := # Core -obj-y += common.o clock.o +obj-y += common.o # Core support @@ -22,16 +22,16 @@ obj-$(CONFIG_CPU_S3C6410) += s3c6410.o # PM obj-$(CONFIG_PM) += pm.o irq-pm.o sleep.o +obj-$(CONFIG_CPU_IDLE) += cpuidle.o # DMA support -obj-$(CONFIG_S3C64XX_DMA) += dma.o +obj-$(CONFIG_S3C64XX_PL080) += pl080.o # Device support obj-y += dev-uart.o obj-y += dev-audio.o -obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o # Device setup @@ -42,6 +42,7 @@ obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi.o +obj-$(CONFIG_S3C64XX_SETUP_USB_PHY) += setup-usb-phy.o # Machine support @@ -56,3 +57,4 @@ obj-$(CONFIG_MACH_SMARTQ7) += mach-smartq7.o obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o mach-crag6410-module.o +obj-$(CONFIG_MACH_S3C64XX_DT) += mach-s3c64xx-dt.o diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c deleted file mode 100644 index aebbcc291b4..00000000000 --- a/arch/arm/mach-s3c64xx/clock.c +++ /dev/null @@ -1,897 +0,0 @@ -/* linux/arch/arm/plat-s3c64xx/clock.c - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C64XX Base clock support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/io.h> - -#include <mach/hardware.h> -#include <mach/map.h> - -#include <mach/regs-sys.h> -#include <mach/regs-clock.h> - -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/cpu-freq.h> -#include <plat/clock.h> -#include <plat/clock-clksrc.h> -#include <plat/pll.h> - -/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call - * ext_xtal_mux for want of an actual name from the manual. -*/ - -static struct clk clk_ext_xtal_mux = { - .name = "ext_xtal", -}; - -#define clk_fin_apll clk_ext_xtal_mux -#define clk_fin_mpll clk_ext_xtal_mux -#define clk_fin_epll clk_ext_xtal_mux - -#define clk_fout_mpll clk_mpll -#define clk_fout_epll clk_epll - -struct clk clk_h2 = { - .name = "hclk2", - .rate = 0, -}; - -struct clk clk_27m = { - .name = "clk_27m", - .rate = 27000000, -}; - -static int clk_48m_ctrl(struct clk *clk, int enable) -{ - unsigned long flags; - u32 val; - - /* can't rely on clock lock, this register has other usages */ - local_irq_save(flags); - - val = __raw_readl(S3C64XX_OTHERS); - if (enable) - val |= S3C64XX_OTHERS_USBMASK; - else - val &= ~S3C64XX_OTHERS_USBMASK; - - __raw_writel(val, S3C64XX_OTHERS); - local_irq_restore(flags); - - return 0; -} - -struct clk clk_48m = { - .name = "clk_48m", - .rate = 48000000, - .enable = clk_48m_ctrl, -}; - -struct clk clk_xusbxti = { - .name = "xusbxti", - .rate = 48000000, -}; - -static int inline s3c64xx_gate(void __iomem *reg, - struct clk *clk, - int enable) -{ - unsigned int ctrlbit = clk->ctrlbit; - u32 con; - - con = __raw_readl(reg); - - if (enable) - con |= ctrlbit; - else - con &= ~ctrlbit; - - __raw_writel(con, reg); - return 0; -} - -static int s3c64xx_pclk_ctrl(struct clk *clk, int enable) -{ - return s3c64xx_gate(S3C_PCLK_GATE, clk, enable); -} - -static int s3c64xx_hclk_ctrl(struct clk *clk, int enable) -{ - return s3c64xx_gate(S3C_HCLK_GATE, clk, enable); -} - -int s3c64xx_sclk_ctrl(struct clk *clk, int enable) -{ - return s3c64xx_gate(S3C_SCLK_GATE, clk, enable); -} - -static struct clk init_clocks_off[] = { - { - .name = "nand", - .parent = &clk_h, - }, { - .name = "rtc", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_RTC, - }, { - .name = "adc", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_TSADC, - }, { - .name = "i2c", -#ifdef CONFIG_S3C_DEV_I2C1 - .devname = "s3c2440-i2c.0", -#else - .devname = "s3c2440-i2c", -#endif - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_IIC, - }, { - .name = "i2c", - .devname = "s3c2440-i2c.1", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C6410_CLKCON_PCLK_I2C1, - }, { - .name = "iis", - .devname = "samsung-i2s.0", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_IIS0, - }, { - .name = "iis", - .devname = "samsung-i2s.1", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_IIS1, - }, { -#ifdef CONFIG_CPU_S3C6410 - .name = "iis", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C6410_CLKCON_PCLK_IIS2, - }, { -#endif - .name = "keypad", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_KEYPAD, - }, { - .name = "spi", - .devname = "s3c64xx-spi.0", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_SPI0, - }, { - .name = "spi", - .devname = "s3c64xx-spi.1", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_SPI1, - }, { - .name = "48m", - .devname = "s3c-sdhci.0", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_MMC0_48, - }, { - .name = "48m", - .devname = "s3c-sdhci.1", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_MMC1_48, - }, { - .name = "48m", - .devname = "s3c-sdhci.2", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_MMC2_48, - }, { - .name = "dma0", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_DMA0, - }, { - .name = "dma1", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_DMA1, - }, -}; - -static struct clk clk_48m_spi0 = { - .name = "spi_48m", - .devname = "s3c64xx-spi.0", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_SPI0_48, -}; - -static struct clk clk_48m_spi1 = { - .name = "spi_48m", - .devname = "s3c64xx-spi.1", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_SPI1_48, -}; - -static struct clk init_clocks[] = { - { - .name = "lcd", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_LCD, - }, { - .name = "gpio", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_GPIO, - }, { - .name = "usb-host", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_UHOST, - }, { - .name = "otg", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_USB, - }, { - .name = "timers", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_PWM, - }, { - .name = "uart", - .devname = "s3c6400-uart.0", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_UART0, - }, { - .name = "uart", - .devname = "s3c6400-uart.1", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_UART1, - }, { - .name = "uart", - .devname = "s3c6400-uart.2", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_UART2, - }, { - .name = "uart", - .devname = "s3c6400-uart.3", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_UART3, - }, { - .name = "watchdog", - .parent = &clk_p, - .ctrlbit = S3C_CLKCON_PCLK_WDT, - }, { - .name = "ac97", - .parent = &clk_p, - .ctrlbit = S3C_CLKCON_PCLK_AC97, - }, { - .name = "cfcon", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_IHOST, - } -}; - -static struct clk clk_hsmmc0 = { - .name = "hsmmc", - .devname = "s3c-sdhci.0", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_HSMMC0, -}; - -static struct clk clk_hsmmc1 = { - .name = "hsmmc", - .devname = "s3c-sdhci.1", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_HSMMC1, -}; - -static struct clk clk_hsmmc2 = { - .name = "hsmmc", - .devname = "s3c-sdhci.2", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_HSMMC2, -}; - -static struct clk clk_fout_apll = { - .name = "fout_apll", -}; - -static struct clk *clk_src_apll_list[] = { - [0] = &clk_fin_apll, - [1] = &clk_fout_apll, -}; - -static struct clksrc_sources clk_src_apll = { - .sources = clk_src_apll_list, - .nr_sources = ARRAY_SIZE(clk_src_apll_list), -}; - -static struct clksrc_clk clk_mout_apll = { - .clk = { - .name = "mout_apll", - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 0, .size = 1 }, - .sources = &clk_src_apll, -}; - -static struct clk *clk_src_epll_list[] = { - [0] = &clk_fin_epll, - [1] = &clk_fout_epll, -}; - -static struct clksrc_sources clk_src_epll = { - .sources = clk_src_epll_list, - .nr_sources = ARRAY_SIZE(clk_src_epll_list), -}; - -static struct clksrc_clk clk_mout_epll = { - .clk = { - .name = "mout_epll", - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 2, .size = 1 }, - .sources = &clk_src_epll, -}; - -static struct clk *clk_src_mpll_list[] = { - [0] = &clk_fin_mpll, - [1] = &clk_fout_mpll, -}; - -static struct clksrc_sources clk_src_mpll = { - .sources = clk_src_mpll_list, - .nr_sources = ARRAY_SIZE(clk_src_mpll_list), -}; - -static struct clksrc_clk clk_mout_mpll = { - .clk = { - .name = "mout_mpll", - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 1, .size = 1 }, - .sources = &clk_src_mpll, -}; - -static unsigned int armclk_mask; - -static unsigned long s3c64xx_clk_arm_get_rate(struct clk *clk) -{ - unsigned long rate = clk_get_rate(clk->parent); - u32 clkdiv; - - /* divisor mask starts at bit0, so no need to shift */ - clkdiv = __raw_readl(S3C_CLK_DIV0) & armclk_mask; - - return rate / (clkdiv + 1); -} - -static unsigned long s3c64xx_clk_arm_round_rate(struct clk *clk, - unsigned long rate) -{ - unsigned long parent = clk_get_rate(clk->parent); - u32 div; - - if (parent < rate) - return parent; - - div = (parent / rate) - 1; - if (div > armclk_mask) - div = armclk_mask; - - return parent / (div + 1); -} - -static int s3c64xx_clk_arm_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned long parent = clk_get_rate(clk->parent); - u32 div; - u32 val; - - if (rate < parent / (armclk_mask + 1)) - return -EINVAL; - - rate = clk_round_rate(clk, rate); - div = clk_get_rate(clk->parent) / rate; - - val = __raw_readl(S3C_CLK_DIV0); - val &= ~armclk_mask; - val |= (div - 1); - __raw_writel(val, S3C_CLK_DIV0); - - return 0; - -} - -static struct clk clk_arm = { - .name = "armclk", - .parent = &clk_mout_apll.clk, - .ops = &(struct clk_ops) { - .get_rate = s3c64xx_clk_arm_get_rate, - .set_rate = s3c64xx_clk_arm_set_rate, - .round_rate = s3c64xx_clk_arm_round_rate, - }, -}; - -static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk) -{ - unsigned long rate = clk_get_rate(clk->parent); - - printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate); - - if (__raw_readl(S3C_CLK_DIV0) & S3C6400_CLKDIV0_MPLL_MASK) - rate /= 2; - - return rate; -} - -static struct clk_ops clk_dout_ops = { - .get_rate = s3c64xx_clk_doutmpll_get_rate, -}; - -static struct clk clk_dout_mpll = { - .name = "dout_mpll", - .parent = &clk_mout_mpll.clk, - .ops = &clk_dout_ops, -}; - -static struct clk *clkset_spi_mmc_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll, - &clk_fin_epll, - &clk_27m, -}; - -static struct clksrc_sources clkset_spi_mmc = { - .sources = clkset_spi_mmc_list, - .nr_sources = ARRAY_SIZE(clkset_spi_mmc_list), -}; - -static struct clk *clkset_irda_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll, - NULL, - &clk_27m, -}; - -static struct clksrc_sources clkset_irda = { - .sources = clkset_irda_list, - .nr_sources = ARRAY_SIZE(clkset_irda_list), -}; - -static struct clk *clkset_uart_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll, - NULL, - NULL -}; - -static struct clksrc_sources clkset_uart = { - .sources = clkset_uart_list, - .nr_sources = ARRAY_SIZE(clkset_uart_list), -}; - -static struct clk *clkset_uhost_list[] = { - &clk_48m, - &clk_mout_epll.clk, - &clk_dout_mpll, - &clk_fin_epll, -}; - -static struct clksrc_sources clkset_uhost = { - .sources = clkset_uhost_list, - .nr_sources = ARRAY_SIZE(clkset_uhost_list), -}; - -/* The peripheral clocks are all controlled via clocksource followed - * by an optional divider and gate stage. We currently roll this into - * one clock which hides the intermediate clock from the mux. - * - * Note, the JPEG clock can only be an even divider... - * - * The scaler and LCD clocks depend on the S3C64XX version, and also - * have a common parent divisor so are not included here. - */ - -/* clocks that feed other parts of the clock source tree */ - -static struct clk clk_iis_cd0 = { - .name = "iis_cdclk0", -}; - -static struct clk clk_iis_cd1 = { - .name = "iis_cdclk1", -}; - -static struct clk clk_iisv4_cd = { - .name = "iis_cdclk_v4", -}; - -static struct clk clk_pcm_cd = { - .name = "pcm_cdclk", -}; - -static struct clk *clkset_audio0_list[] = { - [0] = &clk_mout_epll.clk, - [1] = &clk_dout_mpll, - [2] = &clk_fin_epll, - [3] = &clk_iis_cd0, - [4] = &clk_pcm_cd, -}; - -static struct clksrc_sources clkset_audio0 = { - .sources = clkset_audio0_list, - .nr_sources = ARRAY_SIZE(clkset_audio0_list), -}; - -static struct clk *clkset_audio1_list[] = { - [0] = &clk_mout_epll.clk, - [1] = &clk_dout_mpll, - [2] = &clk_fin_epll, - [3] = &clk_iis_cd1, - [4] = &clk_pcm_cd, -}; - -static struct clksrc_sources clkset_audio1 = { - .sources = clkset_audio1_list, - .nr_sources = ARRAY_SIZE(clkset_audio1_list), -}; - -static struct clk *clkset_audio2_list[] = { - [0] = &clk_mout_epll.clk, - [1] = &clk_dout_mpll, - [2] = &clk_fin_epll, - [3] = &clk_iisv4_cd, - [4] = &clk_pcm_cd, -}; - -static struct clksrc_sources clkset_audio2 = { - .sources = clkset_audio2_list, - .nr_sources = ARRAY_SIZE(clkset_audio2_list), -}; - -static struct clk *clkset_camif_list[] = { - &clk_h2, -}; - -static struct clksrc_sources clkset_camif = { - .sources = clkset_camif_list, - .nr_sources = ARRAY_SIZE(clkset_camif_list), -}; - -static struct clksrc_clk clksrcs[] = { - { - .clk = { - .name = "usb-bus-host", - .ctrlbit = S3C_CLKCON_SCLK_UHOST, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 5, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV1, .shift = 20, .size = 4 }, - .sources = &clkset_uhost, - }, { - .clk = { - .name = "audio-bus", - .devname = "samsung-i2s.0", - .ctrlbit = S3C_CLKCON_SCLK_AUDIO0, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 7, .size = 3 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 8, .size = 4 }, - .sources = &clkset_audio0, - }, { - .clk = { - .name = "audio-bus", - .devname = "samsung-i2s.1", - .ctrlbit = S3C_CLKCON_SCLK_AUDIO1, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 10, .size = 3 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 12, .size = 4 }, - .sources = &clkset_audio1, - }, { - .clk = { - .name = "audio-bus", - .devname = "samsung-i2s.2", - .ctrlbit = S3C6410_CLKCON_SCLK_AUDIO2, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C6410_CLK_SRC2, .shift = 0, .size = 3 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 24, .size = 4 }, - .sources = &clkset_audio2, - }, { - .clk = { - .name = "irda-bus", - .ctrlbit = S3C_CLKCON_SCLK_IRDA, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 24, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 20, .size = 4 }, - .sources = &clkset_irda, - }, { - .clk = { - .name = "camera", - .ctrlbit = S3C_CLKCON_SCLK_CAM, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_div = { .reg = S3C_CLK_DIV0, .shift = 20, .size = 4 }, - .reg_src = { .reg = NULL, .shift = 0, .size = 0 }, - .sources = &clkset_camif, - }, -}; - -/* Where does UCLK0 come from? */ -static struct clksrc_clk clk_sclk_uclk = { - .clk = { - .name = "uclk1", - .ctrlbit = S3C_CLKCON_SCLK_UART, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 }, - .sources = &clkset_uart, -}; - -static struct clksrc_clk clk_sclk_mmc0 = { - .clk = { - .name = "mmc_bus", - .devname = "s3c-sdhci.0", - .ctrlbit = S3C_CLKCON_SCLK_MMC0, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 18, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV1, .shift = 0, .size = 4 }, - .sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_mmc1 = { - .clk = { - .name = "mmc_bus", - .devname = "s3c-sdhci.1", - .ctrlbit = S3C_CLKCON_SCLK_MMC1, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 20, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV1, .shift = 4, .size = 4 }, - .sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_mmc2 = { - .clk = { - .name = "mmc_bus", - .devname = "s3c-sdhci.2", - .ctrlbit = S3C_CLKCON_SCLK_MMC2, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 22, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV1, .shift = 8, .size = 4 }, - .sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_spi0 = { - .clk = { - .name = "spi-bus", - .devname = "s3c64xx-spi.0", - .ctrlbit = S3C_CLKCON_SCLK_SPI0, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 14, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 0, .size = 4 }, - .sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_spi1 = { - .clk = { - .name = "spi-bus", - .devname = "s3c64xx-spi.1", - .ctrlbit = S3C_CLKCON_SCLK_SPI1, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 16, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 4, .size = 4 }, - .sources = &clkset_spi_mmc, -}; - -/* Clock initialisation code */ - -static struct clksrc_clk *init_parents[] = { - &clk_mout_apll, - &clk_mout_epll, - &clk_mout_mpll, -}; - -static struct clksrc_clk *clksrc_cdev[] = { - &clk_sclk_uclk, - &clk_sclk_mmc0, - &clk_sclk_mmc1, - &clk_sclk_mmc2, - &clk_sclk_spi0, - &clk_sclk_spi1, -}; - -static struct clk *clk_cdev[] = { - &clk_hsmmc0, - &clk_hsmmc1, - &clk_hsmmc2, - &clk_48m_spi0, - &clk_48m_spi1, -}; - -static struct clk_lookup s3c64xx_clk_lookup[] = { - CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), - CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk), - CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0), - CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1), - CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2), - CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk), - CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), - CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), - CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), - CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk), - CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &clk_48m_spi0), - CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk), - CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk2", &clk_48m_spi1), -}; - -#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) - -void __init_or_cpufreq s3c64xx_setup_clocks(void) -{ - struct clk *xtal_clk; - unsigned long xtal; - unsigned long fclk; - unsigned long hclk; - unsigned long hclk2; - unsigned long pclk; - unsigned long epll; - unsigned long apll; - unsigned long mpll; - unsigned int ptr; - u32 clkdiv0; - - printk(KERN_DEBUG "%s: registering clocks\n", __func__); - - clkdiv0 = __raw_readl(S3C_CLK_DIV0); - printk(KERN_DEBUG "%s: clkdiv0 = %08x\n", __func__, clkdiv0); - - xtal_clk = clk_get(NULL, "xtal"); - BUG_ON(IS_ERR(xtal_clk)); - - xtal = clk_get_rate(xtal_clk); - clk_put(xtal_clk); - - printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); - - /* For now assume the mux always selects the crystal */ - clk_ext_xtal_mux.parent = xtal_clk; - - epll = s3c_get_pll6553x(xtal, __raw_readl(S3C_EPLL_CON0), - __raw_readl(S3C_EPLL_CON1)); - mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON)); - apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON)); - - fclk = mpll; - - printk(KERN_INFO "S3C64XX: PLL settings, A=%ld, M=%ld, E=%ld\n", - apll, mpll, epll); - - if(__raw_readl(S3C64XX_OTHERS) & S3C64XX_OTHERS_SYNCMUXSEL) - /* Synchronous mode */ - hclk2 = apll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2); - else - /* Asynchronous mode */ - hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2); - - hclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK); - pclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK); - - printk(KERN_INFO "S3C64XX: HCLK2=%ld, HCLK=%ld, PCLK=%ld\n", - hclk2, hclk, pclk); - - clk_fout_mpll.rate = mpll; - clk_fout_epll.rate = epll; - clk_fout_apll.rate = apll; - - clk_h2.rate = hclk2; - clk_h.rate = hclk; - clk_p.rate = pclk; - clk_f.rate = fclk; - - for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++) - s3c_set_clksrc(init_parents[ptr], true); - - for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) - s3c_set_clksrc(&clksrcs[ptr], true); -} - -static struct clk *clks1[] __initdata = { - &clk_ext_xtal_mux, - &clk_iis_cd0, - &clk_iis_cd1, - &clk_iisv4_cd, - &clk_pcm_cd, - &clk_mout_epll.clk, - &clk_mout_mpll.clk, - &clk_dout_mpll, - &clk_arm, -}; - -static struct clk *clks[] __initdata = { - &clk_ext, - &clk_epll, - &clk_27m, - &clk_48m, - &clk_h2, - &clk_xusbxti, -}; - -/** - * s3c64xx_register_clocks - register clocks for s3c6400 and s3c6410 - * @xtal: The rate for the clock crystal feeding the PLLs. - * @armclk_divlimit: Divisor mask for ARMCLK. - * - * Register the clocks for the S3C6400 and S3C6410 SoC range, such - * as ARMCLK as well as the necessary parent clocks. - * - * This call does not setup the clocks, which is left to the - * s3c64xx_setup_clocks() call which may be needed by the cpufreq - * or resume code to re-set the clocks if the bootloader has changed - * them. - */ -void __init s3c64xx_register_clocks(unsigned long xtal, - unsigned armclk_divlimit) -{ - unsigned int cnt; - - armclk_mask = armclk_divlimit; - - s3c24xx_register_baseclocks(xtal); - s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); - - s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); - - s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); - s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); - - s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev)); - for (cnt = 0; cnt < ARRAY_SIZE(clk_cdev); cnt++) - s3c_disable_clocks(clk_cdev[cnt], 1); - - s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1)); - s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); - for (cnt = 0; cnt < ARRAY_SIZE(clksrc_cdev); cnt++) - s3c_register_clksrc(clksrc_cdev[cnt], 1); - clkdev_add_table(s3c64xx_clk_lookup, ARRAY_SIZE(s3c64xx_clk_lookup)); - - s3c_pwmclk_init(); -} diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c index bee7dcd4df7..5c45aae675b 100644 --- a/arch/arm/mach-s3c64xx/common.c +++ b/arch/arm/mach-s3c64xx/common.c @@ -14,39 +14,60 @@ * published by the Free Software Foundation. */ +/* + * NOTE: Code in this file is not used when booting with Device Tree support. + */ + #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/clk-provider.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/serial_core.h> +#include <linux/serial_s3c.h> #include <linux/platform_device.h> +#include <linux/reboot.h> #include <linux/io.h> #include <linux/dma-mapping.h> #include <linux/irq.h> #include <linux/gpio.h> +#include <linux/irqchip/arm-vic.h> +#include <clocksource/samsung_pwm.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <asm/hardware/vic.h> +#include <asm/system_misc.h> #include <mach/map.h> #include <mach/hardware.h> #include <mach/regs-gpio.h> +#include <mach/gpio-samsung.h> #include <plat/cpu.h> -#include <plat/clock.h> #include <plat/devs.h> #include <plat/pm.h> #include <plat/gpio-cfg.h> #include <plat/irq-uart.h> -#include <plat/irq-vic-timer.h> +#include <plat/pwm-core.h> #include <plat/regs-irqtype.h> -#include <plat/regs-serial.h> #include <plat/watchdog-reset.h> #include "common.h" +/* External clock frequency */ +static unsigned long xtal_f = 12000000, xusbxti_f = 48000000; + +void __init s3c64xx_set_xtal_freq(unsigned long freq) +{ + xtal_f = freq; +} + +void __init s3c64xx_set_xusbxti_freq(unsigned long freq) +{ + xusbxti_f = freq; +} + /* uart registration process */ static void __init s3c64xx_init_uarts(struct s3c2410_uartcfg *cfg, int no) @@ -64,7 +85,6 @@ static struct cpu_table cpu_ids[] __initdata = { .idcode = S3C6400_CPU_ID, .idmask = S3C64XX_CPU_MASK, .map_io = s3c6400_map_io, - .init_clocks = s3c6400_init_clocks, .init_uarts = s3c64xx_init_uarts, .init = s3c6400_init, .name = name_s3c6400, @@ -72,7 +92,6 @@ static struct cpu_table cpu_ids[] __initdata = { .idcode = S3C6410_CPU_ID, .idmask = S3C64XX_CPU_MASK, .map_io = s3c6410_map_io, - .init_clocks = s3c6410_init_clocks, .init_uarts = s3c64xx_init_uarts, .init = s3c6410_init, .name = name_s3c6410, @@ -147,6 +166,30 @@ static struct device s3c64xx_dev = { .bus = &s3c64xx_subsys, }; +static struct samsung_pwm_variant s3c64xx_pwm_variant = { + .bits = 32, + .div_base = 0, + .has_tint_cstat = true, + .tclk_mask = (1 << 7) | (1 << 6) | (1 << 5), +}; + +void __init samsung_set_timer_source(unsigned int event, unsigned int source) +{ + s3c64xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1; + s3c64xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source)); +} + +void __init samsung_timer_init(void) +{ + unsigned int timer_irqs[SAMSUNG_PWM_NUM] = { + IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC, + IRQ_TIMER3_VIC, IRQ_TIMER4_VIC, + }; + + samsung_pwm_clocksource_init(S3C_VA_TIMER, + timer_irqs, &s3c64xx_pwm_variant); +} + /* read cpu identification code */ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size) @@ -154,16 +197,21 @@ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size) /* initialise the io descriptors we need for initialisation */ iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); iotable_init(mach_desc, size); - init_consistent_dma_size(SZ_8M); /* detect cpu id */ s3c64xx_init_cpu(); s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids)); + + samsung_pwm_set_platdata(&s3c64xx_pwm_variant); } static __init int s3c64xx_dev_init(void) { + /* Not applicable when using DT. */ + if (of_have_populated_dt()) + return 0; + subsys_system_register(&s3c64xx_subsys, NULL); return device_register(&s3c64xx_dev); } @@ -183,14 +231,19 @@ core_initcall(s3c64xx_dev_init); void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid) { + /* + * FIXME: there is no better place to put this at the moment + * (s3c64xx_clk_init needs ioremap and must happen before init_time + * samsung_wdt_reset_init needs clocks) + */ + s3c64xx_clk_init(NULL, xtal_f, xusbxti_f, soc_is_s3c6400(), S3C_VA_SYS); + samsung_wdt_reset_init(S3C_VA_WATCHDOG); + printk(KERN_DEBUG "%s: initialising interrupts\n", __func__); /* initialise the pair of VICs */ vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME); vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME); - - /* add the timer sub-irqs */ - s3c_init_vic_timer_irq(5, IRQ_TIMER0); } #define eint_offset(irq) ((irq) - IRQ_EINT(0)) @@ -360,6 +413,10 @@ static int __init s3c64xx_init_irq_eint(void) { int irq; + /* On DT-enabled systems EINTs are handled by pinctrl-s3c64xx driver. */ + if (of_have_populated_dt()) + return -ENODEV; + for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) { irq_set_chip_and_handler(irq, &s3c_irq_eint, handle_level_irq); irq_set_chip_data(irq, (void *)eint_irq_to_bit(irq)); @@ -375,11 +432,16 @@ static int __init s3c64xx_init_irq_eint(void) } arch_initcall(s3c64xx_init_irq_eint); -void s3c64xx_restart(char mode, const char *cmd) +void s3c64xx_restart(enum reboot_mode mode, const char *cmd) { - if (mode != 's') - arch_wdt_reset(); + if (mode != REBOOT_SOFT) + samsung_wdt_reset(); /* if all else fails, or mode was for soft, jump to 0 */ soft_restart(0); } + +void __init s3c64xx_init_late(void) +{ + s3c64xx_pm_late_initcall(); +} diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c64xx/common.h index 5eb9c9a7d73..7043e7a3a67 100644 --- a/arch/arm/mach-s3c64xx/common.h +++ b/arch/arm/mach-s3c64xx/common.h @@ -17,25 +17,26 @@ #ifndef __ARCH_ARM_MACH_S3C64XX_COMMON_H #define __ARCH_ARM_MACH_S3C64XX_COMMON_H +#include <linux/reboot.h> + void s3c64xx_init_irq(u32 vic0, u32 vic1); void s3c64xx_init_io(struct map_desc *mach_desc, int size); -void s3c64xx_register_clocks(unsigned long xtal, unsigned armclk_limit); -void s3c64xx_setup_clocks(void); - -void s3c64xx_restart(char mode, const char *cmd); +void s3c64xx_restart(enum reboot_mode mode, const char *cmd); +void s3c64xx_init_late(void); -extern struct syscore_ops s3c64xx_irq_syscore_ops; +void s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, + unsigned long xusbxti_f, bool is_s3c6400, void __iomem *reg_base); +void s3c64xx_set_xtal_freq(unsigned long freq); +void s3c64xx_set_xusbxti_freq(unsigned long freq); #ifdef CONFIG_CPU_S3C6400 extern int s3c6400_init(void); extern void s3c6400_init_irq(void); extern void s3c6400_map_io(void); -extern void s3c6400_init_clocks(int xtal); #else -#define s3c6400_init_clocks NULL #define s3c6400_map_io NULL #define s3c6400_init NULL #endif @@ -45,12 +46,21 @@ extern void s3c6400_init_clocks(int xtal); extern int s3c6410_init(void); extern void s3c6410_init_irq(void); extern void s3c6410_map_io(void); -extern void s3c6410_init_clocks(int xtal); #else -#define s3c6410_init_clocks NULL #define s3c6410_map_io NULL #define s3c6410_init NULL #endif +#ifdef CONFIG_PM +int __init s3c64xx_pm_late_initcall(void); +#else +static inline int s3c64xx_pm_late_initcall(void) { return 0; } +#endif + +#ifdef CONFIG_S3C64XX_PL080 +extern struct pl08x_platform_data s3c64xx_dma0_plat_data; +extern struct pl08x_platform_data s3c64xx_dma1_plat_data; +#endif + #endif /* __ARCH_ARM_MACH_S3C64XX_COMMON_H */ diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-s3c64xx/cpuidle.c new file mode 100644 index 00000000000..3c8ab07c201 --- /dev/null +++ b/arch/arm/mach-s3c64xx/cpuidle.c @@ -0,0 +1,63 @@ +/* linux/arch/arm/mach-s3c64xx/cpuidle.c + * + * Copyright (c) 2011 Wolfson Microelectronics, plc + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/cpuidle.h> +#include <linux/io.h> +#include <linux/export.h> +#include <linux/time.h> + +#include <asm/proc-fns.h> + +#include <mach/map.h> + +#include "regs-sys.h" +#include "regs-syscon-power.h" + +static int s3c64xx_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + unsigned long tmp; + + /* Setup PWRCFG to enter idle mode */ + tmp = __raw_readl(S3C64XX_PWR_CFG); + tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK; + tmp |= S3C64XX_PWRCFG_CFG_WFI_IDLE; + __raw_writel(tmp, S3C64XX_PWR_CFG); + + cpu_do_idle(); + + return index; +} + +static struct cpuidle_driver s3c64xx_cpuidle_driver = { + .name = "s3c64xx_cpuidle", + .owner = THIS_MODULE, + .states = { + { + .enter = s3c64xx_enter_idle, + .exit_latency = 1, + .target_residency = 1, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "IDLE", + .desc = "System active, ARM gated", + }, + }, + .state_count = 1, +}; + +static int __init s3c64xx_init_cpuidle(void) +{ + return cpuidle_register(&s3c64xx_cpuidle_driver, NULL); +} +device_initcall(s3c64xx_init_cpuidle); diff --git a/arch/arm/mach-s3c64xx/include/mach/crag6410.h b/arch/arm/mach-s3c64xx/crag6410.h index 4cb2f951f1e..7bc66682687 100644 --- a/arch/arm/mach-s3c64xx/include/mach/crag6410.h +++ b/arch/arm/mach-s3c64xx/crag6410.h @@ -11,11 +11,9 @@ #ifndef MACH_CRAG6410_H #define MACH_CRAG6410_H -#include <linux/gpio.h> +#include <mach/gpio-samsung.h> -#define BANFF_PMIC_IRQ_BASE IRQ_BOARD_START -#define GLENFARCLAS_PMIC_IRQ_BASE (IRQ_BOARD_START + 64) -#define CODEC_IRQ_BASE (IRQ_BOARD_START + 128) +#define GLENFARCLAS_PMIC_IRQ_BASE IRQ_BOARD_START #define PCA935X_GPIO_BASE GPIO_BOARD_START #define CODEC_GPIO_BASE (GPIO_BOARD_START + 8) diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c index 93470b158a4..ff780a8d836 100644 --- a/arch/arm/mach-s3c64xx/dev-audio.c +++ b/arch/arm/mach-s3c64xx/dev-audio.c @@ -20,13 +20,9 @@ #include <mach/dma.h> #include <plat/devs.h> -#include <plat/audio.h> +#include <linux/platform_data/asoc-s3c.h> #include <plat/gpio-cfg.h> - -static const char *rclksrc[] = { - [0] = "iis", - [1] = "audio-bus", -}; +#include <mach/gpio-samsung.h> static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev) { @@ -57,30 +53,13 @@ static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev) } static struct resource s3c64xx_iis0_resource[] = { - [0] = { - .start = S3C64XX_PA_IIS0, - .end = S3C64XX_PA_IIS0 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_I2S0_OUT, - .end = DMACH_I2S0_OUT, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_I2S0_IN, - .end = DMACH_I2S0_IN, - .flags = IORESOURCE_DMA, - }, + [0] = DEFINE_RES_MEM(S3C64XX_PA_IIS0, SZ_256), + [1] = DEFINE_RES_DMA(DMACH_I2S0_OUT), + [2] = DEFINE_RES_DMA(DMACH_I2S0_IN), }; static struct s3c_audio_pdata i2sv3_pdata = { .cfg_gpio = s3c64xx_i2s_cfg_gpio, - .type = { - .i2s = { - .src_clk = rclksrc, - }, - }, }; struct platform_device s3c64xx_device_iis0 = { @@ -95,21 +74,9 @@ struct platform_device s3c64xx_device_iis0 = { EXPORT_SYMBOL(s3c64xx_device_iis0); static struct resource s3c64xx_iis1_resource[] = { - [0] = { - .start = S3C64XX_PA_IIS1, - .end = S3C64XX_PA_IIS1 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_I2S1_OUT, - .end = DMACH_I2S1_OUT, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_I2S1_IN, - .end = DMACH_I2S1_IN, - .flags = IORESOURCE_DMA, - }, + [0] = DEFINE_RES_MEM(S3C64XX_PA_IIS1, SZ_256), + [1] = DEFINE_RES_DMA(DMACH_I2S1_OUT), + [2] = DEFINE_RES_DMA(DMACH_I2S1_IN), }; struct platform_device s3c64xx_device_iis1 = { @@ -124,21 +91,9 @@ struct platform_device s3c64xx_device_iis1 = { EXPORT_SYMBOL(s3c64xx_device_iis1); static struct resource s3c64xx_iisv4_resource[] = { - [0] = { - .start = S3C64XX_PA_IISV4, - .end = S3C64XX_PA_IISV4 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_HSI_I2SV40_TX, - .end = DMACH_HSI_I2SV40_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_HSI_I2SV40_RX, - .end = DMACH_HSI_I2SV40_RX, - .flags = IORESOURCE_DMA, - }, + [0] = DEFINE_RES_MEM(S3C64XX_PA_IISV4, SZ_256), + [1] = DEFINE_RES_DMA(DMACH_HSI_I2SV40_TX), + [2] = DEFINE_RES_DMA(DMACH_HSI_I2SV40_RX), }; static struct s3c_audio_pdata i2sv4_pdata = { @@ -146,7 +101,6 @@ static struct s3c_audio_pdata i2sv4_pdata = { .type = { .i2s = { .quirks = QUIRK_PRI_6CHAN, - .src_clk = rclksrc, }, }, }; @@ -187,21 +141,9 @@ static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev) } static struct resource s3c64xx_pcm0_resource[] = { - [0] = { - .start = S3C64XX_PA_PCM0, - .end = S3C64XX_PA_PCM0 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_PCM0_TX, - .end = DMACH_PCM0_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_PCM0_RX, - .end = DMACH_PCM0_RX, - .flags = IORESOURCE_DMA, - }, + [0] = DEFINE_RES_MEM(S3C64XX_PA_PCM0, SZ_256), + [1] = DEFINE_RES_DMA(DMACH_PCM0_TX), + [2] = DEFINE_RES_DMA(DMACH_PCM0_RX), }; static struct s3c_audio_pdata s3c_pcm0_pdata = { @@ -220,21 +162,9 @@ struct platform_device s3c64xx_device_pcm0 = { EXPORT_SYMBOL(s3c64xx_device_pcm0); static struct resource s3c64xx_pcm1_resource[] = { - [0] = { - .start = S3C64XX_PA_PCM1, - .end = S3C64XX_PA_PCM1 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_PCM1_TX, - .end = DMACH_PCM1_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_PCM1_RX, - .end = DMACH_PCM1_RX, - .flags = IORESOURCE_DMA, - }, + [0] = DEFINE_RES_MEM(S3C64XX_PA_PCM1, SZ_256), + [1] = DEFINE_RES_DMA(DMACH_PCM1_TX), + [2] = DEFINE_RES_DMA(DMACH_PCM1_RX), }; static struct s3c_audio_pdata s3c_pcm1_pdata = { @@ -265,31 +195,11 @@ static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev) } static struct resource s3c64xx_ac97_resource[] = { - [0] = { - .start = S3C64XX_PA_AC97, - .end = S3C64XX_PA_AC97 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_AC97_PCMOUT, - .end = DMACH_AC97_PCMOUT, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_AC97_PCMIN, - .end = DMACH_AC97_PCMIN, - .flags = IORESOURCE_DMA, - }, - [3] = { - .start = DMACH_AC97_MICIN, - .end = DMACH_AC97_MICIN, - .flags = IORESOURCE_DMA, - }, - [4] = { - .start = IRQ_AC97, - .end = IRQ_AC97, - .flags = IORESOURCE_IRQ, - }, + [0] = DEFINE_RES_MEM(S3C64XX_PA_AC97, SZ_256), + [1] = DEFINE_RES_DMA(DMACH_AC97_PCMOUT), + [2] = DEFINE_RES_DMA(DMACH_AC97_PCMIN), + [3] = DEFINE_RES_DMA(DMACH_AC97_MICIN), + [4] = DEFINE_RES_IRQ(IRQ_AC97), }; static struct s3c_audio_pdata s3c_ac97_pdata; diff --git a/arch/arm/mach-s3c64xx/dev-uart.c b/arch/arm/mach-s3c64xx/dev-uart.c index c681b99eda0..46e18d77ea9 100644 --- a/arch/arm/mach-s3c64xx/dev-uart.c +++ b/arch/arm/mach-s3c64xx/dev-uart.c @@ -31,55 +31,23 @@ /* 64xx uarts are closer together */ static struct resource s3c64xx_uart0_resource[] = { - [0] = { - .start = S3C_PA_UART0, - .end = S3C_PA_UART0 + 0x100, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_UART0, - .end = IRQ_UART0, - .flags = IORESOURCE_IRQ, - }, + [0] = DEFINE_RES_MEM(S3C_PA_UART0, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_UART0), }; static struct resource s3c64xx_uart1_resource[] = { - [0] = { - .start = S3C_PA_UART1, - .end = S3C_PA_UART1 + 0x100, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_UART1, - .end = IRQ_UART1, - .flags = IORESOURCE_IRQ, - }, + [0] = DEFINE_RES_MEM(S3C_PA_UART1, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_UART1), }; static struct resource s3c6xx_uart2_resource[] = { - [0] = { - .start = S3C_PA_UART2, - .end = S3C_PA_UART2 + 0x100, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_UART2, - .end = IRQ_UART2, - .flags = IORESOURCE_IRQ, - }, + [0] = DEFINE_RES_MEM(S3C_PA_UART2, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_UART2), }; static struct resource s3c64xx_uart3_resource[] = { - [0] = { - .start = S3C_PA_UART3, - .end = S3C_PA_UART3 + 0x100, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_UART3, - .end = IRQ_UART3, - .flags = IORESOURCE_IRQ, - }, + [0] = DEFINE_RES_MEM(S3C_PA_UART3, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_UART3), }; diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c deleted file mode 100644 index f2a7a172559..00000000000 --- a/arch/arm/mach-s3c64xx/dma.c +++ /dev/null @@ -1,753 +0,0 @@ -/* linux/arch/arm/plat-s3c64xx/dma.c - * - * Copyright 2009 Openmoko, Inc. - * Copyright 2009 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C64XX DMA core - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/dmapool.h> -#include <linux/device.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/io.h> - -#include <mach/dma.h> -#include <mach/map.h> -#include <mach/irqs.h> - -#include <mach/regs-sys.h> - -#include <asm/hardware/pl080.h> - -/* dma channel state information */ - -struct s3c64xx_dmac { - struct device dev; - struct clk *clk; - void __iomem *regs; - struct s3c2410_dma_chan *channels; - enum dma_ch chanbase; -}; - -/* pool to provide LLI buffers */ -static struct dma_pool *dma_pool; - -/* Debug configuration and code */ - -static unsigned char debug_show_buffs = 0; - -static void dbg_showchan(struct s3c2410_dma_chan *chan) -{ - pr_debug("DMA%d: %08x->%08x L %08x C %08x,%08x S %08x\n", - chan->number, - readl(chan->regs + PL080_CH_SRC_ADDR), - readl(chan->regs + PL080_CH_DST_ADDR), - readl(chan->regs + PL080_CH_LLI), - readl(chan->regs + PL080_CH_CONTROL), - readl(chan->regs + PL080S_CH_CONTROL2), - readl(chan->regs + PL080S_CH_CONFIG)); -} - -static void show_lli(struct pl080s_lli *lli) -{ - pr_debug("LLI[%p] %08x->%08x, NL %08x C %08x,%08x\n", - lli, lli->src_addr, lli->dst_addr, lli->next_lli, - lli->control0, lli->control1); -} - -static void dbg_showbuffs(struct s3c2410_dma_chan *chan) -{ - struct s3c64xx_dma_buff *ptr; - struct s3c64xx_dma_buff *end; - - pr_debug("DMA%d: buffs next %p, curr %p, end %p\n", - chan->number, chan->next, chan->curr, chan->end); - - ptr = chan->next; - end = chan->end; - - if (debug_show_buffs) { - for (; ptr != NULL; ptr = ptr->next) { - pr_debug("DMA%d: %08x ", - chan->number, ptr->lli_dma); - show_lli(ptr->lli); - } - } -} - -/* End of Debug */ - -static struct s3c2410_dma_chan *s3c64xx_dma_map_channel(unsigned int channel) -{ - struct s3c2410_dma_chan *chan; - unsigned int start, offs; - - start = 0; - - if (channel >= DMACH_PCM1_TX) - start = 8; - - for (offs = 0; offs < 8; offs++) { - chan = &s3c2410_chans[start + offs]; - if (!chan->in_use) - goto found; - } - - return NULL; - -found: - s3c_dma_chan_map[channel] = chan; - return chan; -} - -int s3c2410_dma_config(enum dma_ch channel, int xferunit) -{ - struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); - - if (chan == NULL) - return -EINVAL; - - switch (xferunit) { - case 1: - chan->hw_width = 0; - break; - case 2: - chan->hw_width = 1; - break; - case 4: - chan->hw_width = 2; - break; - default: - printk(KERN_ERR "%s: illegal width %d\n", __func__, xferunit); - return -EINVAL; - } - - return 0; -} -EXPORT_SYMBOL(s3c2410_dma_config); - -static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan, - struct pl080s_lli *lli, - dma_addr_t data, int size) -{ - dma_addr_t src, dst; - u32 control0, control1; - - switch (chan->source) { - case DMA_FROM_DEVICE: - src = chan->dev_addr; - dst = data; - control0 = PL080_CONTROL_SRC_AHB2; - control0 |= PL080_CONTROL_DST_INCR; - break; - - case DMA_TO_DEVICE: - src = data; - dst = chan->dev_addr; - control0 = PL080_CONTROL_DST_AHB2; - control0 |= PL080_CONTROL_SRC_INCR; - break; - default: - BUG(); - } - - /* note, we do not currently setup any of the burst controls */ - - control1 = size >> chan->hw_width; /* size in no of xfers */ - control0 |= PL080_CONTROL_PROT_SYS; /* always in priv. mode */ - control0 |= PL080_CONTROL_TC_IRQ_EN; /* always fire IRQ */ - control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT; - control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT; - - lli->src_addr = src; - lli->dst_addr = dst; - lli->next_lli = 0; - lli->control0 = control0; - lli->control1 = control1; -} - -static void s3c64xx_lli_to_regs(struct s3c2410_dma_chan *chan, - struct pl080s_lli *lli) -{ - void __iomem *regs = chan->regs; - - pr_debug("%s: LLI %p => regs\n", __func__, lli); - show_lli(lli); - - writel(lli->src_addr, regs + PL080_CH_SRC_ADDR); - writel(lli->dst_addr, regs + PL080_CH_DST_ADDR); - writel(lli->next_lli, regs + PL080_CH_LLI); - writel(lli->control0, regs + PL080_CH_CONTROL); - writel(lli->control1, regs + PL080S_CH_CONTROL2); -} - -static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan) -{ - struct s3c64xx_dmac *dmac = chan->dmac; - u32 config; - u32 bit = chan->bit; - - dbg_showchan(chan); - - pr_debug("%s: clearing interrupts\n", __func__); - - /* clear interrupts */ - writel(bit, dmac->regs + PL080_TC_CLEAR); - writel(bit, dmac->regs + PL080_ERR_CLEAR); - - pr_debug("%s: starting channel\n", __func__); - - config = readl(chan->regs + PL080S_CH_CONFIG); - config |= PL080_CONFIG_ENABLE; - config &= ~PL080_CONFIG_HALT; - - pr_debug("%s: writing config %08x\n", __func__, config); - writel(config, chan->regs + PL080S_CH_CONFIG); - - return 0; -} - -static int s3c64xx_dma_stop(struct s3c2410_dma_chan *chan) -{ - u32 config; - int timeout; - - pr_debug("%s: stopping channel\n", __func__); - - dbg_showchan(chan); - - config = readl(chan->regs + PL080S_CH_CONFIG); - config |= PL080_CONFIG_HALT; - writel(config, chan->regs + PL080S_CH_CONFIG); - - timeout = 1000; - do { - config = readl(chan->regs + PL080S_CH_CONFIG); - pr_debug("%s: %d - config %08x\n", __func__, timeout, config); - if (config & PL080_CONFIG_ACTIVE) - udelay(10); - else - break; - } while (--timeout > 0); - - if (config & PL080_CONFIG_ACTIVE) { - printk(KERN_ERR "%s: channel still active\n", __func__); - return -EFAULT; - } - - config = readl(chan->regs + PL080S_CH_CONFIG); - config &= ~PL080_CONFIG_ENABLE; - writel(config, chan->regs + PL080S_CH_CONFIG); - - return 0; -} - -static inline void s3c64xx_dma_bufffdone(struct s3c2410_dma_chan *chan, - struct s3c64xx_dma_buff *buf, - enum s3c2410_dma_buffresult result) -{ - if (chan->callback_fn != NULL) - (chan->callback_fn)(chan, buf->pw, 0, result); -} - -static void s3c64xx_dma_freebuff(struct s3c64xx_dma_buff *buff) -{ - dma_pool_free(dma_pool, buff->lli, buff->lli_dma); - kfree(buff); -} - -static int s3c64xx_dma_flush(struct s3c2410_dma_chan *chan) -{ - struct s3c64xx_dma_buff *buff, *next; - u32 config; - - dbg_showchan(chan); - - pr_debug("%s: flushing channel\n", __func__); - - config = readl(chan->regs + PL080S_CH_CONFIG); - config &= ~PL080_CONFIG_ENABLE; - writel(config, chan->regs + PL080S_CH_CONFIG); - - /* dump all the buffers associated with this channel */ - - for (buff = chan->curr; buff != NULL; buff = next) { - next = buff->next; - pr_debug("%s: buff %p (next %p)\n", __func__, buff, buff->next); - - s3c64xx_dma_bufffdone(chan, buff, S3C2410_RES_ABORT); - s3c64xx_dma_freebuff(buff); - } - - chan->curr = chan->next = chan->end = NULL; - - return 0; -} - -int s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op) -{ - struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); - - WARN_ON(!chan); - if (!chan) - return -EINVAL; - - switch (op) { - case S3C2410_DMAOP_START: - return s3c64xx_dma_start(chan); - - case S3C2410_DMAOP_STOP: - return s3c64xx_dma_stop(chan); - - case S3C2410_DMAOP_FLUSH: - return s3c64xx_dma_flush(chan); - - /* believe PAUSE/RESUME are no-ops */ - case S3C2410_DMAOP_PAUSE: - case S3C2410_DMAOP_RESUME: - case S3C2410_DMAOP_STARTED: - case S3C2410_DMAOP_TIMEOUT: - return 0; - } - - return -ENOENT; -} -EXPORT_SYMBOL(s3c2410_dma_ctrl); - -/* s3c2410_dma_enque - * - */ - -int s3c2410_dma_enqueue(enum dma_ch channel, void *id, - dma_addr_t data, int size) -{ - struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); - struct s3c64xx_dma_buff *next; - struct s3c64xx_dma_buff *buff; - struct pl080s_lli *lli; - unsigned long flags; - int ret; - - WARN_ON(!chan); - if (!chan) - return -EINVAL; - - buff = kzalloc(sizeof(struct s3c64xx_dma_buff), GFP_ATOMIC); - if (!buff) { - printk(KERN_ERR "%s: no memory for buffer\n", __func__); - return -ENOMEM; - } - - lli = dma_pool_alloc(dma_pool, GFP_ATOMIC, &buff->lli_dma); - if (!lli) { - printk(KERN_ERR "%s: no memory for lli\n", __func__); - ret = -ENOMEM; - goto err_buff; - } - - pr_debug("%s: buff %p, dp %08x lli (%p, %08x) %d\n", - __func__, buff, data, lli, (u32)buff->lli_dma, size); - - buff->lli = lli; - buff->pw = id; - - s3c64xx_dma_fill_lli(chan, lli, data, size); - - local_irq_save(flags); - - if ((next = chan->next) != NULL) { - struct s3c64xx_dma_buff *end = chan->end; - struct pl080s_lli *endlli = end->lli; - - pr_debug("enquing onto channel\n"); - - end->next = buff; - endlli->next_lli = buff->lli_dma; - - if (chan->flags & S3C2410_DMAF_CIRCULAR) { - struct s3c64xx_dma_buff *curr = chan->curr; - lli->next_lli = curr->lli_dma; - } - - if (next == chan->curr) { - writel(buff->lli_dma, chan->regs + PL080_CH_LLI); - chan->next = buff; - } - - show_lli(endlli); - chan->end = buff; - } else { - pr_debug("enquing onto empty channel\n"); - - chan->curr = buff; - chan->next = buff; - chan->end = buff; - - s3c64xx_lli_to_regs(chan, lli); - } - - local_irq_restore(flags); - - show_lli(lli); - - dbg_showchan(chan); - dbg_showbuffs(chan); - return 0; - -err_buff: - kfree(buff); - return ret; -} - -EXPORT_SYMBOL(s3c2410_dma_enqueue); - - -int s3c2410_dma_devconfig(enum dma_ch channel, - enum dma_data_direction source, - unsigned long devaddr) -{ - struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); - u32 peripheral; - u32 config = 0; - - pr_debug("%s: channel %d, source %d, dev %08lx, chan %p\n", - __func__, channel, source, devaddr, chan); - - WARN_ON(!chan); - if (!chan) - return -EINVAL; - - peripheral = (chan->peripheral & 0xf); - chan->source = source; - chan->dev_addr = devaddr; - - pr_debug("%s: peripheral %d\n", __func__, peripheral); - - switch (source) { - case DMA_FROM_DEVICE: - config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT; - config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT; - break; - case DMA_TO_DEVICE: - config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT; - config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT; - break; - default: - printk(KERN_ERR "%s: bad source\n", __func__); - return -EINVAL; - } - - /* allow TC and ERR interrupts */ - config |= PL080_CONFIG_TC_IRQ_MASK; - config |= PL080_CONFIG_ERR_IRQ_MASK; - - pr_debug("%s: config %08x\n", __func__, config); - - writel(config, chan->regs + PL080S_CH_CONFIG); - - return 0; -} -EXPORT_SYMBOL(s3c2410_dma_devconfig); - - -int s3c2410_dma_getposition(enum dma_ch channel, - dma_addr_t *src, dma_addr_t *dst) -{ - struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); - - WARN_ON(!chan); - if (!chan) - return -EINVAL; - - if (src != NULL) - *src = readl(chan->regs + PL080_CH_SRC_ADDR); - - if (dst != NULL) - *dst = readl(chan->regs + PL080_CH_DST_ADDR); - - return 0; -} -EXPORT_SYMBOL(s3c2410_dma_getposition); - -/* s3c2410_request_dma - * - * get control of an dma channel -*/ - -int s3c2410_dma_request(enum dma_ch channel, - struct s3c2410_dma_client *client, - void *dev) -{ - struct s3c2410_dma_chan *chan; - unsigned long flags; - - pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n", - channel, client->name, dev); - - local_irq_save(flags); - - chan = s3c64xx_dma_map_channel(channel); - if (chan == NULL) { - local_irq_restore(flags); - return -EBUSY; - } - - dbg_showchan(chan); - - chan->client = client; - chan->in_use = 1; - chan->peripheral = channel; - - local_irq_restore(flags); - - /* need to setup */ - - pr_debug("%s: channel initialised, %p\n", __func__, chan); - - return chan->number | DMACH_LOW_LEVEL; -} - -EXPORT_SYMBOL(s3c2410_dma_request); - -/* s3c2410_dma_free - * - * release the given channel back to the system, will stop and flush - * any outstanding transfers, and ensure the channel is ready for the - * next claimant. - * - * Note, although a warning is currently printed if the freeing client - * info is not the same as the registrant's client info, the free is still - * allowed to go through. -*/ - -int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *client) -{ - struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); - unsigned long flags; - - if (chan == NULL) - return -EINVAL; - - local_irq_save(flags); - - if (chan->client != client) { - printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n", - channel, chan->client, client); - } - - /* sort out stopping and freeing the channel */ - - - chan->client = NULL; - chan->in_use = 0; - - if (!(channel & DMACH_LOW_LEVEL)) - s3c_dma_chan_map[channel] = NULL; - - local_irq_restore(flags); - - return 0; -} - -EXPORT_SYMBOL(s3c2410_dma_free); - -static irqreturn_t s3c64xx_dma_irq(int irq, void *pw) -{ - struct s3c64xx_dmac *dmac = pw; - struct s3c2410_dma_chan *chan; - enum s3c2410_dma_buffresult res; - u32 tcstat, errstat; - u32 bit; - int offs; - - tcstat = readl(dmac->regs + PL080_TC_STATUS); - errstat = readl(dmac->regs + PL080_ERR_STATUS); - - for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) { - struct s3c64xx_dma_buff *buff; - - if (!(errstat & bit) && !(tcstat & bit)) - continue; - - chan = dmac->channels + offs; - res = S3C2410_RES_ERR; - - if (tcstat & bit) { - writel(bit, dmac->regs + PL080_TC_CLEAR); - res = S3C2410_RES_OK; - } - - if (errstat & bit) - writel(bit, dmac->regs + PL080_ERR_CLEAR); - - /* 'next' points to the buffer that is next to the - * currently active buffer. - * For CIRCULAR queues, 'next' will be same as 'curr' - * when 'end' is the active buffer. - */ - buff = chan->curr; - while (buff && buff != chan->next - && buff->next != chan->next) - buff = buff->next; - - if (!buff) - BUG(); - - if (buff == chan->next) - buff = chan->end; - - s3c64xx_dma_bufffdone(chan, buff, res); - - /* Free the node and update curr, if non-circular queue */ - if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) { - chan->curr = buff->next; - s3c64xx_dma_freebuff(buff); - } - - /* Update 'next' */ - buff = chan->next; - if (chan->next == chan->end) { - chan->next = chan->curr; - if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) - chan->end = NULL; - } else { - chan->next = buff->next; - } - } - - return IRQ_HANDLED; -} - -static struct bus_type dma_subsys = { - .name = "s3c64xx-dma", - .dev_name = "s3c64xx-dma", -}; - -static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, - int irq, unsigned int base) -{ - struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno]; - struct s3c64xx_dmac *dmac; - char clkname[16]; - void __iomem *regs; - void __iomem *regptr; - int err, ch; - - dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL); - if (!dmac) { - printk(KERN_ERR "%s: failed to alloc mem\n", __func__); - return -ENOMEM; - } - - dmac->dev.id = chno / 8; - dmac->dev.bus = &dma_subsys; - - err = device_register(&dmac->dev); - if (err) { - printk(KERN_ERR "%s: failed to register device\n", __func__); - goto err_alloc; - } - - regs = ioremap(base, 0x200); - if (!regs) { - printk(KERN_ERR "%s: failed to ioremap()\n", __func__); - err = -ENXIO; - goto err_dev; - } - - snprintf(clkname, sizeof(clkname), "dma%d", dmac->dev.id); - - dmac->clk = clk_get(NULL, clkname); - if (IS_ERR(dmac->clk)) { - printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname); - err = PTR_ERR(dmac->clk); - goto err_map; - } - - clk_enable(dmac->clk); - - dmac->regs = regs; - dmac->chanbase = chbase; - dmac->channels = chptr; - - err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac); - if (err < 0) { - printk(KERN_ERR "%s: failed to get irq\n", __func__); - goto err_clk; - } - - regptr = regs + PL080_Cx_BASE(0); - - for (ch = 0; ch < 8; ch++, chptr++) { - pr_debug("%s: registering DMA %d (%p)\n", - __func__, chno + ch, regptr); - - chptr->bit = 1 << ch; - chptr->number = chno + ch; - chptr->dmac = dmac; - chptr->regs = regptr; - regptr += PL080_Cx_STRIDE; - } - - /* for the moment, permanently enable the controller */ - writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG); - - printk(KERN_INFO "PL080: IRQ %d, at %p, channels %d..%d\n", - irq, regs, chno, chno+8); - - return 0; - -err_clk: - clk_disable(dmac->clk); - clk_put(dmac->clk); -err_map: - iounmap(regs); -err_dev: - device_unregister(&dmac->dev); -err_alloc: - kfree(dmac); - return err; -} - -static int __init s3c64xx_dma_init(void) -{ - int ret; - - printk(KERN_INFO "%s: Registering DMA channels\n", __func__); - - dma_pool = dma_pool_create("DMA-LLI", NULL, sizeof(struct pl080s_lli), 16, 0); - if (!dma_pool) { - printk(KERN_ERR "%s: failed to create pool\n", __func__); - return -ENOMEM; - } - - ret = subsys_system_register(&dma_subsys, NULL); - if (ret) { - printk(KERN_ERR "%s: failed to create subsys\n", __func__); - return -ENOMEM; - } - - /* Set all DMA configuration to be DMA, not SDMA */ - writel(0xffffff, S3C64XX_SDMA_SEL); - - /* Register standard DMA controllers */ - s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000); - s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000); - - return 0; -} - -arch_initcall(s3c64xx_dma_init); diff --git a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S index c0c076a90f2..c9b95325b67 100644 --- a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S +++ b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S @@ -12,8 +12,8 @@ /* pull in the relevant register and map files. */ +#include <linux/serial_s3c.h> #include <mach/map.h> -#include <plat/regs-serial.h> /* note, for the boot process to work we have to keep the UART * virtual address aligned to an 1MiB boundary for the L1 @@ -35,4 +35,4 @@ * will be fine with us. */ -#include <plat/debug-macro.S> +#include <debug/samsung.S> diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h index fe1a98cf0e4..059b1fc8503 100644 --- a/arch/arm/mach-s3c64xx/include/mach/dma.h +++ b/arch/arm/mach-s3c64xx/include/mach/dma.h @@ -11,51 +11,48 @@ #ifndef __ASM_ARCH_DMA_H #define __ASM_ARCH_DMA_H __FILE__ -#define S3C_DMA_CHANNELS (16) +#define S3C64XX_DMA_CHAN(name) ((unsigned long)(name)) + +/* DMA0/SDMA0 */ +#define DMACH_UART0 S3C64XX_DMA_CHAN("uart0_tx") +#define DMACH_UART0_SRC2 S3C64XX_DMA_CHAN("uart0_rx") +#define DMACH_UART1 S3C64XX_DMA_CHAN("uart1_tx") +#define DMACH_UART1_SRC2 S3C64XX_DMA_CHAN("uart1_rx") +#define DMACH_UART2 S3C64XX_DMA_CHAN("uart2_tx") +#define DMACH_UART2_SRC2 S3C64XX_DMA_CHAN("uart2_rx") +#define DMACH_UART3 S3C64XX_DMA_CHAN("uart3_tx") +#define DMACH_UART3_SRC2 S3C64XX_DMA_CHAN("uart3_rx") +#define DMACH_PCM0_TX S3C64XX_DMA_CHAN("pcm0_tx") +#define DMACH_PCM0_RX S3C64XX_DMA_CHAN("pcm0_rx") +#define DMACH_I2S0_OUT S3C64XX_DMA_CHAN("i2s0_tx") +#define DMACH_I2S0_IN S3C64XX_DMA_CHAN("i2s0_rx") +#define DMACH_SPI0_TX S3C64XX_DMA_CHAN("spi0_tx") +#define DMACH_SPI0_RX S3C64XX_DMA_CHAN("spi0_rx") +#define DMACH_HSI_I2SV40_TX S3C64XX_DMA_CHAN("i2s2_tx") +#define DMACH_HSI_I2SV40_RX S3C64XX_DMA_CHAN("i2s2_rx") + +/* DMA1/SDMA1 */ +#define DMACH_PCM1_TX S3C64XX_DMA_CHAN("pcm1_tx") +#define DMACH_PCM1_RX S3C64XX_DMA_CHAN("pcm1_rx") +#define DMACH_I2S1_OUT S3C64XX_DMA_CHAN("i2s1_tx") +#define DMACH_I2S1_IN S3C64XX_DMA_CHAN("i2s1_rx") +#define DMACH_SPI1_TX S3C64XX_DMA_CHAN("spi1_tx") +#define DMACH_SPI1_RX S3C64XX_DMA_CHAN("spi1_rx") +#define DMACH_AC97_PCMOUT S3C64XX_DMA_CHAN("ac97_out") +#define DMACH_AC97_PCMIN S3C64XX_DMA_CHAN("ac97_in") +#define DMACH_AC97_MICIN S3C64XX_DMA_CHAN("ac97_mic") +#define DMACH_PWM S3C64XX_DMA_CHAN("pwm") +#define DMACH_IRDA S3C64XX_DMA_CHAN("irda") +#define DMACH_EXTERNAL S3C64XX_DMA_CHAN("external") +#define DMACH_SECURITY_RX S3C64XX_DMA_CHAN("sec_rx") +#define DMACH_SECURITY_TX S3C64XX_DMA_CHAN("sec_tx") -/* see mach-s3c2410/dma.h for notes on dma channel numbers */ - -/* Note, for the S3C64XX architecture we keep the DMACH_ - * defines in the order they are allocated to [S]DMA0/[S]DMA1 - * so that is easy to do DHACH_ -> DMA controller conversion - */ enum dma_ch { - /* DMA0/SDMA0 */ - DMACH_UART0 = 0, - DMACH_UART0_SRC2, - DMACH_UART1, - DMACH_UART1_SRC2, - DMACH_UART2, - DMACH_UART2_SRC2, - DMACH_UART3, - DMACH_UART3_SRC2, - DMACH_PCM0_TX, - DMACH_PCM0_RX, - DMACH_I2S0_OUT, - DMACH_I2S0_IN, - DMACH_SPI0_TX, - DMACH_SPI0_RX, - DMACH_HSI_I2SV40_TX, - DMACH_HSI_I2SV40_RX, + DMACH_MAX = 32 +}; - /* DMA1/SDMA1 */ - DMACH_PCM1_TX = 16, - DMACH_PCM1_RX, - DMACH_I2S1_OUT, - DMACH_I2S1_IN, - DMACH_SPI1_TX, - DMACH_SPI1_RX, - DMACH_AC97_PCMOUT, - DMACH_AC97_PCMIN, - DMACH_AC97_MICIN, - DMACH_PWM, - DMACH_IRDA, - DMACH_EXTERNAL, - DMACH_RES1, - DMACH_RES2, - DMACH_SECURITY_RX, /* SDMA1 only */ - DMACH_SECURITY_TX, /* SDMA1 only */ - DMACH_MAX /* the end */ +struct s3c2410_dma_client { + char *name; }; static inline bool samsung_dma_has_circular(void) @@ -65,67 +62,10 @@ static inline bool samsung_dma_has_circular(void) static inline bool samsung_dma_is_dmadev(void) { - return false; + return true; } -#define S3C2410_DMAF_CIRCULAR (1 << 0) - -#include <plat/dma.h> - -#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */ - -struct s3c64xx_dma_buff; - -/** s3c64xx_dma_buff - S3C64XX DMA buffer descriptor - * @next: Pointer to next buffer in queue or ring. - * @pw: Client provided identifier - * @lli: Pointer to hardware descriptor this buffer is associated with. - * @lli_dma: Hardare address of the descriptor. - */ -struct s3c64xx_dma_buff { - struct s3c64xx_dma_buff *next; - - void *pw; - struct pl080s_lli *lli; - dma_addr_t lli_dma; -}; - -struct s3c64xx_dmac; - -struct s3c2410_dma_chan { - unsigned char number; /* number of this dma channel */ - unsigned char in_use; /* channel allocated */ - unsigned char bit; /* bit for enable/disable/etc */ - unsigned char hw_width; - unsigned char peripheral; - - unsigned int flags; - enum dma_data_direction source; - - - dma_addr_t dev_addr; - - struct s3c2410_dma_client *client; - struct s3c64xx_dmac *dmac; /* pointer to controller */ - - void __iomem *regs; - - /* cdriver callbacks */ - s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */ - s3c2410_dma_opfn_t op_fn; /* channel op callback */ - - /* buffer list and information */ - struct s3c64xx_dma_buff *curr; /* current dma buffer */ - struct s3c64xx_dma_buff *next; /* next buffer to load */ - struct s3c64xx_dma_buff *end; /* end of queue */ - - /* note, when channel is running in circular mode, curr is the - * first buffer enqueued, end is the last and curr is where the - * last buffer-done event is set-at. The buffers are not freed - * and the last buffer hardware descriptor points back to the - * first. - */ -}; -#include <plat/dma-core.h> +#include <linux/amba/pl08x.h> +#include <plat/dma-ops.h> #endif /* __ASM_ARCH_IRQ_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/entry-macro.S b/arch/arm/mach-s3c64xx/include/mach/entry-macro.S deleted file mode 100644 index dc2bc15142c..00000000000 --- a/arch/arm/mach-s3c64xx/include/mach/entry-macro.S +++ /dev/null @@ -1,19 +0,0 @@ -/* arch/arm/mach-s3c6400/include/mach/entry-macro.S - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * Low-level IRQ helper macros for the Samsung S3C64XX series - * - * 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. -*/ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio.h b/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h index 8b540c42d5d..9c81fac3b2d 100644 --- a/arch/arm/mach-s3c64xx/include/mach/gpio.h +++ b/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h @@ -1,5 +1,4 @@ -/* arch/arm/mach-s3c6400/include/mach/gpio.h - * +/* * Copyright 2008 Openmoko, Inc. * Copyright 2008 Simtec Electronics * http://armlinux.simtec.co.uk/ @@ -12,6 +11,9 @@ * published by the Free Software Foundation. */ +#ifndef GPIO_SAMSUNG_S3C64XX_H +#define GPIO_SAMSUNG_S3C64XX_H + /* GPIO bank sizes */ #define S3C64XX_GPIO_A_NR (8) #define S3C64XX_GPIO_B_NR (7) @@ -88,6 +90,5 @@ enum s3c_gpio_number { /* define the number of gpios we need to the one after the GPQ() range */ #define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1) -#define BOARD_NR_GPIOS (16 + CONFIG_SAMSUNG_GPIO_EXTRA) +#endif /* GPIO_SAMSUNG_S3C64XX_H */ -#define ARCH_NR_GPIOS (GPIO_BOARD_START + BOARD_NR_GPIOS) diff --git a/arch/arm/mach-s3c64xx/include/mach/io.h b/arch/arm/mach-s3c64xx/include/mach/io.h deleted file mode 100644 index de5716dbbd6..00000000000 --- a/arch/arm/mach-s3c64xx/include/mach/io.h +++ /dev/null @@ -1,18 +0,0 @@ -/* arch/arm/mach-s3c64xxinclude/mach/io.h - * - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben-linux@fluff.org> - * - * Default IO routines for S3C64XX based - */ - -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -/* No current ISA/PCI bus support. */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#define IO_SPACE_LIMIT (0xFFFFFFFF) - -#endif diff --git a/arch/arm/mach-s3c64xx/include/mach/irqs.h b/arch/arm/mach-s3c64xx/include/mach/irqs.h index 96d60e0d937..67bbd1dd04c 100644 --- a/arch/arm/mach-s3c64xx/include/mach/irqs.h +++ b/arch/arm/mach-s3c64xx/include/mach/irqs.h @@ -107,14 +107,6 @@ #define IRQ_TC IRQ_PENDN #define IRQ_ADC S3C64XX_IRQ_VIC1(31) -#define S3C64XX_TIMER_IRQ(x) S3C_IRQ(64 + (x)) - -#define IRQ_TIMER0 S3C64XX_TIMER_IRQ(0) -#define IRQ_TIMER1 S3C64XX_TIMER_IRQ(1) -#define IRQ_TIMER2 S3C64XX_TIMER_IRQ(2) -#define IRQ_TIMER3 S3C64XX_TIMER_IRQ(3) -#define IRQ_TIMER4 S3C64XX_TIMER_IRQ(4) - /* compatibility for device defines */ #define IRQ_IIC1 IRQ_S3C6410_IIC1 diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c64xx/include/mach/map.h index 8e2097bb208..f55ccb1ce89 100644 --- a/arch/arm/mach-s3c64xx/include/mach/map.h +++ b/arch/arm/mach-s3c64xx/include/mach/map.h @@ -121,5 +121,6 @@ #define SAMSUNG_PA_ADC S3C64XX_PA_ADC #define SAMSUNG_PA_CFCON S3C64XX_PA_CFCON #define SAMSUNG_PA_KEYPAD S3C64XX_PA_KEYPAD +#define SAMSUNG_PA_TIMER S3C64XX_PA_TIMER #endif /* __ASM_ARCH_6400_MAP_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/pm-core.h b/arch/arm/mach-s3c64xx/include/mach/pm-core.h index fcf3dcabb69..a30a1e3ffc6 100644 --- a/arch/arm/mach-s3c64xx/include/mach/pm-core.h +++ b/arch/arm/mach-s3c64xx/include/mach/pm-core.h @@ -12,6 +12,11 @@ * published by the Free Software Foundation. */ +#ifndef __MACH_S3C64XX_PM_CORE_H +#define __MACH_S3C64XX_PM_CORE_H __FILE__ + +#include <linux/serial_s3c.h> + #include <mach/regs-gpio.h> static inline void s3c_pm_debug_init_uart(void) @@ -113,3 +118,4 @@ static inline void samsung_pm_saved_gpios(void) __raw_writel(S3C64XX_SLPEN_USE_xSLP, S3C64XX_SLPEN); } +#endif /* __MACH_S3C64XX_PM_CORE_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h index 05332b998ec..4f44aac7709 100644 --- a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h +++ b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h @@ -15,145 +15,21 @@ #ifndef __PLAT_REGS_CLOCK_H #define __PLAT_REGS_CLOCK_H __FILE__ +/* + * FIXME: Remove remaining definitions + */ + #define S3C_CLKREG(x) (S3C_VA_SYS + (x)) -#define S3C_APLL_LOCK S3C_CLKREG(0x00) -#define S3C_MPLL_LOCK S3C_CLKREG(0x04) -#define S3C_EPLL_LOCK S3C_CLKREG(0x08) -#define S3C_APLL_CON S3C_CLKREG(0x0C) -#define S3C_MPLL_CON S3C_CLKREG(0x10) -#define S3C_EPLL_CON0 S3C_CLKREG(0x14) -#define S3C_EPLL_CON1 S3C_CLKREG(0x18) -#define S3C_CLK_SRC S3C_CLKREG(0x1C) -#define S3C_CLK_DIV0 S3C_CLKREG(0x20) -#define S3C_CLK_DIV1 S3C_CLKREG(0x24) -#define S3C_CLK_DIV2 S3C_CLKREG(0x28) -#define S3C_CLK_OUT S3C_CLKREG(0x2C) -#define S3C_HCLK_GATE S3C_CLKREG(0x30) #define S3C_PCLK_GATE S3C_CLKREG(0x34) -#define S3C_SCLK_GATE S3C_CLKREG(0x38) -#define S3C_MEM0_GATE S3C_CLKREG(0x3C) #define S3C6410_CLK_SRC2 S3C_CLKREG(0x10C) #define S3C_MEM_SYS_CFG S3C_CLKREG(0x120) -/* CLKDIV0 */ -#define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12) -#define S3C6400_CLKDIV0_PCLK_SHIFT (12) -#define S3C6400_CLKDIV0_HCLK2_MASK (0x7 << 9) -#define S3C6400_CLKDIV0_HCLK2_SHIFT (9) -#define S3C6400_CLKDIV0_HCLK_MASK (0x1 << 8) -#define S3C6400_CLKDIV0_HCLK_SHIFT (8) -#define S3C6400_CLKDIV0_MPLL_MASK (0x1 << 4) -#define S3C6400_CLKDIV0_MPLL_SHIFT (4) - -#define S3C6400_CLKDIV0_ARM_MASK (0x7 << 0) -#define S3C6410_CLKDIV0_ARM_MASK (0xf << 0) -#define S3C6400_CLKDIV0_ARM_SHIFT (0) - -/* HCLK GATE Registers */ -#define S3C_CLKCON_HCLK_3DSE (1<<31) -#define S3C_CLKCON_HCLK_UHOST (1<<29) -#define S3C_CLKCON_HCLK_SECUR (1<<28) -#define S3C_CLKCON_HCLK_SDMA1 (1<<27) -#define S3C_CLKCON_HCLK_SDMA0 (1<<26) -#define S3C_CLKCON_HCLK_IROM (1<<25) -#define S3C_CLKCON_HCLK_DDR1 (1<<24) -#define S3C_CLKCON_HCLK_DDR0 (1<<23) -#define S3C_CLKCON_HCLK_MEM1 (1<<22) -#define S3C_CLKCON_HCLK_MEM0 (1<<21) -#define S3C_CLKCON_HCLK_USB (1<<20) -#define S3C_CLKCON_HCLK_HSMMC2 (1<<19) -#define S3C_CLKCON_HCLK_HSMMC1 (1<<18) -#define S3C_CLKCON_HCLK_HSMMC0 (1<<17) -#define S3C_CLKCON_HCLK_MDP (1<<16) -#define S3C_CLKCON_HCLK_DHOST (1<<15) -#define S3C_CLKCON_HCLK_IHOST (1<<14) -#define S3C_CLKCON_HCLK_DMA1 (1<<13) -#define S3C_CLKCON_HCLK_DMA0 (1<<12) -#define S3C_CLKCON_HCLK_JPEG (1<<11) -#define S3C_CLKCON_HCLK_CAMIF (1<<10) -#define S3C_CLKCON_HCLK_SCALER (1<<9) -#define S3C_CLKCON_HCLK_2D (1<<8) -#define S3C_CLKCON_HCLK_TV (1<<7) -#define S3C_CLKCON_HCLK_POST0 (1<<5) -#define S3C_CLKCON_HCLK_ROT (1<<4) -#define S3C_CLKCON_HCLK_LCD (1<<3) -#define S3C_CLKCON_HCLK_TZIC (1<<2) -#define S3C_CLKCON_HCLK_INTC (1<<1) -#define S3C_CLKCON_HCLK_MFC (1<<0) - /* PCLK GATE Registers */ -#define S3C6410_CLKCON_PCLK_I2C1 (1<<27) -#define S3C6410_CLKCON_PCLK_IIS2 (1<<26) -#define S3C_CLKCON_PCLK_SKEY (1<<24) -#define S3C_CLKCON_PCLK_CHIPID (1<<23) -#define S3C_CLKCON_PCLK_SPI1 (1<<22) -#define S3C_CLKCON_PCLK_SPI0 (1<<21) -#define S3C_CLKCON_PCLK_HSIRX (1<<20) -#define S3C_CLKCON_PCLK_HSITX (1<<19) -#define S3C_CLKCON_PCLK_GPIO (1<<18) -#define S3C_CLKCON_PCLK_IIC (1<<17) -#define S3C_CLKCON_PCLK_IIS1 (1<<16) -#define S3C_CLKCON_PCLK_IIS0 (1<<15) -#define S3C_CLKCON_PCLK_AC97 (1<<14) -#define S3C_CLKCON_PCLK_TZPC (1<<13) -#define S3C_CLKCON_PCLK_TSADC (1<<12) -#define S3C_CLKCON_PCLK_KEYPAD (1<<11) -#define S3C_CLKCON_PCLK_IRDA (1<<10) -#define S3C_CLKCON_PCLK_PCM1 (1<<9) -#define S3C_CLKCON_PCLK_PCM0 (1<<8) -#define S3C_CLKCON_PCLK_PWM (1<<7) -#define S3C_CLKCON_PCLK_RTC (1<<6) -#define S3C_CLKCON_PCLK_WDT (1<<5) #define S3C_CLKCON_PCLK_UART3 (1<<4) #define S3C_CLKCON_PCLK_UART2 (1<<3) #define S3C_CLKCON_PCLK_UART1 (1<<2) #define S3C_CLKCON_PCLK_UART0 (1<<1) -#define S3C_CLKCON_PCLK_MFC (1<<0) - -/* SCLK GATE Registers */ -#define S3C_CLKCON_SCLK_UHOST (1<<30) -#define S3C_CLKCON_SCLK_MMC2_48 (1<<29) -#define S3C_CLKCON_SCLK_MMC1_48 (1<<28) -#define S3C_CLKCON_SCLK_MMC0_48 (1<<27) -#define S3C_CLKCON_SCLK_MMC2 (1<<26) -#define S3C_CLKCON_SCLK_MMC1 (1<<25) -#define S3C_CLKCON_SCLK_MMC0 (1<<24) -#define S3C_CLKCON_SCLK_SPI1_48 (1<<23) -#define S3C_CLKCON_SCLK_SPI0_48 (1<<22) -#define S3C_CLKCON_SCLK_SPI1 (1<<21) -#define S3C_CLKCON_SCLK_SPI0 (1<<20) -#define S3C_CLKCON_SCLK_DAC27 (1<<19) -#define S3C_CLKCON_SCLK_TV27 (1<<18) -#define S3C_CLKCON_SCLK_SCALER27 (1<<17) -#define S3C_CLKCON_SCLK_SCALER (1<<16) -#define S3C_CLKCON_SCLK_LCD27 (1<<15) -#define S3C_CLKCON_SCLK_LCD (1<<14) -#define S3C6400_CLKCON_SCLK_POST1_27 (1<<13) -#define S3C6410_CLKCON_FIMC (1<<13) -#define S3C_CLKCON_SCLK_POST0_27 (1<<12) -#define S3C6400_CLKCON_SCLK_POST1 (1<<11) -#define S3C6410_CLKCON_SCLK_AUDIO2 (1<<11) -#define S3C_CLKCON_SCLK_POST0 (1<<10) -#define S3C_CLKCON_SCLK_AUDIO1 (1<<9) -#define S3C_CLKCON_SCLK_AUDIO0 (1<<8) -#define S3C_CLKCON_SCLK_SECUR (1<<7) -#define S3C_CLKCON_SCLK_IRDA (1<<6) -#define S3C_CLKCON_SCLK_UART (1<<5) -#define S3C_CLKCON_SCLK_ONENAND (1<<4) -#define S3C_CLKCON_SCLK_MFC (1<<3) -#define S3C_CLKCON_SCLK_CAM (1<<2) -#define S3C_CLKCON_SCLK_JPEG (1<<1) - -/* CLKSRC */ - -#define S3C6400_CLKSRC_APLL_MOUT (1 << 0) -#define S3C6400_CLKSRC_MPLL_MOUT (1 << 1) -#define S3C6400_CLKSRC_EPLL_MOUT (1 << 2) -#define S3C6400_CLKSRC_APLL_MOUT_SHIFT (0) -#define S3C6400_CLKSRC_MPLL_MOUT_SHIFT (1) -#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT (2) -#define S3C6400_CLKSRC_MFC (1 << 4) /* MEM_SYS_CFG */ #define MEM_SYS_CFG_INDEP_CF 0x4000 diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-irq.h b/arch/arm/mach-s3c64xx/include/mach/regs-irq.h index bcce68a0bb7..6a1127891c8 100644 --- a/arch/arm/mach-s3c64xx/include/mach/regs-irq.h +++ b/arch/arm/mach-s3c64xx/include/mach/regs-irq.h @@ -15,6 +15,5 @@ #ifndef __ASM_ARCH_REGS_IRQ_H #define __ASM_ARCH_REGS_IRQ_H __FILE__ -#include <asm/hardware/vic.h> #endif /* __ASM_ARCH_6400_REGS_IRQ_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-sys.h b/arch/arm/mach-s3c64xx/include/mach/regs-sys.h deleted file mode 100644 index b91e0209328..00000000000 --- a/arch/arm/mach-s3c64xx/include/mach/regs-sys.h +++ /dev/null @@ -1,31 +0,0 @@ -/* arch/arm/plat-s3c64xx/include/plat/regs-sys.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C64XX system register definitions - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __PLAT_REGS_SYS_H -#define __PLAT_REGS_SYS_H __FILE__ - -#define S3C_SYSREG(x) (S3C_VA_SYS + (x)) - -#define S3C64XX_AHB_CON0 S3C_SYSREG(0x100) -#define S3C64XX_AHB_CON1 S3C_SYSREG(0x104) -#define S3C64XX_AHB_CON2 S3C_SYSREG(0x108) - -#define S3C64XX_SDMA_SEL S3C_SYSREG(0x110) - -#define S3C64XX_OTHERS S3C_SYSREG(0x900) - -#define S3C64XX_OTHERS_USBMASK (1 << 16) -#define S3C64XX_OTHERS_SYNCMUXSEL (1 << 6) - -#endif /* _PLAT_REGS_SYS_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h b/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h deleted file mode 100644 index 9d0c43b4b68..00000000000 --- a/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h +++ /dev/null @@ -1,18 +0,0 @@ -/* linux/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h - * - * Copyright (C) 2009 Samsung Electronics Ltd. - * Jaswinder Singh <jassi.brar@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __S3C64XX_PLAT_SPI_CLKS_H -#define __S3C64XX_PLAT_SPI_CLKS_H __FILE__ - -#define S3C64XX_SPI_SRCCLK_PCLK 0 -#define S3C64XX_SPI_SRCCLK_SPIBUS 1 -#define S3C64XX_SPI_SRCCLK_48M 2 - -#endif /* __S3C64XX_PLAT_SPI_CLKS_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/system.h b/arch/arm/mach-s3c64xx/include/mach/system.h deleted file mode 100644 index 353ed4389ae..00000000000 --- a/arch/arm/mach-s3c64xx/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* linux/arch/arm/mach-s3c6400/include/mach/system.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C6400 - system implementation - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H __FILE__ - -static void arch_idle(void) -{ - /* nothing here yet */ -} - -#endif /* __ASM_ARCH_IRQ_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/tick.h b/arch/arm/mach-s3c64xx/include/mach/tick.h deleted file mode 100644 index ebe18a9469b..00000000000 --- a/arch/arm/mach-s3c64xx/include/mach/tick.h +++ /dev/null @@ -1,29 +0,0 @@ -/* linux/arch/arm/mach-s3c6400/include/mach/tick.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * S3C64XX - Timer tick support definitions - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_TICK_H -#define __ASM_ARCH_TICK_H __FILE__ - -/* note, the timer interrutps turn up in 2 places, the vic and then - * the timer block. We take the VIC as the base at the moment. - */ -static inline u32 s3c24xx_ostimer_pending(void) -{ - u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS); - return pend & 1 << (IRQ_TIMER4_VIC - S3C64XX_IRQ_VIC0(0)); -} - -#define TICK_MAX (0xffffffff) - -#endif /* __ASM_ARCH_6400_TICK_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/timex.h b/arch/arm/mach-s3c64xx/include/mach/timex.h deleted file mode 100644 index fb2e8cd4082..00000000000 --- a/arch/arm/mach-s3c64xx/include/mach/timex.h +++ /dev/null @@ -1,24 +0,0 @@ -/* arch/arm/mach-s3c64xx/include/mach/timex.h - * - * Copyright (c) 2003-2005 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * S3C6400 - time parameters - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_TIMEX_H -#define __ASM_ARCH_TIMEX_H - -/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it - * a variable is useless. It seems as long as we make our timers an - * exact multiple of HZ, any value that makes a 1->1 correspondence - * for the time conversion functions to/from jiffies is acceptable. -*/ - -#define CLOCK_TICK_RATE 12000000 - -#endif /* __ASM_ARCH_TIMEX_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/uncompress.h b/arch/arm/mach-s3c64xx/include/mach/uncompress.h deleted file mode 100644 index c6a82a20bf2..00000000000 --- a/arch/arm/mach-s3c64xx/include/mach/uncompress.h +++ /dev/null @@ -1,28 +0,0 @@ -/* arch/arm/mach-s3c6400/include/mach/uncompress.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * S3C6400 - uncompress code - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_UNCOMPRESS_H -#define __ASM_ARCH_UNCOMPRESS_H - -#include <mach/map.h> -#include <plat/uncompress.h> - -static void arch_detect_cpu(void) -{ - /* we do not need to do any cpu detection here at the moment. */ - fifo_mask = S3C2440_UFSTAT_TXMASK; - fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT; -} - -#endif /* __ASM_ARCH_UNCOMPRESS_H */ diff --git a/arch/arm/mach-s3c64xx/irq-pm.c b/arch/arm/mach-s3c64xx/irq-pm.c index 8bec61e242c..ae4ea7601f6 100644 --- a/arch/arm/mach-s3c64xx/irq-pm.c +++ b/arch/arm/mach-s3c64xx/irq-pm.c @@ -12,17 +12,21 @@ * published by the Free Software Foundation. */ +/* + * NOTE: Code in this file is not used when booting with Device Tree support. + */ + #include <linux/kernel.h> #include <linux/syscore_ops.h> #include <linux/interrupt.h> #include <linux/serial_core.h> +#include <linux/serial_s3c.h> #include <linux/irq.h> #include <linux/io.h> +#include <linux/of.h> #include <mach/map.h> -#include <plat/regs-serial.h> -#include <plat/regs-timer.h> #include <mach/regs-gpio.h> #include <plat/cpu.h> #include <plat/pm.h> @@ -43,7 +47,6 @@ static struct sleep_save irq_save[] = { SAVE_ITEM(S3C64XX_EINT0FLTCON2), SAVE_ITEM(S3C64XX_EINT0FLTCON3), SAVE_ITEM(S3C64XX_EINT0MASK), - SAVE_ITEM(S3C64XX_TINT_CSTAT), }; static struct irq_grp_save { @@ -52,7 +55,13 @@ static struct irq_grp_save { u32 mask; } eint_grp_save[5]; -static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS]; +#ifndef CONFIG_SERIAL_SAMSUNG_UARTS +#define SERIAL_SAMSUNG_UARTS 0 +#else +#define SERIAL_SAMSUNG_UARTS CONFIG_SERIAL_SAMSUNG_UARTS +#endif + +static u32 irq_uart_mask[SERIAL_SAMSUNG_UARTS]; static int s3c64xx_irq_pm_suspend(void) { @@ -63,7 +72,7 @@ static int s3c64xx_irq_pm_suspend(void) s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); - for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++) + for (i = 0; i < SERIAL_SAMSUNG_UARTS; i++) irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM); for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) { @@ -84,7 +93,7 @@ static void s3c64xx_irq_pm_resume(void) s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); - for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++) + for (i = 0; i < SERIAL_SAMSUNG_UARTS; i++) __raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM); for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) { @@ -96,13 +105,17 @@ static void s3c64xx_irq_pm_resume(void) S3C_PMDBG("%s: IRQ configuration restored\n", __func__); } -struct syscore_ops s3c64xx_irq_syscore_ops = { +static struct syscore_ops s3c64xx_irq_syscore_ops = { .suspend = s3c64xx_irq_pm_suspend, .resume = s3c64xx_irq_pm_resume, }; static __init int s3c64xx_syscore_init(void) { + /* Appropriate drivers (pinctrl, uart) handle this when using DT. */ + if (of_have_populated_dt()) + return 0; + register_syscore_ops(&s3c64xx_irq_syscore_ops); return 0; diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c index b86f2779e4e..55eb6a69655 100644 --- a/arch/arm/mach-s3c64xx/mach-anw6410.c +++ b/arch/arm/mach-s3c64xx/mach-anw6410.c @@ -20,6 +20,7 @@ #include <linux/timer.h> #include <linux/init.h> #include <linux/serial_core.h> +#include <linux/serial_s3c.h> #include <linux/platform_device.h> #include <linux/io.h> #include <linux/i2c.h> @@ -29,8 +30,8 @@ #include <linux/dm9000.h> #include <video/platform_lcd.h> +#include <video/samsung_fimd.h> -#include <asm/hardware/vic.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> @@ -41,18 +42,18 @@ #include <asm/irq.h> #include <asm/mach-types.h> -#include <plat/regs-serial.h> -#include <plat/iic.h> +#include <linux/platform_data/i2c-s3c2410.h> #include <plat/fb.h> -#include <plat/regs-fb-v4.h> #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> #include <mach/regs-gpio.h> -#include <mach/regs-modem.h> +#include <mach/gpio-samsung.h> +#include <plat/samsung-time.h> #include "common.h" +#include "regs-modem.h" /* DM9000 */ #define ANW6410_PA_DM9000 (0x18000000) @@ -134,24 +135,27 @@ static struct platform_device anw6410_lcd_powerdev = { }; static struct s3c_fb_pd_win anw6410_fb_win0 = { - /* this is to ensure we use win0 */ - .win_mode = { - .left_margin = 8, - .right_margin = 13, - .upper_margin = 7, - .lower_margin = 5, - .hsync_len = 3, - .vsync_len = 1, - .xres = 800, - .yres = 480, - }, .max_bpp = 32, .default_bpp = 16, + .xres = 800, + .yres = 480, +}; + +static struct fb_videomode anw6410_lcd_timing = { + .left_margin = 8, + .right_margin = 13, + .upper_margin = 7, + .lower_margin = 5, + .hsync_len = 3, + .vsync_len = 1, + .xres = 800, + .yres = 480, }; /* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */ static struct s3c_fb_platdata anw6410_lcd_pdata __initdata = { .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, + .vtiming = &anw6410_lcd_timing, .win[0] = &anw6410_fb_win0, .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, @@ -165,21 +169,10 @@ static void __init anw6410_dm9000_enable(void) } static struct resource anw6410_dm9000_resource[] = { - [0] = { - .start = ANW6410_PA_DM9000, - .end = ANW6410_PA_DM9000 + 3, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = ANW6410_PA_DM9000 + 4, - .end = ANW6410_PA_DM9000 + 4 + 500, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = IRQ_EINT(15), - .end = IRQ_EINT(15), - .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH, - }, + [0] = DEFINE_RES_MEM(ANW6410_PA_DM9000, 4), + [1] = DEFINE_RES_MEM(ANW6410_PA_DM9000 + 4, 501), + [2] = DEFINE_RES_NAMED(IRQ_EINT(15), 1, NULL, IORESOURCE_IRQ \ + | IRQF_TRIGGER_HIGH), }; static struct dm9000_plat_data anw6410_dm9000_pdata = { @@ -215,8 +208,9 @@ static struct platform_device *anw6410_devices[] __initdata = { static void __init anw6410_map_io(void) { s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); anw6410_lcd_mode_set(); } @@ -238,9 +232,9 @@ MACHINE_START(ANW6410, "A&W6410") .atag_offset = 0x100, .init_irq = s3c6410_init_irq, - .handle_irq = vic_handle_irq, .map_io = anw6410_map_io, .init_machine = anw6410_machine_init, - .timer = &s3c24xx_timer, + .init_late = s3c64xx_init_late, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index cd3c97e2ee7..9c00d83f715 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -11,17 +11,60 @@ #include <linux/export.h> #include <linux/interrupt.h> #include <linux/i2c.h> +#include <linux/spi/spi.h> #include <linux/mfd/wm831x/irq.h> #include <linux/mfd/wm831x/gpio.h> #include <linux/mfd/wm8994/pdata.h> +#include <linux/mfd/arizona/pdata.h> +#include <linux/regulator/machine.h> + +#include <sound/wm0010.h> +#include <sound/wm2200.h> #include <sound/wm5100.h> #include <sound/wm8996.h> #include <sound/wm8962.h> #include <sound/wm9081.h> -#include <mach/crag6410.h> +#include <linux/platform_data/spi-s3c64xx.h> + +#include "crag6410.h" + +static struct s3c64xx_spi_csinfo wm0010_spi_csinfo = { + .line = S3C64XX_GPC(3), +}; + +static struct wm0010_pdata wm0010_pdata = { + .gpio_reset = S3C64XX_GPN(6), + .reset_active_high = 1, /* Active high for Glenfarclas Rev 2 */ +}; + +static struct spi_board_info wm1253_devs[] = { + [0] = { + .modalias = "wm0010", + .max_speed_hz = 26 * 1000 * 1000, + .bus_num = 0, + .chip_select = 0, + .mode = SPI_MODE_0, + .irq = S3C_EINT(4), + .controller_data = &wm0010_spi_csinfo, + .platform_data = &wm0010_pdata, + }, +}; + +static struct spi_board_info balblair_devs[] = { + [0] = { + .modalias = "wm0010", + .max_speed_hz = 26 * 1000 * 1000, + .bus_num = 0, + .chip_select = 0, + .mode = SPI_MODE_0, + .irq = S3C_EINT(4), + .controller_data = &wm0010_spi_csinfo, + .platform_data = &wm0010_pdata, + }, +}; static struct wm5100_pdata wm5100_pdata = { .ldo_ena = S3C64XX_GPN(7), @@ -102,6 +145,7 @@ static struct wm8962_pdata wm8962_pdata __initdata = { 0x8000 | WM8962_GPIO_FN_DMICDAT, WM8962_GPIO_FN_IRQ, /* Open drain mode */ }, + .in4_dc_measure = true, }; static struct wm9081_pdata wm9081_pdata __initdata = { @@ -134,15 +178,23 @@ static const struct i2c_board_info wm1259_devs[] = { }, }; +static struct regulator_init_data wm8994_ldo1 = { + .supply_regulator = "WALLVDD", +}; + +static struct regulator_init_data wm8994_ldo2 = { + .supply_regulator = "WALLVDD", +}; + static struct wm8994_pdata wm8994_pdata = { .gpio_base = CODEC_GPIO_BASE, + .micb2_delay = 150, .gpio_defaults = { 0x3, /* IRQ out, active high, CMOS */ }, - .irq_base = CODEC_IRQ_BASE, .ldo = { - { .supply = "WALLVDD" }, - { .supply = "WALLVDD" }, + { .enable = S3C64XX_GPN(6), .init_data = &wm8994_ldo1, }, + { .enable = S3C64XX_GPN(4), .init_data = &wm8994_ldo2, }, }, }; @@ -153,32 +205,147 @@ static const struct i2c_board_info wm1277_devs[] = { }, }; -static __devinitdata const struct { +static struct arizona_pdata wm5102_reva_pdata = { + .ldoena = S3C64XX_GPN(7), + .gpio_base = CODEC_GPIO_BASE, + .irq_flags = IRQF_TRIGGER_HIGH, + .micd_pol_gpio = CODEC_GPIO_BASE + 4, + .micd_rate = 6, + .gpio_defaults = { + [2] = 0x10000, /* AIF3TXLRCLK */ + [3] = 0x4, /* OPCLK */ + }, +}; + +static struct s3c64xx_spi_csinfo codec_spi_csinfo = { + .line = S3C64XX_GPN(5), +}; + +static struct spi_board_info wm5102_reva_spi_devs[] = { + [0] = { + .modalias = "wm5102", + .max_speed_hz = 10 * 1000 * 1000, + .bus_num = 0, + .chip_select = 1, + .mode = SPI_MODE_0, + .irq = GLENFARCLAS_PMIC_IRQ_BASE + + WM831X_IRQ_GPIO_2, + .controller_data = &codec_spi_csinfo, + .platform_data = &wm5102_reva_pdata, + }, +}; + +static struct arizona_pdata wm5102_pdata = { + .ldoena = S3C64XX_GPN(7), + .gpio_base = CODEC_GPIO_BASE, + .irq_flags = IRQF_TRIGGER_HIGH, + .micd_pol_gpio = CODEC_GPIO_BASE + 2, + .gpio_defaults = { + [2] = 0x10000, /* AIF3TXLRCLK */ + [3] = 0x4, /* OPCLK */ + }, +}; + +static struct spi_board_info wm5102_spi_devs[] = { + [0] = { + .modalias = "wm5102", + .max_speed_hz = 10 * 1000 * 1000, + .bus_num = 0, + .chip_select = 1, + .mode = SPI_MODE_0, + .irq = GLENFARCLAS_PMIC_IRQ_BASE + + WM831X_IRQ_GPIO_2, + .controller_data = &codec_spi_csinfo, + .platform_data = &wm5102_pdata, + }, +}; + +static struct spi_board_info wm5110_spi_devs[] = { + [0] = { + .modalias = "wm5110", + .max_speed_hz = 10 * 1000 * 1000, + .bus_num = 0, + .chip_select = 1, + .mode = SPI_MODE_0, + .irq = GLENFARCLAS_PMIC_IRQ_BASE + + WM831X_IRQ_GPIO_2, + .controller_data = &codec_spi_csinfo, + .platform_data = &wm5102_reva_pdata, + }, +}; + +static const struct i2c_board_info wm6230_i2c_devs[] = { + { I2C_BOARD_INFO("wm9081", 0x6c), + .platform_data = &wm9081_pdata, }, +}; + +static struct wm2200_pdata wm2200_pdata = { + .ldo_ena = S3C64XX_GPN(7), + .gpio_defaults = { + [2] = 0x0005, /* GPIO3 24.576MHz output clock */ + }, +}; + +static const struct i2c_board_info wm2200_i2c[] = { + { I2C_BOARD_INFO("wm2200", 0x3a), + .platform_data = &wm2200_pdata, }, +}; + +static const struct { u8 id; + u8 rev; const char *name; const struct i2c_board_info *i2c_devs; int num_i2c_devs; + const struct spi_board_info *spi_devs; + int num_spi_devs; } gf_mods[] = { - { .id = 0x01, .name = "1250-EV1 Springbank" }, - { .id = 0x02, .name = "1251-EV1 Jura" }, - { .id = 0x03, .name = "1252-EV1 Glenlivet" }, - { .id = 0x11, .name = "6249-EV2 Glenfarclas", }, - { .id = 0x21, .name = "1275-EV1 Mortlach" }, - { .id = 0x25, .name = "1274-EV1 Glencadam" }, - { .id = 0x31, .name = "1253-EV1 Tomatin", }, - { .id = 0x39, .name = "1254-EV1 Dallas Dhu", + { .id = 0x01, .rev = 0xff, .name = "1250-EV1 Springbank" }, + { .id = 0x02, .rev = 0xff, .name = "1251-EV1 Jura" }, + { .id = 0x03, .rev = 0xff, .name = "1252-EV1 Glenlivet" }, + { .id = 0x06, .rev = 0xff, .name = "WM8997-6721-CS96-EV1 Lapraoig" }, + { .id = 0x07, .rev = 0xff, .name = "WM5110-6271 Deanston", + .spi_devs = wm5110_spi_devs, + .num_spi_devs = ARRAY_SIZE(wm5110_spi_devs) }, + { .id = 0x08, .rev = 0xff, .name = "WM8903-6102 Tamdhu" }, + { .id = 0x09, .rev = 0xff, .name = "WM1811A-6305 Adelphi" }, + { .id = 0x0a, .rev = 0xff, .name = "WM8996-6272 Blackadder" }, + { .id = 0x0b, .rev = 0xff, .name = "WM8994-6235 Benromach" }, + { .id = 0x11, .rev = 0xff, .name = "6249-EV2 Glenfarclas", }, + { .id = 0x14, .rev = 0xff, .name = "6271-EV1 Lochnagar" }, + { .id = 0x15, .rev = 0xff, .name = "6320-EV1 Bells", + .i2c_devs = wm6230_i2c_devs, + .num_i2c_devs = ARRAY_SIZE(wm6230_i2c_devs) }, + { .id = 0x21, .rev = 0xff, .name = "1275-EV1 Mortlach" }, + { .id = 0x25, .rev = 0xff, .name = "1274-EV1 Glencadam" }, + { .id = 0x31, .rev = 0xff, .name = "1253-EV1 Tomatin", + .spi_devs = wm1253_devs, .num_spi_devs = ARRAY_SIZE(wm1253_devs) }, + { .id = 0x32, .rev = 0xff, .name = "XXXX-EV1 Caol Illa" }, + { .id = 0x33, .rev = 0xff, .name = "XXXX-EV1 Oban" }, + { .id = 0x34, .rev = 0xff, .name = "WM0010-6320-CS42 Balblair", + .spi_devs = balblair_devs, + .num_spi_devs = ARRAY_SIZE(balblair_devs) }, + { .id = 0x39, .rev = 0xff, .name = "1254-EV1 Dallas Dhu", .i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs) }, - { .id = 0x3a, .name = "1259-EV1 Tobermory", + { .id = 0x3a, .rev = 0xff, .name = "1259-EV1 Tobermory", .i2c_devs = wm1259_devs, .num_i2c_devs = ARRAY_SIZE(wm1259_devs) }, - { .id = 0x3b, .name = "1255-EV1 Kilchoman", + { .id = 0x3b, .rev = 0xff, .name = "1255-EV1 Kilchoman", .i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs) }, - { .id = 0x3c, .name = "1273-EV1 Longmorn" }, - { .id = 0x3d, .name = "1277-EV1 Littlemill", + { .id = 0x3c, .rev = 0xff, .name = "1273-EV1 Longmorn" }, + { .id = 0x3d, .rev = 0xff, .name = "1277-EV1 Littlemill", .i2c_devs = wm1277_devs, .num_i2c_devs = ARRAY_SIZE(wm1277_devs) }, + { .id = 0x3e, .rev = 0, .name = "WM5102-6271-EV1-CS127 Amrut", + .spi_devs = wm5102_reva_spi_devs, + .num_spi_devs = ARRAY_SIZE(wm5102_reva_spi_devs) }, + { .id = 0x3e, .rev = -1, .name = "WM5102-6271-EV1-CS127 Amrut", + .spi_devs = wm5102_spi_devs, + .num_spi_devs = ARRAY_SIZE(wm5102_spi_devs) }, + { .id = 0x3f, .rev = -1, .name = "WM2200-6271-CS90-M-REV1", + .i2c_devs = wm2200_i2c, .num_i2c_devs = ARRAY_SIZE(wm2200_i2c) }, }; -static __devinit int wlf_gf_module_probe(struct i2c_client *i2c, - const struct i2c_device_id *i2c_id) +static int wlf_gf_module_probe(struct i2c_client *i2c, + const struct i2c_device_id *i2c_id) { int ret, i, j, id, rev; @@ -191,18 +358,23 @@ static __devinit int wlf_gf_module_probe(struct i2c_client *i2c, id = (ret & 0xfe) >> 2; rev = ret & 0x3; for (i = 0; i < ARRAY_SIZE(gf_mods); i++) - if (id == gf_mods[i].id) + if (id == gf_mods[i].id && (gf_mods[i].rev == 0xff || + rev == gf_mods[i].rev)) break; if (i < ARRAY_SIZE(gf_mods)) { dev_info(&i2c->dev, "%s revision %d\n", gf_mods[i].name, rev + 1); + for (j = 0; j < gf_mods[i].num_i2c_devs; j++) { if (!i2c_new_device(i2c->adapter, &(gf_mods[i].i2c_devs[j]))) dev_err(&i2c->dev, "Failed to register dev: %d\n", ret); } + + spi_register_board_info(gf_mods[i].spi_devs, + gf_mods[i].num_spi_devs); } else { dev_warn(&i2c->dev, "Unknown module ID 0x%x revision %d\n", id, rev + 1); @@ -229,4 +401,4 @@ static int __init wlf_gf_module_register(void) { return i2c_add_driver(&wlf_gf_module_driver); } -module_init(wlf_gf_module_register); +device_initcall(wlf_gf_module_register); diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index 8077f650eb0..4b0199fff9f 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -14,12 +14,15 @@ #include <linux/kernel.h> #include <linux/list.h> #include <linux/serial_core.h> +#include <linux/serial_s3c.h> #include <linux/platform_device.h> #include <linux/fb.h> #include <linux/io.h> #include <linux/init.h> #include <linux/gpio.h> +#include <linux/leds.h> #include <linux/delay.h> +#include <linux/mmc/host.h> #include <linux/regulator/machine.h> #include <linux/regulator/fixed.h> #include <linux/pwm_backlight.h> @@ -28,7 +31,8 @@ #include <linux/basic_mmio_gpio.h> #include <linux/spi/spi.h> -#include <linux/i2c/pca953x.h> +#include <linux/platform_data/pca953x.h> +#include <linux/platform_data/s3c-hsotg.h> #include <video/platform_lcd.h> @@ -39,36 +43,34 @@ #include <sound/wm1250-ev1.h> -#include <asm/hardware/vic.h> #include <asm/mach/arch.h> #include <asm/mach-types.h> +#include <video/samsung_fimd.h> #include <mach/hardware.h> #include <mach/map.h> - -#include <mach/regs-sys.h> #include <mach/regs-gpio.h> -#include <mach/regs-modem.h> -#include <mach/crag6410.h> - -#include <mach/regs-gpio-memport.h> +#include <mach/gpio-samsung.h> -#include <plat/regs-serial.h> -#include <plat/regs-fb-v4.h> #include <plat/fb.h> #include <plat/sdhci.h> #include <plat/gpio-cfg.h> -#include <plat/s3c64xx-spi.h> +#include <linux/platform_data/spi-s3c64xx.h> #include <plat/keypad.h> #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> #include <plat/adc.h> -#include <plat/iic.h> +#include <linux/platform_data/i2c-s3c2410.h> #include <plat/pm.h> +#include <plat/samsung-time.h> #include "common.h" +#include "crag6410.h" +#include "regs-gpio-memport.h" +#include "regs-modem.h" +#include "regs-sys.h" /* serial port setup */ @@ -112,13 +114,14 @@ static struct platform_pwm_backlight_data crag6410_backlight_data = { .max_brightness = 1000, .dft_brightness = 600, .pwm_period_ns = 100000, /* about 1kHz */ + .enable_gpio = -1, }; static struct platform_device crag6410_backlight_device = { .name = "pwm-backlight", .id = -1, .dev = { - .parent = &s3c_device_timer[0].dev, + .parent = &samsung_device_pwm.dev, .platform_data = &crag6410_backlight_data, }, }; @@ -148,26 +151,29 @@ static struct platform_device crag6410_lcd_powerdev = { /* 640x480 URT */ static struct s3c_fb_pd_win crag6410_fb_win0 = { - /* this is to ensure we use win0 */ - .win_mode = { - .left_margin = 150, - .right_margin = 80, - .upper_margin = 40, - .lower_margin = 5, - .hsync_len = 40, - .vsync_len = 5, - .xres = 640, - .yres = 480, - }, .max_bpp = 32, .default_bpp = 16, + .xres = 640, + .yres = 480, .virtual_y = 480 * 2, .virtual_x = 640, }; +static struct fb_videomode crag6410_lcd_timing = { + .left_margin = 150, + .right_margin = 80, + .upper_margin = 40, + .lower_margin = 5, + .hsync_len = 40, + .vsync_len = 5, + .xres = 640, + .yres = 480, +}; + /* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */ -static struct s3c_fb_platdata crag6410_lcd_pdata __initdata = { +static struct s3c_fb_platdata crag6410_lcd_pdata = { .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, + .vtiming = &crag6410_lcd_timing, .win[0] = &crag6410_fb_win0, .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, @@ -175,7 +181,7 @@ static struct s3c_fb_platdata crag6410_lcd_pdata __initdata = { /* 2x6 keypad */ -static uint32_t crag6410_keymap[] __initdata = { +static uint32_t crag6410_keymap[] = { /* KEY(row, col, keycode) */ KEY(0, 0, KEY_VOLUMEUP), KEY(0, 1, KEY_HOME), @@ -191,12 +197,12 @@ static uint32_t crag6410_keymap[] __initdata = { KEY(1, 5, KEY_CAMERA), }; -static struct matrix_keymap_data crag6410_keymap_data __initdata = { +static struct matrix_keymap_data crag6410_keymap_data = { .keymap = crag6410_keymap, .keymap_size = ARRAY_SIZE(crag6410_keymap), }; -static struct samsung_keypad_platdata crag6410_keypad_data __initdata = { +static struct samsung_keypad_platdata crag6410_keypad_data = { .keymap_data = &crag6410_keymap_data, .rows = 2, .cols = 6, @@ -229,21 +235,10 @@ static struct platform_device crag6410_gpio_keydev = { }; static struct resource crag6410_dm9k_resource[] = { - [0] = { - .start = S3C64XX_PA_XM0CSN5, - .end = S3C64XX_PA_XM0CSN5 + 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = S3C64XX_PA_XM0CSN5 + (1 << 8), - .end = S3C64XX_PA_XM0CSN5 + (1 << 8) + 1, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = S3C_EINT(17), - .end = S3C_EINT(17), - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, + [0] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN5, 2), + [1] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN5 + (1 << 8), 2), + [2] = DEFINE_RES_NAMED(S3C_EINT(17), 1, NULL, IORESOURCE_IRQ \ + | IORESOURCE_IRQ_HIGHLEVEL), }; static struct dm9000_plat_data mini6410_dm9k_pdata = { @@ -259,12 +254,7 @@ static struct platform_device crag6410_dm9k_device = { }; static struct resource crag6410_mmgpio_resource[] = { - [0] = { - .name = "dat", - .start = S3C64XX_PA_XM0CSN4 + 1, - .end = S3C64XX_PA_XM0CSN4 + 1, - .flags = IORESOURCE_MEM, - }, + [0] = DEFINE_RES_MEM_NAMED(S3C64XX_PA_XM0CSN4, 1, "dat"), }; static struct platform_device crag6410_mmgpio = { @@ -297,11 +287,58 @@ static struct platform_device littlemill_device = { .id = -1, }; +static struct platform_device bells_wm2200_device = { + .name = "bells", + .id = 0, +}; + +static struct platform_device bells_wm5102_device = { + .name = "bells", + .id = 1, +}; + +static struct platform_device bells_wm5110_device = { + .name = "bells", + .id = 2, +}; + static struct regulator_consumer_supply wallvdd_consumers[] = { + REGULATOR_SUPPLY("SPKVDD", "1-001a"), REGULATOR_SUPPLY("SPKVDD1", "1-001a"), REGULATOR_SUPPLY("SPKVDD2", "1-001a"), REGULATOR_SUPPLY("SPKVDDL", "1-001a"), REGULATOR_SUPPLY("SPKVDDR", "1-001a"), + + REGULATOR_SUPPLY("SPKVDDL", "spi0.1"), + REGULATOR_SUPPLY("SPKVDDR", "spi0.1"), + + REGULATOR_SUPPLY("DC1VDD", "0-0034"), + REGULATOR_SUPPLY("DC2VDD", "0-0034"), + REGULATOR_SUPPLY("DC3VDD", "0-0034"), + REGULATOR_SUPPLY("LDO1VDD", "0-0034"), + REGULATOR_SUPPLY("LDO2VDD", "0-0034"), + REGULATOR_SUPPLY("LDO4VDD", "0-0034"), + REGULATOR_SUPPLY("LDO5VDD", "0-0034"), + REGULATOR_SUPPLY("LDO6VDD", "0-0034"), + REGULATOR_SUPPLY("LDO7VDD", "0-0034"), + REGULATOR_SUPPLY("LDO8VDD", "0-0034"), + REGULATOR_SUPPLY("LDO9VDD", "0-0034"), + REGULATOR_SUPPLY("LDO10VDD", "0-0034"), + REGULATOR_SUPPLY("LDO11VDD", "0-0034"), + + REGULATOR_SUPPLY("DC1VDD", "1-0034"), + REGULATOR_SUPPLY("DC2VDD", "1-0034"), + REGULATOR_SUPPLY("DC3VDD", "1-0034"), + REGULATOR_SUPPLY("LDO1VDD", "1-0034"), + REGULATOR_SUPPLY("LDO2VDD", "1-0034"), + REGULATOR_SUPPLY("LDO4VDD", "1-0034"), + REGULATOR_SUPPLY("LDO5VDD", "1-0034"), + REGULATOR_SUPPLY("LDO6VDD", "1-0034"), + REGULATOR_SUPPLY("LDO7VDD", "1-0034"), + REGULATOR_SUPPLY("LDO8VDD", "1-0034"), + REGULATOR_SUPPLY("LDO9VDD", "1-0034"), + REGULATOR_SUPPLY("LDO10VDD", "1-0034"), + REGULATOR_SUPPLY("LDO11VDD", "1-0034"), }; static struct regulator_init_data wallvdd_data = { @@ -335,10 +372,9 @@ static struct platform_device *crag6410_devices[] __initdata = { &s3c_device_fb, &s3c_device_ohci, &s3c_device_usb_hsotg, - &s3c_device_timer[0], + &samsung_device_pwm, &s3c64xx_device_iis0, &s3c64xx_device_iis1, - &samsung_asoc_dma, &samsung_device_keypad, &crag6410_gpio_keydev, &crag6410_dm9k_device, @@ -350,6 +386,9 @@ static struct platform_device *crag6410_devices[] __initdata = { &tobermory_device, &littlemill_device, &lowland_device, + &bells_wm2200_device, + &bells_wm5102_device, + &bells_wm5110_device, &wallvdd_device, }; @@ -364,11 +403,11 @@ static struct wm831x_buckv_pdata vddarm_pdata = { .dvs_gpio = S3C64XX_GPK(0), }; -static struct regulator_consumer_supply vddarm_consumers[] __initdata = { +static struct regulator_consumer_supply vddarm_consumers[] = { REGULATOR_SUPPLY("vddarm", NULL), }; -static struct regulator_init_data vddarm __initdata = { +static struct regulator_init_data vddarm = { .constraints = { .name = "VDDARM", .min_uV = 1000000, @@ -382,11 +421,11 @@ static struct regulator_init_data vddarm __initdata = { .driver_data = &vddarm_pdata, }; -static struct regulator_consumer_supply vddint_consumers[] __initdata = { +static struct regulator_consumer_supply vddint_consumers[] = { REGULATOR_SUPPLY("vddint", NULL), }; -static struct regulator_init_data vddint __initdata = { +static struct regulator_init_data vddint = { .constraints = { .name = "VDDINT", .min_uV = 1000000, @@ -399,27 +438,27 @@ static struct regulator_init_data vddint __initdata = { .supply_regulator = "WALLVDD", }; -static struct regulator_init_data vddmem __initdata = { +static struct regulator_init_data vddmem = { .constraints = { .name = "VDDMEM", .always_on = 1, }, }; -static struct regulator_init_data vddsys __initdata = { +static struct regulator_init_data vddsys = { .constraints = { .name = "VDDSYS,VDDEXT,VDDPCM,VDDSS", .always_on = 1, }, }; -static struct regulator_consumer_supply vddmmc_consumers[] __initdata = { +static struct regulator_consumer_supply vddmmc_consumers[] = { REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"), REGULATOR_SUPPLY("vmmc", "s3c-sdhci.1"), REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"), }; -static struct regulator_init_data vddmmc __initdata = { +static struct regulator_init_data vddmmc = { .constraints = { .name = "VDDMMC,UH", .always_on = 1, @@ -429,7 +468,7 @@ static struct regulator_init_data vddmmc __initdata = { .supply_regulator = "WALLVDD", }; -static struct regulator_init_data vddotgi __initdata = { +static struct regulator_init_data vddotgi = { .constraints = { .name = "VDDOTGi", .always_on = 1, @@ -437,7 +476,7 @@ static struct regulator_init_data vddotgi __initdata = { .supply_regulator = "WALLVDD", }; -static struct regulator_init_data vddotg __initdata = { +static struct regulator_init_data vddotg = { .constraints = { .name = "VDDOTG", .always_on = 1, @@ -445,7 +484,7 @@ static struct regulator_init_data vddotg __initdata = { .supply_regulator = "WALLVDD", }; -static struct regulator_init_data vddhi __initdata = { +static struct regulator_init_data vddhi = { .constraints = { .name = "VDDHI", .always_on = 1, @@ -453,7 +492,7 @@ static struct regulator_init_data vddhi __initdata = { .supply_regulator = "WALLVDD", }; -static struct regulator_init_data vddadc __initdata = { +static struct regulator_init_data vddadc = { .constraints = { .name = "VDDADC,VDDDAC", .always_on = 1, @@ -461,7 +500,7 @@ static struct regulator_init_data vddadc __initdata = { .supply_regulator = "WALLVDD", }; -static struct regulator_init_data vddmem0 __initdata = { +static struct regulator_init_data vddmem0 = { .constraints = { .name = "VDDMEM0", .always_on = 1, @@ -469,7 +508,7 @@ static struct regulator_init_data vddmem0 __initdata = { .supply_regulator = "WALLVDD", }; -static struct regulator_init_data vddpll __initdata = { +static struct regulator_init_data vddpll = { .constraints = { .name = "VDDPLL", .always_on = 1, @@ -477,7 +516,7 @@ static struct regulator_init_data vddpll __initdata = { .supply_regulator = "WALLVDD", }; -static struct regulator_init_data vddlcd __initdata = { +static struct regulator_init_data vddlcd = { .constraints = { .name = "VDDLCD", .always_on = 1, @@ -485,7 +524,7 @@ static struct regulator_init_data vddlcd __initdata = { .supply_regulator = "WALLVDD", }; -static struct regulator_init_data vddalive __initdata = { +static struct regulator_init_data vddalive = { .constraints = { .name = "VDDALIVE", .always_on = 1, @@ -493,30 +532,29 @@ static struct regulator_init_data vddalive __initdata = { .supply_regulator = "WALLVDD", }; -static struct wm831x_backup_pdata banff_backup_pdata __initdata = { +static struct wm831x_backup_pdata banff_backup_pdata = { .charger_enable = 1, .vlim = 2500, /* mV */ .ilim = 200, /* uA */ }; -static struct wm831x_status_pdata banff_red_led __initdata = { +static struct wm831x_status_pdata banff_red_led = { .name = "banff:red:", .default_src = WM831X_STATUS_MANUAL, }; -static struct wm831x_status_pdata banff_green_led __initdata = { +static struct wm831x_status_pdata banff_green_led = { .name = "banff:green:", .default_src = WM831X_STATUS_MANUAL, }; -static struct wm831x_touch_pdata touch_pdata __initdata = { +static struct wm831x_touch_pdata touch_pdata = { .data_irq = S3C_EINT(26), .pd_irq = S3C_EINT(27), }; -static struct wm831x_pdata crag_pmic_pdata __initdata = { +static struct wm831x_pdata crag_pmic_pdata = { .wm831x_num = 1, - .irq_base = BANFF_PMIC_IRQ_BASE, .gpio_base = BANFF_PMIC_GPIO_BASE, .soft_shutdown = true, @@ -559,7 +597,7 @@ static struct wm831x_pdata crag_pmic_pdata __initdata = { .touch = &touch_pdata, }; -static struct i2c_board_info i2c_devs0[] __initdata = { +static struct i2c_board_info i2c_devs0[] = { { I2C_BOARD_INFO("24c08", 0x50), }, { I2C_BOARD_INFO("tca6408", 0x20), .platform_data = &crag6410_pca_data, @@ -574,14 +612,23 @@ static struct s3c2410_platform_i2c i2c0_pdata = { .frequency = 400000, }; -static struct regulator_init_data pvdd_1v2 __initdata = { +static struct regulator_consumer_supply pvdd_1v2_consumers[] = { + REGULATOR_SUPPLY("DCVDD", "spi0.0"), + REGULATOR_SUPPLY("AVDD", "spi0.0"), + REGULATOR_SUPPLY("AVDD", "spi0.1"), +}; + +static struct regulator_init_data pvdd_1v2 = { .constraints = { .name = "PVDD_1V2", - .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, }, + + .consumer_supplies = pvdd_1v2_consumers, + .num_consumer_supplies = ARRAY_SIZE(pvdd_1v2_consumers), }; -static struct regulator_consumer_supply pvdd_1v8_consumers[] __initdata = { +static struct regulator_consumer_supply pvdd_1v8_consumers[] = { REGULATOR_SUPPLY("LDOVDD", "1-001a"), REGULATOR_SUPPLY("PLLVDD", "1-001a"), REGULATOR_SUPPLY("DBVDD", "1-001a"), @@ -592,9 +639,20 @@ static struct regulator_consumer_supply pvdd_1v8_consumers[] __initdata = { REGULATOR_SUPPLY("AVDD2", "1-001a"), REGULATOR_SUPPLY("DCVDD", "1-001a"), REGULATOR_SUPPLY("AVDD", "1-001a"), + REGULATOR_SUPPLY("DBVDD", "spi0.0"), + + REGULATOR_SUPPLY("DBVDD", "1-003a"), + REGULATOR_SUPPLY("LDOVDD", "1-003a"), + REGULATOR_SUPPLY("CPVDD", "1-003a"), + REGULATOR_SUPPLY("AVDD", "1-003a"), + REGULATOR_SUPPLY("DBVDD1", "spi0.1"), + REGULATOR_SUPPLY("DBVDD2", "spi0.1"), + REGULATOR_SUPPLY("DBVDD3", "spi0.1"), + REGULATOR_SUPPLY("LDOVDD", "spi0.1"), + REGULATOR_SUPPLY("CPVDD", "spi0.1"), }; -static struct regulator_init_data pvdd_1v8 __initdata = { +static struct regulator_init_data pvdd_1v8 = { .constraints = { .name = "PVDD_1V8", .always_on = 1, @@ -604,12 +662,12 @@ static struct regulator_init_data pvdd_1v8 __initdata = { .num_consumer_supplies = ARRAY_SIZE(pvdd_1v8_consumers), }; -static struct regulator_consumer_supply pvdd_3v3_consumers[] __initdata = { +static struct regulator_consumer_supply pvdd_3v3_consumers[] = { REGULATOR_SUPPLY("MICVDD", "1-001a"), REGULATOR_SUPPLY("AVDD1", "1-001a"), }; -static struct regulator_init_data pvdd_3v3 __initdata = { +static struct regulator_init_data pvdd_3v3 = { .constraints = { .name = "PVDD_3V3", .always_on = 1, @@ -619,7 +677,7 @@ static struct regulator_init_data pvdd_3v3 __initdata = { .num_consumer_supplies = ARRAY_SIZE(pvdd_3v3_consumers), }; -static struct wm831x_pdata glenfarclas_pmic_pdata __initdata = { +static struct wm831x_pdata glenfarclas_pmic_pdata = { .wm831x_num = 2, .irq_base = GLENFARCLAS_PMIC_IRQ_BASE, .gpio_base = GLENFARCLAS_PMIC_GPIO_BASE, @@ -651,11 +709,13 @@ static struct wm1250_ev1_pdata wm1250_ev1_pdata = { }, }; -static struct i2c_board_info i2c_devs1[] __initdata = { +static struct i2c_board_info i2c_devs1[] = { { I2C_BOARD_INFO("wm8311", 0x34), .irq = S3C_EINT(0), .platform_data = &glenfarclas_pmic_pdata }, + { I2C_BOARD_INFO("wlf-gf-module", 0x20) }, + { I2C_BOARD_INFO("wlf-gf-module", 0x22) }, { I2C_BOARD_INFO("wlf-gf-module", 0x24) }, { I2C_BOARD_INFO("wlf-gf-module", 0x25) }, { I2C_BOARD_INFO("wlf-gf-module", 0x26) }, @@ -672,8 +732,9 @@ static struct s3c2410_platform_i2c i2c1_pdata = { static void __init crag6410_map_io(void) { s3c64xx_init_io(NULL, 0); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(crag6410_uartcfgs, ARRAY_SIZE(crag6410_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); /* LCD type and Bypass set by bootloader */ } @@ -681,6 +742,7 @@ static void __init crag6410_map_io(void) static struct s3c_sdhci_platdata crag6410_hsmmc2_pdata = { .max_width = 4, .cd_type = S3C_SDHCI_CD_PERMANENT, + .host_caps = MMC_CAP_POWER_OFF_CARD, }; static void crag6410_cfg_sdhci0(struct platform_device *dev, int width) @@ -696,8 +758,59 @@ static struct s3c_sdhci_platdata crag6410_hsmmc0_pdata = { .max_width = 4, .cd_type = S3C_SDHCI_CD_INTERNAL, .cfg_gpio = crag6410_cfg_sdhci0, + .host_caps = MMC_CAP_POWER_OFF_CARD, +}; + +static const struct gpio_led gpio_leds[] = { + { + .name = "d13:green:", + .gpio = MMGPIO_GPIO_BASE + 0, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "d14:green:", + .gpio = MMGPIO_GPIO_BASE + 1, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "d15:green:", + .gpio = MMGPIO_GPIO_BASE + 2, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "d16:green:", + .gpio = MMGPIO_GPIO_BASE + 3, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "d17:green:", + .gpio = MMGPIO_GPIO_BASE + 4, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "d18:green:", + .gpio = MMGPIO_GPIO_BASE + 5, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "d19:green:", + .gpio = MMGPIO_GPIO_BASE + 6, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "d20:green:", + .gpio = MMGPIO_GPIO_BASE + 7, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, +}; + +static const struct gpio_led_platform_data gpio_leds_pdata = { + .leds = gpio_leds, + .num_leds = ARRAY_SIZE(gpio_leds), }; +static struct s3c_hsotg_plat crag6410_hsotg_pdata; + static void __init crag6410_machine_init(void) { /* Open drain IRQs need pullups */ @@ -722,14 +835,18 @@ static void __init crag6410_machine_init(void) s3c_i2c0_set_platdata(&i2c0_pdata); s3c_i2c1_set_platdata(&i2c1_pdata); s3c_fb_set_platdata(&crag6410_lcd_pdata); + s3c_hsotg_set_platdata(&crag6410_hsotg_pdata); i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0)); i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1)); samsung_keypad_set_platdata(&crag6410_keypad_data); + s3c64xx_spi0_set_platdata(NULL, 0, 2); platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices)); + gpio_led_register_device(-1, &gpio_leds_pdata); + regulator_has_full_constraints(); s3c64xx_pm_init(); @@ -739,9 +856,9 @@ MACHINE_START(WLF_CRAGG_6410, "Wolfson Cragganmore 6410") /* Maintainer: Mark Brown <broonie@opensource.wolfsonmicro.com> */ .atag_offset = 0x100, .init_irq = s3c6410_init_irq, - .handle_irq = vic_handle_irq, .map_io = crag6410_map_io, .init_machine = crag6410_machine_init, - .timer = &s3c24xx_timer, + .init_late = s3c64xx_init_late, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c index 521e07b8501..72cee08c8bf 100644 --- a/arch/arm/mach-s3c64xx/mach-hmt.c +++ b/arch/arm/mach-s3c64xx/mach-hmt.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/serial_core.h> +#include <linux/serial_s3c.h> #include <linux/platform_device.h> #include <linux/io.h> #include <linux/i2c.h> @@ -26,22 +27,22 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <video/samsung_fimd.h> #include <mach/hardware.h> #include <mach/map.h> -#include <asm/hardware/vic.h> #include <asm/irq.h> #include <asm/mach-types.h> -#include <plat/regs-serial.h> -#include <plat/iic.h> +#include <linux/platform_data/i2c-s3c2410.h> +#include <mach/gpio-samsung.h> #include <plat/fb.h> -#include <plat/nand.h> +#include <linux/platform_data/mtd-nand-s3c2410.h> #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> -#include <plat/regs-fb-v4.h> +#include <plat/samsung-time.h> #include "common.h" @@ -114,6 +115,7 @@ static struct platform_pwm_backlight_data hmt_backlight_data = { .max_brightness = 100 * 256, .dft_brightness = 40 * 256, .pwm_period_ns = 1000000000 / (100 * 256 * 20), + .enable_gpio = -1, .init = hmt_bl_init, .notify = hmt_bl_notify, .exit = hmt_bl_exit, @@ -123,29 +125,33 @@ static struct platform_pwm_backlight_data hmt_backlight_data = { static struct platform_device hmt_backlight_device = { .name = "pwm-backlight", .dev = { - .parent = &s3c_device_timer[1].dev, + .parent = &samsung_device_pwm.dev, .platform_data = &hmt_backlight_data, }, }; static struct s3c_fb_pd_win hmt_fb_win0 = { - .win_mode = { - .left_margin = 8, - .right_margin = 13, - .upper_margin = 7, - .lower_margin = 5, - .hsync_len = 3, - .vsync_len = 1, - .xres = 800, - .yres = 480, - }, .max_bpp = 32, .default_bpp = 16, + .xres = 800, + .yres = 480, +}; + +static struct fb_videomode hmt_lcd_timing = { + .left_margin = 8, + .right_margin = 13, + .upper_margin = 7, + .lower_margin = 5, + .hsync_len = 3, + .vsync_len = 1, + .xres = 800, + .yres = 480, }; /* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */ static struct s3c_fb_platdata hmt_lcd_pdata __initdata = { .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, + .vtiming = &hmt_lcd_timing, .win[0] = &hmt_fb_win0, .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, @@ -235,7 +241,7 @@ static struct platform_device *hmt_devices[] __initdata = { &s3c_device_nand, &s3c_device_fb, &s3c_device_ohci, - &s3c_device_timer[1], + &samsung_device_pwm, &hmt_backlight_device, &hmt_leds_device, }; @@ -243,8 +249,9 @@ static struct platform_device *hmt_devices[] __initdata = { static void __init hmt_map_io(void) { s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init hmt_machine_init(void) @@ -269,9 +276,9 @@ MACHINE_START(HMT, "Airgoo-HMT") /* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */ .atag_offset = 0x100, .init_irq = s3c6410_init_irq, - .handle_irq = vic_handle_irq, .map_io = hmt_map_io, .init_machine = hmt_machine_init, - .timer = &s3c24xx_timer, + .init_late = s3c64xx_init_late, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c index c34c2ab22ea..9cbc07602ef 100644 --- a/arch/arm/mach-s3c64xx/mach-mini6410.c +++ b/arch/arm/mach-s3c64xx/mach-mini6410.c @@ -22,30 +22,33 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/serial_core.h> +#include <linux/serial_s3c.h> #include <linux/types.h> -#include <asm/hardware/vic.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <mach/map.h> #include <mach/regs-gpio.h> -#include <mach/regs-modem.h> -#include <mach/regs-srom.h> +#include <mach/gpio-samsung.h> #include <plat/adc.h> #include <plat/cpu.h> #include <plat/devs.h> #include <plat/fb.h> -#include <plat/nand.h> -#include <plat/regs-serial.h> -#include <plat/ts.h> -#include <plat/regs-fb-v4.h> +#include <linux/platform_data/mtd-nand-s3c2410.h> +#include <linux/platform_data/mmc-sdhci-s3c.h> +#include <plat/sdhci.h> +#include <linux/platform_data/touchscreen-s3c2410.h> #include <video/platform_lcd.h> +#include <video/samsung_fimd.h> +#include <plat/samsung-time.h> #include "common.h" +#include "regs-modem.h" +#include "regs-srom.h" #define UCON S3C2410_UCON_DEFAULT #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) @@ -85,21 +88,10 @@ static struct s3c2410_uartcfg mini6410_uartcfgs[] __initdata = { /* DM9000AEP 10/100 ethernet controller */ static struct resource mini6410_dm9k_resource[] = { - [0] = { - .start = S3C64XX_PA_XM0CSN1, - .end = S3C64XX_PA_XM0CSN1 + 1, - .flags = IORESOURCE_MEM - }, - [1] = { - .start = S3C64XX_PA_XM0CSN1 + 4, - .end = S3C64XX_PA_XM0CSN1 + 5, - .flags = IORESOURCE_MEM - }, - [2] = { - .start = S3C_EINT(7), - .end = S3C_EINT(7), - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL - } + [0] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1, 2), + [1] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1 + 4, 2), + [2] = DEFINE_RES_NAMED(S3C_EINT(7), 1, NULL, IORESOURCE_IRQ \ + | IORESOURCE_IRQ_HIGHLEVEL), }; static struct dm9000_plat_data mini6410_dm9k_pdata = { @@ -151,41 +143,59 @@ static struct s3c2410_platform_nand mini6410_nand_info = { .sets = mini6410_nand_sets, }; -static struct s3c_fb_pd_win mini6410_fb_win[] = { +static struct s3c_fb_pd_win mini6410_lcd_type0_fb_win = { + .max_bpp = 32, + .default_bpp = 16, + .xres = 480, + .yres = 272, +}; + +static struct fb_videomode mini6410_lcd_type0_timing = { + /* 4.3" 480x272 */ + .left_margin = 3, + .right_margin = 2, + .upper_margin = 1, + .lower_margin = 1, + .hsync_len = 40, + .vsync_len = 1, + .xres = 480, + .yres = 272, +}; + +static struct s3c_fb_pd_win mini6410_lcd_type1_fb_win = { + .max_bpp = 32, + .default_bpp = 16, + .xres = 800, + .yres = 480, +}; + +static struct fb_videomode mini6410_lcd_type1_timing = { + /* 7.0" 800x480 */ + .left_margin = 8, + .right_margin = 13, + .upper_margin = 7, + .lower_margin = 5, + .hsync_len = 3, + .vsync_len = 1, + .xres = 800, + .yres = 480, +}; + +static struct s3c_fb_platdata mini6410_lcd_pdata[] __initdata = { { - .win_mode = { /* 4.3" 480x272 */ - .left_margin = 3, - .right_margin = 2, - .upper_margin = 1, - .lower_margin = 1, - .hsync_len = 40, - .vsync_len = 1, - .xres = 480, - .yres = 272, - }, - .max_bpp = 32, - .default_bpp = 16, + .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, + .vtiming = &mini6410_lcd_type0_timing, + .win[0] = &mini6410_lcd_type0_fb_win, + .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, }, { - .win_mode = { /* 7.0" 800x480 */ - .left_margin = 8, - .right_margin = 13, - .upper_margin = 7, - .lower_margin = 5, - .hsync_len = 3, - .vsync_len = 1, - .xres = 800, - .yres = 480, - }, - .max_bpp = 32, - .default_bpp = 16, + .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, + .vtiming = &mini6410_lcd_type1_timing, + .win[0] = &mini6410_lcd_type1_fb_win, + .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, }, -}; - -static struct s3c_fb_platdata mini6410_lcd_pdata __initdata = { - .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, - .win[0] = &mini6410_fb_win[0], - .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, - .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, + { }, }; static void mini6410_lcd_power_set(struct plat_lcd_data *pd, @@ -207,6 +217,13 @@ static struct platform_device mini6410_lcd_powerdev = { .dev.platform_data = &mini6410_lcd_power_data, }; +static struct s3c_sdhci_platdata mini6410_hsmmc1_pdata = { + .max_width = 4, + .cd_type = S3C_SDHCI_CD_GPIO, + .ext_cd_gpio = S3C64XX_GPN(10), + .ext_cd_gpio_invert = true, +}; + static struct platform_device *mini6410_devices[] __initdata = { &mini6410_device_eth, &s3c_device_hsmmc0, @@ -224,8 +241,9 @@ static void __init mini6410_map_io(void) u32 tmp; s3c64xx_init_io(NULL, 0); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); /* set the LCD type */ tmp = __raw_readl(S3C64XX_SPCON); @@ -283,7 +301,7 @@ static void mini6410_parse_features( "screen type already set\n", f); } else { int li = f - '0'; - if (li >= ARRAY_SIZE(mini6410_fb_win)) + if (li >= ARRAY_SIZE(mini6410_lcd_pdata)) printk(KERN_INFO "MINI6410: '%c' out " "of range LCD mode\n", f); else { @@ -307,14 +325,13 @@ static void __init mini6410_machine_init(void) /* Parse the feature string */ mini6410_parse_features(&features, mini6410_features_str); - mini6410_lcd_pdata.win[0] = &mini6410_fb_win[features.lcd_index]; - printk(KERN_INFO "MINI6410: selected LCD display is %dx%d\n", - mini6410_lcd_pdata.win[0]->win_mode.xres, - mini6410_lcd_pdata.win[0]->win_mode.yres); + mini6410_lcd_pdata[features.lcd_index].win[0]->xres, + mini6410_lcd_pdata[features.lcd_index].win[0]->yres); s3c_nand_set_platdata(&mini6410_nand_info); - s3c_fb_set_platdata(&mini6410_lcd_pdata); + s3c_fb_set_platdata(&mini6410_lcd_pdata[features.lcd_index]); + s3c_sdhci1_set_platdata(&mini6410_hsmmc1_pdata); s3c24xx_ts_set_platdata(NULL); /* configure nCS1 width to 16 bits */ @@ -347,9 +364,9 @@ MACHINE_START(MINI6410, "MINI6410") /* Maintainer: Darius Augulis <augulis.darius@gmail.com> */ .atag_offset = 0x100, .init_irq = s3c6410_init_irq, - .handle_irq = vic_handle_irq, .map_io = mini6410_map_io, .init_machine = mini6410_machine_init, - .timer = &s3c24xx_timer, + .init_late = s3c64xx_init_late, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c index 0efa2ba783b..67f06a9ae65 100644 --- a/arch/arm/mach-s3c64xx/mach-ncp.c +++ b/arch/arm/mach-s3c64xx/mach-ncp.c @@ -16,6 +16,7 @@ #include <linux/timer.h> #include <linux/init.h> #include <linux/serial_core.h> +#include <linux/serial_s3c.h> #include <linux/platform_device.h> #include <linux/io.h> #include <linux/i2c.h> @@ -24,8 +25,8 @@ #include <linux/delay.h> #include <video/platform_lcd.h> +#include <video/samsung_fimd.h> -#include <asm/hardware/vic.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> @@ -36,14 +37,13 @@ #include <asm/irq.h> #include <asm/mach-types.h> -#include <plat/regs-serial.h> -#include <plat/iic.h> +#include <linux/platform_data/i2c-s3c2410.h> #include <plat/fb.h> #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> -#include <plat/regs-fb-v4.h> +#include <plat/samsung-time.h> #include "common.h" @@ -86,8 +86,9 @@ static struct map_desc ncp_iodesc[] __initdata = {}; static void __init ncp_map_io(void) { s3c64xx_init_io(ncp_iodesc, ARRAY_SIZE(ncp_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init ncp_machine_init(void) @@ -101,9 +102,9 @@ MACHINE_START(NCP, "NCP") /* Maintainer: Samsung Electronics */ .atag_offset = 0x100, .init_irq = s3c6410_init_irq, - .handle_irq = vic_handle_irq, .map_io = ncp_map_io, .init_machine = ncp_machine_init, - .timer = &s3c24xx_timer, + .init_late = s3c64xx_init_late, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c index be2a9a22ab7..fbad2af1ef1 100644 --- a/arch/arm/mach-s3c64xx/mach-real6410.c +++ b/arch/arm/mach-s3c64xx/mach-real6410.c @@ -23,30 +23,31 @@ #include <linux/mtd/partitions.h> #include <linux/platform_device.h> #include <linux/serial_core.h> +#include <linux/serial_s3c.h> #include <linux/types.h> -#include <asm/hardware/vic.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <mach/map.h> #include <mach/regs-gpio.h> -#include <mach/regs-modem.h> -#include <mach/regs-srom.h> +#include <mach/gpio-samsung.h> #include <plat/adc.h> #include <plat/cpu.h> #include <plat/devs.h> #include <plat/fb.h> -#include <plat/nand.h> -#include <plat/regs-serial.h> -#include <plat/ts.h> -#include <plat/regs-fb-v4.h> +#include <linux/platform_data/mtd-nand-s3c2410.h> +#include <linux/platform_data/touchscreen-s3c2410.h> #include <video/platform_lcd.h> +#include <video/samsung_fimd.h> +#include <plat/samsung-time.h> #include "common.h" +#include "regs-modem.h" +#include "regs-srom.h" #define UCON S3C2410_UCON_DEFAULT #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) @@ -86,21 +87,10 @@ static struct s3c2410_uartcfg real6410_uartcfgs[] __initdata = { /* DM9000AEP 10/100 ethernet controller */ static struct resource real6410_dm9k_resource[] = { - [0] = { - .start = S3C64XX_PA_XM0CSN1, - .end = S3C64XX_PA_XM0CSN1 + 1, - .flags = IORESOURCE_MEM - }, - [1] = { - .start = S3C64XX_PA_XM0CSN1 + 4, - .end = S3C64XX_PA_XM0CSN1 + 5, - .flags = IORESOURCE_MEM - }, - [2] = { - .start = S3C_EINT(7), - .end = S3C_EINT(7), - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL - } + [0] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1, 2), + [1] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1 + 4, 2), + [2] = DEFINE_RES_NAMED(S3C_EINT(7), 1, NULL, IORESOURCE_IRQ \ + | IORESOURCE_IRQ_HIGHLEVEL), }; static struct dm9000_plat_data real6410_dm9k_pdata = { @@ -117,41 +107,57 @@ static struct platform_device real6410_device_eth = { }, }; -static struct s3c_fb_pd_win real6410_fb_win[] = { +static struct s3c_fb_pd_win real6410_lcd_type0_fb_win = { + .max_bpp = 32, + .default_bpp = 16, + .xres = 480, + .yres = 272, +}; + +static struct fb_videomode real6410_lcd_type0_timing = { + /* 4.3" 480x272 */ + .left_margin = 3, + .right_margin = 2, + .upper_margin = 1, + .lower_margin = 1, + .hsync_len = 40, + .vsync_len = 1, +}; + +static struct s3c_fb_pd_win real6410_lcd_type1_fb_win = { + .max_bpp = 32, + .default_bpp = 16, + .xres = 800, + .yres = 480, +}; + +static struct fb_videomode real6410_lcd_type1_timing = { + /* 7.0" 800x480 */ + .left_margin = 8, + .right_margin = 13, + .upper_margin = 7, + .lower_margin = 5, + .hsync_len = 3, + .vsync_len = 1, + .xres = 800, + .yres = 480, +}; + +static struct s3c_fb_platdata real6410_lcd_pdata[] __initdata = { { - .win_mode = { /* 4.3" 480x272 */ - .left_margin = 3, - .right_margin = 2, - .upper_margin = 1, - .lower_margin = 1, - .hsync_len = 40, - .vsync_len = 1, - .xres = 480, - .yres = 272, - }, - .max_bpp = 32, - .default_bpp = 16, + .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, + .vtiming = &real6410_lcd_type0_timing, + .win[0] = &real6410_lcd_type0_fb_win, + .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, }, { - .win_mode = { /* 7.0" 800x480 */ - .left_margin = 8, - .right_margin = 13, - .upper_margin = 7, - .lower_margin = 5, - .hsync_len = 3, - .vsync_len = 1, - .xres = 800, - .yres = 480, - }, - .max_bpp = 32, - .default_bpp = 16, + .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, + .vtiming = &real6410_lcd_type1_timing, + .win[0] = &real6410_lcd_type1_fb_win, + .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, }, -}; - -static struct s3c_fb_platdata real6410_lcd_pdata __initdata = { - .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, - .win[0] = &real6410_fb_win[0], - .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, - .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, + { }, }; static struct mtd_partition real6410_nand_part[] = { @@ -207,6 +213,7 @@ static void __init real6410_map_io(void) s3c64xx_init_io(NULL, 0); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(real6410_uartcfgs, ARRAY_SIZE(real6410_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); /* set the LCD type */ tmp = __raw_readl(S3C64XX_SPCON); @@ -264,7 +271,7 @@ static void real6410_parse_features( "screen type already set\n", f); } else { int li = f - '0'; - if (li >= ARRAY_SIZE(real6410_fb_win)) + if (li >= ARRAY_SIZE(real6410_lcd_pdata)) printk(KERN_INFO "REAL6410: '%c' out " "of range LCD mode\n", f); else { @@ -288,13 +295,11 @@ static void __init real6410_machine_init(void) /* Parse the feature string */ real6410_parse_features(&features, real6410_features_str); - real6410_lcd_pdata.win[0] = &real6410_fb_win[features.lcd_index]; - printk(KERN_INFO "REAL6410: selected LCD display is %dx%d\n", - real6410_lcd_pdata.win[0]->win_mode.xres, - real6410_lcd_pdata.win[0]->win_mode.yres); + real6410_lcd_pdata[features.lcd_index].win[0]->xres, + real6410_lcd_pdata[features.lcd_index].win[0]->yres); - s3c_fb_set_platdata(&real6410_lcd_pdata); + s3c_fb_set_platdata(&real6410_lcd_pdata[features.lcd_index]); s3c_nand_set_platdata(&real6410_nand_info); s3c24xx_ts_set_platdata(NULL); @@ -328,9 +333,9 @@ MACHINE_START(REAL6410, "REAL6410") .atag_offset = 0x100, .init_irq = s3c6410_init_irq, - .handle_irq = vic_handle_irq, .map_io = real6410_map_io, .init_machine = real6410_machine_init, - .timer = &s3c24xx_timer, + .init_late = s3c64xx_init_late, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c new file mode 100644 index 00000000000..2fddf38192d --- /dev/null +++ b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c @@ -0,0 +1,76 @@ +/* + * Samsung's S3C64XX flattened device tree enabled machine + * + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/of_platform.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/system_misc.h> + +#include <plat/cpu.h> +#include <plat/watchdog-reset.h> + +#include <mach/map.h> + +#include "common.h" + +/* + * IO mapping for shared system controller IP. + * + * FIXME: Make remaining drivers use dynamic mapping. + */ +static struct map_desc s3c64xx_dt_iodesc[] __initdata = { + { + .virtual = (unsigned long)S3C_VA_SYS, + .pfn = __phys_to_pfn(S3C64XX_PA_SYSCON), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +static void __init s3c64xx_dt_map_io(void) +{ + debug_ll_io_init(); + iotable_init(s3c64xx_dt_iodesc, ARRAY_SIZE(s3c64xx_dt_iodesc)); + + s3c64xx_init_cpu(); + + if (!soc_is_s3c64xx()) + panic("SoC is not S3C64xx!"); +} + +static void __init s3c64xx_dt_init_machine(void) +{ + samsung_wdt_reset_of_init(); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static void s3c64xx_dt_restart(enum reboot_mode mode, const char *cmd) +{ + if (mode != REBOOT_SOFT) + samsung_wdt_reset(); + + /* if all else fails, or mode was for soft, jump to 0 */ + soft_restart(0); +} + +static char const *s3c64xx_dt_compat[] __initdata = { + "samsung,s3c6400", + "samsung,s3c6410", + NULL +}; + +DT_MACHINE_START(S3C6400_DT, "Samsung S3C64xx (Flattened Device Tree)") + /* Maintainer: Tomasz Figa <tomasz.figa@gmail.com> */ + .dt_compat = s3c64xx_dt_compat, + .map_io = s3c64xx_dt_map_io, + .init_machine = s3c64xx_dt_init_machine, + .restart = s3c64xx_dt_restart, +MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c index ce31db13623..78dd6f73c07 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq.c +++ b/arch/arm/mach-s3c64xx/mach-smartq.c @@ -16,31 +16,33 @@ #include <linux/platform_device.h> #include <linux/pwm_backlight.h> #include <linux/serial_core.h> +#include <linux/serial_s3c.h> #include <linux/spi/spi_gpio.h> #include <linux/usb/gpio_vbus.h> +#include <linux/platform_data/s3c-hsotg.h> #include <asm/mach-types.h> #include <asm/mach/map.h> #include <mach/map.h> #include <mach/regs-gpio.h> -#include <mach/regs-modem.h> +#include <mach/gpio-samsung.h> #include <plat/clock.h> #include <plat/cpu.h> #include <plat/devs.h> -#include <plat/iic.h> +#include <linux/platform_data/i2c-s3c2410.h> #include <plat/gpio-cfg.h> -#include <plat/hwmon.h> -#include <plat/regs-serial.h> -#include <plat/udc-hs.h> -#include <plat/usb-control.h> +#include <linux/platform_data/hwmon-s3c.h> +#include <linux/platform_data/usb-ohci-s3c2410.h> #include <plat/sdhci.h> -#include <plat/ts.h> +#include <linux/platform_data/touchscreen-s3c2410.h> #include <video/platform_lcd.h> +#include <plat/samsung-time.h> #include "common.h" +#include "regs-modem.h" #define UCON S3C2410_UCON_DEFAULT #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE) @@ -105,7 +107,7 @@ static void smartq_usb_host_enableoc(struct s3c2410_hcd_info *info, int on) if (on) { ret = request_irq(gpio_to_irq(S3C64XX_GPL(10)), - smartq_usb_host_ocirq, IRQF_DISABLED | + smartq_usb_host_ocirq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "USB host overcurrent", info); if (ret != 0) @@ -150,13 +152,14 @@ static struct platform_pwm_backlight_data smartq_backlight_data = { .max_brightness = 1000, .dft_brightness = 600, .pwm_period_ns = 1000000000 / (1000 * 20), + .enable_gpio = -1, .init = smartq_bl_init, }; static struct platform_device smartq_backlight_device = { .name = "pwm-backlight", .dev = { - .parent = &s3c_device_timer[1].dev, + .parent = &samsung_device_pwm.dev, .platform_data = &smartq_backlight_data, }, }; @@ -187,6 +190,8 @@ static struct s3c_hwmon_pdata smartq_hwmon_pdata __initdata = { }, }; +static struct s3c_hsotg_plat smartq_hsotg_pdata; + static int __init smartq_lcd_setup_gpio(void) { int ret; @@ -243,7 +248,7 @@ static struct platform_device *smartq_devices[] __initdata = { &s3c_device_i2c0, &s3c_device_ohci, &s3c_device_rtc, - &s3c_device_timer[1], + &samsung_device_pwm, &s3c_device_ts, &s3c_device_usb_hsotg, &s3c64xx_device_iis0, @@ -334,13 +339,6 @@ err: return ret; } -static int __init smartq_usb_otg_init(void) -{ - clk_xusbxti.rate = 12000000; - - return 0; -} - static int __init smartq_wifi_init(void) { int ret; @@ -374,8 +372,10 @@ static struct map_desc smartq_iodesc[] __initdata = {}; void __init smartq_map_io(void) { s3c64xx_init_io(smartq_iodesc, ARRAY_SIZE(smartq_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); + s3c64xx_set_xusbxti_freq(12000000); s3c24xx_init_uarts(smartq_uartcfgs, ARRAY_SIZE(smartq_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); smartq_lcd_mode_set(); } @@ -383,6 +383,7 @@ void __init smartq_map_io(void) void __init smartq_machine_init(void) { s3c_i2c0_set_platdata(NULL); + s3c_hsotg_set_platdata(&smartq_hsotg_pdata); s3c_hwmon_set_platdata(&smartq_hwmon_pdata); s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata); s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata); @@ -394,7 +395,6 @@ void __init smartq_machine_init(void) WARN_ON(smartq_lcd_setup_gpio()); WARN_ON(smartq_power_off_init()); WARN_ON(smartq_usb_host_init()); - WARN_ON(smartq_usb_otg_init()); WARN_ON(smartq_wifi_init()); platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices)); diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c64xx/mach-smartq5.c index 3f42431d4dd..dec4c08e834 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq5.c +++ b/arch/arm/mach-s3c64xx/mach-smartq5.c @@ -17,18 +17,19 @@ #include <linux/leds.h> #include <linux/platform_device.h> -#include <asm/hardware/vic.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <video/samsung_fimd.h> #include <mach/map.h> #include <mach/regs-gpio.h> +#include <mach/gpio-samsung.h> #include <plat/cpu.h> #include <plat/devs.h> #include <plat/fb.h> #include <plat/gpio-cfg.h> -#include <plat/regs-fb-v4.h> +#include <plat/samsung-time.h> #include "common.h" #include "mach-smartq.h" @@ -108,23 +109,27 @@ static struct platform_device smartq5_buttons_device = { }; static struct s3c_fb_pd_win smartq5_fb_win0 = { - .win_mode = { - .left_margin = 216, - .right_margin = 40, - .upper_margin = 35, - .lower_margin = 10, - .hsync_len = 1, - .vsync_len = 1, - .xres = 800, - .yres = 480, - .refresh = 80, - }, .max_bpp = 32, .default_bpp = 16, + .xres = 800, + .yres = 480, +}; + +static struct fb_videomode smartq5_lcd_timing = { + .left_margin = 216, + .right_margin = 40, + .upper_margin = 35, + .lower_margin = 10, + .hsync_len = 1, + .vsync_len = 1, + .xres = 800, + .yres = 480, + .refresh = 80, }; static struct s3c_fb_platdata smartq5_lcd_pdata __initdata = { .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, + .vtiming = &smartq5_lcd_timing, .win[0] = &smartq5_fb_win0, .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC | @@ -149,9 +154,9 @@ MACHINE_START(SMARTQ5, "SmartQ 5") /* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */ .atag_offset = 0x100, .init_irq = s3c6410_init_irq, - .handle_irq = vic_handle_irq, .map_io = smartq_map_io, .init_machine = smartq5_machine_init, - .timer = &s3c24xx_timer, + .init_late = s3c64xx_init_late, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c64xx/mach-smartq7.c index e5c09b6db96..27b322069c7 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq7.c +++ b/arch/arm/mach-s3c64xx/mach-smartq7.c @@ -17,18 +17,19 @@ #include <linux/leds.h> #include <linux/platform_device.h> -#include <asm/hardware/vic.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <video/samsung_fimd.h> #include <mach/map.h> #include <mach/regs-gpio.h> +#include <mach/gpio-samsung.h> #include <plat/cpu.h> #include <plat/devs.h> #include <plat/fb.h> #include <plat/gpio-cfg.h> -#include <plat/regs-fb-v4.h> +#include <plat/samsung-time.h> #include "common.h" #include "mach-smartq.h" @@ -124,23 +125,27 @@ static struct platform_device smartq7_buttons_device = { }; static struct s3c_fb_pd_win smartq7_fb_win0 = { - .win_mode = { - .left_margin = 3, - .right_margin = 5, - .upper_margin = 1, - .lower_margin = 20, - .hsync_len = 10, - .vsync_len = 3, - .xres = 800, - .yres = 480, - .refresh = 80, - }, .max_bpp = 32, .default_bpp = 16, + .xres = 800, + .yres = 480, +}; + +static struct fb_videomode smartq7_lcd_timing = { + .left_margin = 3, + .right_margin = 5, + .upper_margin = 1, + .lower_margin = 20, + .hsync_len = 10, + .vsync_len = 3, + .xres = 800, + .yres = 480, + .refresh = 80, }; static struct s3c_fb_platdata smartq7_lcd_pdata __initdata = { .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, + .vtiming = &smartq7_lcd_timing, .win[0] = &smartq7_fb_win0, .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC | @@ -165,9 +170,9 @@ MACHINE_START(SMARTQ7, "SmartQ 7") /* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */ .atag_offset = 0x100, .init_irq = s3c6410_init_irq, - .handle_irq = vic_handle_irq, .map_io = smartq_map_io, .init_machine = smartq7_machine_init, - .timer = &s3c24xx_timer, + .init_late = s3c64xx_init_late, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c index 5f096534f4c..c85d1cbe769 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6400.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c @@ -16,13 +16,13 @@ #include <linux/timer.h> #include <linux/init.h> #include <linux/serial_core.h> +#include <linux/serial_s3c.h> #include <linux/platform_device.h> #include <linux/i2c.h> #include <linux/io.h> #include <asm/mach-types.h> -#include <asm/hardware/vic.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> @@ -30,12 +30,12 @@ #include <mach/hardware.h> #include <mach/map.h> -#include <plat/regs-serial.h> - #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> -#include <plat/iic.h> +#include <linux/platform_data/i2c-s3c2410.h> +#include <mach/gpio-samsung.h> +#include <plat/samsung-time.h> #include "common.h" @@ -65,8 +65,9 @@ static struct map_desc smdk6400_iodesc[] = {}; static void __init smdk6400_map_io(void) { s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static struct platform_device *smdk6400_devices[] __initdata = { @@ -90,9 +91,9 @@ MACHINE_START(SMDK6400, "SMDK6400") .atag_offset = 0x100, .init_irq = s3c6400_init_irq, - .handle_irq = vic_handle_irq, .map_io = smdk6400_map_io, .init_machine = smdk6400_machine_init, - .timer = &s3c24xx_timer, + .init_late = s3c64xx_init_late, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index ca6fc204f0e..c6a8b2ab024 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -19,6 +19,7 @@ #include <linux/init.h> #include <linux/input.h> #include <linux/serial_core.h> +#include <linux/serial_s3c.h> #include <linux/platform_device.h> #include <linux/io.h> #include <linux/i2c.h> @@ -30,6 +31,7 @@ #include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> #include <linux/pwm_backlight.h> +#include <linux/platform_data/s3c-hsotg.h> #ifdef CONFIG_SMDK6410_WM1190_EV1 #include <linux/mfd/wm8350/core.h> @@ -42,8 +44,8 @@ #endif #include <video/platform_lcd.h> +#include <video/samsung_fimd.h> -#include <asm/hardware/vic.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> @@ -54,13 +56,10 @@ #include <asm/irq.h> #include <asm/mach-types.h> -#include <plat/regs-serial.h> -#include <mach/regs-modem.h> #include <mach/regs-gpio.h> -#include <mach/regs-sys.h> -#include <mach/regs-srom.h> -#include <plat/ata.h> -#include <plat/iic.h> +#include <mach/gpio-samsung.h> +#include <linux/platform_data/ata-samsung_cf.h> +#include <linux/platform_data/i2c-s3c2410.h> #include <plat/fb.h> #include <plat/gpio-cfg.h> @@ -68,12 +67,15 @@ #include <plat/devs.h> #include <plat/cpu.h> #include <plat/adc.h> -#include <plat/ts.h> +#include <linux/platform_data/touchscreen-s3c2410.h> #include <plat/keypad.h> #include <plat/backlight.h> -#include <plat/regs-fb-v4.h> +#include <plat/samsung-time.h> #include "common.h" +#include "regs-modem.h" +#include "regs-srom.h" +#include "regs-sys.h" #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB @@ -145,26 +147,29 @@ static struct platform_device smdk6410_lcd_powerdev = { }; static struct s3c_fb_pd_win smdk6410_fb_win0 = { - /* this is to ensure we use win0 */ - .win_mode = { - .left_margin = 8, - .right_margin = 13, - .upper_margin = 7, - .lower_margin = 5, - .hsync_len = 3, - .vsync_len = 1, - .xres = 800, - .yres = 480, - }, .max_bpp = 32, .default_bpp = 16, + .xres = 800, + .yres = 480, .virtual_y = 480 * 2, .virtual_x = 800, }; +static struct fb_videomode smdk6410_lcd_timing = { + .left_margin = 8, + .right_margin = 13, + .upper_margin = 7, + .lower_margin = 5, + .hsync_len = 3, + .vsync_len = 1, + .xres = 800, + .yres = 480, +}; + /* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */ static struct s3c_fb_platdata smdk6410_lcd_pdata __initdata = { .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, + .vtiming = &smdk6410_lcd_timing, .win[0] = &smdk6410_fb_win0, .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, @@ -181,16 +186,9 @@ static struct s3c_fb_platdata smdk6410_lcd_pdata __initdata = { */ static struct resource smdk6410_smsc911x_resources[] = { - [0] = { - .start = S3C64XX_PA_XM0CSN1, - .end = S3C64XX_PA_XM0CSN1 + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = S3C_EINT(10), - .end = S3C_EINT(10), - .flags = IORESOURCE_IRQ | IRQ_TYPE_LEVEL_LOW, - }, + [0] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1, SZ_64K), + [1] = DEFINE_RES_NAMED(S3C_EINT(10), 1, NULL, IORESOURCE_IRQ \ + | IRQ_TYPE_LEVEL_LOW), }; static struct smsc911x_platform_config smdk6410_smsc911x_pdata = { @@ -277,8 +275,8 @@ static struct platform_device *smdk6410_devices[] __initdata = { &s3c_device_i2c1, &s3c_device_fb, &s3c_device_ohci, + &samsung_device_pwm, &s3c_device_usb_hsotg, - &samsung_asoc_dma, &s3c64xx_device_iisv4, &samsung_device_keypad, @@ -569,7 +567,6 @@ static struct wm831x_status_pdata wm1192_led8_pdata = { static struct wm831x_pdata smdk6410_wm1192_pdata = { .pre_init = wm1192_pre_init, - .irq_base = IRQ_BOARD_START, .backlight = &wm1192_backlight_pdata, .dcdc = { @@ -629,15 +626,19 @@ static struct samsung_bl_gpio_info smdk6410_bl_gpio_info = { static struct platform_pwm_backlight_data smdk6410_bl_data = { .pwm_id = 1, + .enable_gpio = -1, }; +static struct s3c_hsotg_plat smdk6410_hsotg_pdata; + static void __init smdk6410_map_io(void) { u32 tmp; s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); /* set the LCD type */ @@ -659,6 +660,7 @@ static void __init smdk6410_machine_init(void) s3c_i2c0_set_platdata(NULL); s3c_i2c1_set_platdata(NULL); s3c_fb_set_platdata(&smdk6410_lcd_pdata); + s3c_hsotg_set_platdata(&smdk6410_hsotg_pdata); samsung_keypad_set_platdata(&smdk6410_keypad_data); @@ -692,9 +694,9 @@ static void __init smdk6410_machine_init(void) s3c_ide_set_platdata(&smdk6410_ide_pdata); - samsung_bl_set(&smdk6410_bl_gpio_info, &smdk6410_bl_data); - platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices)); + + samsung_bl_set(&smdk6410_bl_gpio_info, &smdk6410_bl_data); } MACHINE_START(SMDK6410, "SMDK6410") @@ -702,9 +704,9 @@ MACHINE_START(SMDK6410, "SMDK6410") .atag_offset = 0x100, .init_irq = s3c6410_init_irq, - .handle_irq = vic_handle_irq, .map_io = smdk6410_map_io, .init_machine = smdk6410_machine_init, - .timer = &s3c24xx_timer, + .init_late = s3c64xx_init_late, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/pl080.c b/arch/arm/mach-s3c64xx/pl080.c new file mode 100644 index 00000000000..901a984bddc --- /dev/null +++ b/arch/arm/mach-s3c64xx/pl080.c @@ -0,0 +1,244 @@ +/* + * Samsung's S3C64XX generic DMA support using amba-pl08x driver. + * + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/amba/bus.h> +#include <linux/amba/pl080.h> +#include <linux/amba/pl08x.h> +#include <linux/of.h> + +#include <mach/irqs.h> +#include <mach/map.h> + +#include "regs-sys.h" + +static int pl08x_get_xfer_signal(const struct pl08x_channel_data *cd) +{ + return cd->min_signal; +} + +static void pl08x_put_xfer_signal(const struct pl08x_channel_data *cd, int ch) +{ +} + +/* + * DMA0 + */ + +static struct pl08x_channel_data s3c64xx_dma0_info[] = { + { + .bus_id = "uart0_tx", + .min_signal = 0, + .max_signal = 0, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "uart0_rx", + .min_signal = 1, + .max_signal = 1, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "uart1_tx", + .min_signal = 2, + .max_signal = 2, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "uart1_rx", + .min_signal = 3, + .max_signal = 3, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "uart2_tx", + .min_signal = 4, + .max_signal = 4, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "uart2_rx", + .min_signal = 5, + .max_signal = 5, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "uart3_tx", + .min_signal = 6, + .max_signal = 6, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "uart3_rx", + .min_signal = 7, + .max_signal = 7, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "pcm0_tx", + .min_signal = 8, + .max_signal = 8, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "pcm0_rx", + .min_signal = 9, + .max_signal = 9, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "i2s0_tx", + .min_signal = 10, + .max_signal = 10, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "i2s0_rx", + .min_signal = 11, + .max_signal = 11, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "spi0_tx", + .min_signal = 12, + .max_signal = 12, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "spi0_rx", + .min_signal = 13, + .max_signal = 13, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "i2s2_tx", + .min_signal = 14, + .max_signal = 14, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "i2s2_rx", + .min_signal = 15, + .max_signal = 15, + .periph_buses = PL08X_AHB2, + } +}; + +struct pl08x_platform_data s3c64xx_dma0_plat_data = { + .memcpy_channel = { + .bus_id = "memcpy", + .cctl_memcpy = + (PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT | + PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT | + PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | + PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | + PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | + PL080_CONTROL_PROT_SYS), + }, + .lli_buses = PL08X_AHB1, + .mem_buses = PL08X_AHB1, + .get_xfer_signal = pl08x_get_xfer_signal, + .put_xfer_signal = pl08x_put_xfer_signal, + .slave_channels = s3c64xx_dma0_info, + .num_slave_channels = ARRAY_SIZE(s3c64xx_dma0_info), +}; + +static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0, + 0x75000000, {IRQ_DMA0}, &s3c64xx_dma0_plat_data); + +/* + * DMA1 + */ + +static struct pl08x_channel_data s3c64xx_dma1_info[] = { + { + .bus_id = "pcm1_tx", + .min_signal = 0, + .max_signal = 0, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "pcm1_rx", + .min_signal = 1, + .max_signal = 1, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "i2s1_tx", + .min_signal = 2, + .max_signal = 2, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "i2s1_rx", + .min_signal = 3, + .max_signal = 3, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "spi1_tx", + .min_signal = 4, + .max_signal = 4, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "spi1_rx", + .min_signal = 5, + .max_signal = 5, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "ac97_out", + .min_signal = 6, + .max_signal = 6, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "ac97_in", + .min_signal = 7, + .max_signal = 7, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "ac97_mic", + .min_signal = 8, + .max_signal = 8, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "pwm", + .min_signal = 9, + .max_signal = 9, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "irda", + .min_signal = 10, + .max_signal = 10, + .periph_buses = PL08X_AHB2, + }, { + .bus_id = "external", + .min_signal = 11, + .max_signal = 11, + .periph_buses = PL08X_AHB2, + }, +}; + +struct pl08x_platform_data s3c64xx_dma1_plat_data = { + .memcpy_channel = { + .bus_id = "memcpy", + .cctl_memcpy = + (PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT | + PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT | + PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | + PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | + PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | + PL080_CONTROL_PROT_SYS), + }, + .lli_buses = PL08X_AHB1, + .mem_buses = PL08X_AHB1, + .get_xfer_signal = pl08x_get_xfer_signal, + .put_xfer_signal = pl08x_put_xfer_signal, + .slave_channels = s3c64xx_dma1_info, + .num_slave_channels = ARRAY_SIZE(s3c64xx_dma1_info), +}; + +static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0, + 0x75100000, {IRQ_DMA1}, &s3c64xx_dma1_plat_data); + +static int __init s3c64xx_pl080_init(void) +{ + /* Set all DMA configuration to be DMA, not SDMA */ + writel(0xffffff, S3C64XX_SDMA_SEL); + + if (of_have_populated_dt()) + return 0; + + amba_device_register(&s3c64xx_dma0_device, &iomem_resource); + amba_device_register(&s3c64xx_dma1_device, &iomem_resource); + + return 0; +} +arch_initcall(s3c64xx_pl080_init); diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c index 7d3e81b9dd0..6b37694fa33 100644 --- a/arch/arm/mach-s3c64xx/pm.c +++ b/arch/arm/mach-s3c64xx/pm.c @@ -26,12 +26,14 @@ #include <plat/pm.h> #include <plat/wakeup-mask.h> -#include <mach/regs-sys.h> #include <mach/regs-gpio.h> #include <mach/regs-clock.h> -#include <mach/regs-syscon-power.h> -#include <mach/regs-gpio-memport.h> -#include <mach/regs-modem.h> +#include <mach/gpio-samsung.h> + +#include "regs-gpio-memport.h" +#include "regs-modem.h" +#include "regs-sys.h" +#include "regs-syscon-power.h" struct s3c64xx_pm_domain { char *const name; @@ -193,29 +195,8 @@ void s3c_pm_debug_smdkled(u32 set, u32 clear) #endif static struct sleep_save core_save[] = { - SAVE_ITEM(S3C_APLL_LOCK), - SAVE_ITEM(S3C_MPLL_LOCK), - SAVE_ITEM(S3C_EPLL_LOCK), - SAVE_ITEM(S3C_CLK_SRC), - SAVE_ITEM(S3C_CLK_DIV0), - SAVE_ITEM(S3C_CLK_DIV1), - SAVE_ITEM(S3C_CLK_DIV2), - SAVE_ITEM(S3C_CLK_OUT), - SAVE_ITEM(S3C_HCLK_GATE), - SAVE_ITEM(S3C_PCLK_GATE), - SAVE_ITEM(S3C_SCLK_GATE), - SAVE_ITEM(S3C_MEM0_GATE), - - SAVE_ITEM(S3C_EPLL_CON1), - SAVE_ITEM(S3C_EPLL_CON0), - SAVE_ITEM(S3C64XX_MEM0DRVCON), SAVE_ITEM(S3C64XX_MEM1DRVCON), - -#ifndef CONFIG_CPU_FREQ - SAVE_ITEM(S3C_APLL_CON), - SAVE_ITEM(S3C_MPLL_CON), -#endif }; static struct sleep_save misc_save[] = { @@ -296,7 +277,8 @@ static int s3c64xx_cpu_suspend(unsigned long arg) /* we should never get past here */ - panic("sleep resumed to originator?"); + pr_info("Failed to suspend the system\n"); + return 1; /* Aborting suspend */ } /* mapping of interrupts to parts of the wakeup mask */ @@ -338,8 +320,10 @@ int __init s3c64xx_pm_init(void) for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); i++) pm_genpd_init(&s3c64xx_pm_domains[i]->pd, NULL, false); +#ifdef CONFIG_S3C_DEV_FB if (dev_get_platdata(&s3c_device_fb.dev)) pm_genpd_add_device(&s3c64xx_pm_f.pd, &s3c_device_fb.dev); +#endif return 0; } @@ -348,7 +332,6 @@ static __init int s3c64xx_pm_initcall(void) { pm_cpu_prep = s3c64xx_pm_prepare; pm_cpu_sleep = s3c64xx_cpu_suspend; - pm_uart_udivslot = 1; #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK gpio_request(S3C64XX_GPN(12), "DEBUG_LED0"); @@ -365,10 +348,9 @@ static __init int s3c64xx_pm_initcall(void) } arch_initcall(s3c64xx_pm_initcall); -static __init int s3c64xx_pm_late_initcall(void) +int __init s3c64xx_pm_late_initcall(void) { pm_genpd_poweroff_unused(); return 0; } -late_initcall(s3c64xx_pm_late_initcall); diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-gpio-memport.h b/arch/arm/mach-s3c64xx/regs-gpio-memport.h index 82342f6fd27..b927593019f 100644 --- a/arch/arm/mach-s3c64xx/include/mach/regs-gpio-memport.h +++ b/arch/arm/mach-s3c64xx/regs-gpio-memport.h @@ -1,5 +1,4 @@ -/* linux/arch/arm/plat-s3c64xx/include/mach/regs-gpio-memport.h - * +/* * Copyright 2008 Openmoko, Inc. * Copyright 2008 Simtec Electronics * Ben Dooks <ben@simtec.co.uk> @@ -8,8 +7,8 @@ * S3C64XX - GPIO memory port register definitions */ -#ifndef __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H -#define __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H __FILE__ +#ifndef __MACH_S3C64XX_REGS_GPIO_MEMPORT_H +#define __MACH_S3C64XX_REGS_GPIO_MEMPORT_H __FILE__ #define S3C64XX_MEM0CONSTOP S3C64XX_GPIOREG(0x1B0) #define S3C64XX_MEM1CONSTOP S3C64XX_GPIOREG(0x1B4) @@ -21,5 +20,5 @@ #define S3C64XX_MEM0DRVCON S3C64XX_GPIOREG(0x1D0) #define S3C64XX_MEM1DRVCON S3C64XX_GPIOREG(0x1D4) -#endif /* __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H */ +#endif /* __MACH_S3C64XX_REGS_GPIO_MEMPORT_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-modem.h b/arch/arm/mach-s3c64xx/regs-modem.h index 49f7759dedf..073cdd3a03b 100644 --- a/arch/arm/mach-s3c64xx/include/mach/regs-modem.h +++ b/arch/arm/mach-s3c64xx/regs-modem.h @@ -1,5 +1,4 @@ -/* arch/arm/plat-s3c64xx/include/plat/regs-modem.h - * +/* * Copyright 2008 Openmoko, Inc. * Copyright 2008 Simtec Electronics * http://armlinux.simtec.co.uk/ @@ -12,10 +11,10 @@ * published by the Free Software Foundation. */ -#ifndef __PLAT_S3C64XX_REGS_MODEM_H -#define __PLAT_S3C64XX_REGS_MODEM_H __FILE__ +#ifndef __MACH_S3C64XX_REGS_MODEM_H +#define __MACH_S3C64XX_REGS_MODEM_H __FILE__ -#define S3C64XX_MODEMREG(x) (S3C64XX_VA_MODEM + (x)) +#define S3C64XX_MODEMREG(x) (S3C64XX_VA_MODEM + (x)) #define S3C64XX_MODEM_INT2AP S3C64XX_MODEMREG(0x0) #define S3C64XX_MODEM_INT2MODEM S3C64XX_MODEMREG(0x4) @@ -28,4 +27,4 @@ #define MIFPCON_INT2M_LEVEL (1 << 4) #define MIFPCON_LCD_BYPASS (1 << 3) -#endif /* __PLAT_S3C64XX_REGS_MODEM_H */ +#endif /* __MACH_S3C64XX_REGS_MODEM_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-srom.h b/arch/arm/mach-s3c64xx/regs-srom.h index 756731b3629..d56f3386eb0 100644 --- a/arch/arm/mach-s3c64xx/include/mach/regs-srom.h +++ b/arch/arm/mach-s3c64xx/regs-srom.h @@ -1,5 +1,4 @@ -/* arch/arm/plat-s3c64xx/include/plat/regs-srom.h - * +/* * Copyright 2009 Andy Green <andy@warmcat.com> * * S3C64XX SROM definitions @@ -9,8 +8,8 @@ * published by the Free Software Foundation. */ -#ifndef __PLAT_REGS_SROM_H -#define __PLAT_REGS_SROM_H __FILE__ +#ifndef __MACH_S3C64XX_REGS_SROM_H +#define __MACH_S3C64XX_REGS_SROM_H __FILE__ #define S3C64XX_SROMREG(x) (S3C_VA_MEM + (x)) @@ -29,7 +28,7 @@ #define S3C64XX_SROM_BW__DATAWIDTH__SHIFT 0 #define S3C64XX_SROM_BW__WAITENABLE__SHIFT 2 #define S3C64XX_SROM_BW__BYTEENABLE__SHIFT 3 -#define S3C64XX_SROM_BW__CS_MASK 0xf +#define S3C64XX_SROM_BW__CS_MASK 0xf #define S3C64XX_SROM_BW__NCS0__SHIFT 0 #define S3C64XX_SROM_BW__NCS1__SHIFT 4 @@ -56,4 +55,4 @@ #define S3C64XX_SROM_BCX__TACS__SHIFT 28 #define S3C64XX_SROM_BCX__TACS__MASK 0xf -#endif /* _PLAT_REGS_SROM_H */ +#endif /* __MACH_S3C64XX_REGS_SROM_H */ diff --git a/arch/arm/mach-s3c64xx/regs-sys.h b/arch/arm/mach-s3c64xx/regs-sys.h new file mode 100644 index 00000000000..8c411fbb0cd --- /dev/null +++ b/arch/arm/mach-s3c64xx/regs-sys.h @@ -0,0 +1,30 @@ +/* + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * http://armlinux.simtec.co.uk/ + * + * S3C64XX system register definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __MACH_S3C64XX_REGS_SYS_H +#define __MACH_S3C64XX_REGS_SYS_H __FILE__ + +#define S3C_SYSREG(x) (S3C_VA_SYS + (x)) + +#define S3C64XX_AHB_CON0 S3C_SYSREG(0x100) +#define S3C64XX_AHB_CON1 S3C_SYSREG(0x104) +#define S3C64XX_AHB_CON2 S3C_SYSREG(0x108) + +#define S3C64XX_SDMA_SEL S3C_SYSREG(0x110) + +#define S3C64XX_OTHERS S3C_SYSREG(0x900) + +#define S3C64XX_OTHERS_USBMASK (1 << 16) +#define S3C64XX_OTHERS_SYNCMUXSEL (1 << 6) + +#endif /* __MACH_S3C64XX_REGS_SYS_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-syscon-power.h b/arch/arm/mach-s3c64xx/regs-syscon-power.h index 270d96ac970..6e16b3404da 100644 --- a/arch/arm/mach-s3c64xx/include/mach/regs-syscon-power.h +++ b/arch/arm/mach-s3c64xx/regs-syscon-power.h @@ -1,5 +1,4 @@ -/* arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h - * +/* * Copyright 2008 Openmoko, Inc. * Copyright 2008 Simtec Electronics * http://armlinux.simtec.co.uk/ @@ -12,8 +11,8 @@ * published by the Free Software Foundation. */ -#ifndef __PLAT_S3C64XX_REGS_SYSCON_POWER_H -#define __PLAT_S3C64XX_REGS_SYSCON_POWER_H __FILE__ +#ifndef __MACH_S3C64XX_REGS_SYSCON_POWER_H +#define __MACH_S3C64XX_REGS_SYSCON_POWER_H __FILE__ #define S3C64XX_PWR_CFG S3C_SYSREG(0x804) @@ -113,4 +112,4 @@ #define S3C64XX_INFORM2 S3C_SYSREG(0xA08) #define S3C64XX_INFORM3 S3C_SYSREG(0xA0C) -#endif /* __PLAT_S3C64XX_REGS_SYSCON_POWER_H */ +#endif /* __MACH_S3C64XX_REGS_SYSCON_POWER_H */ diff --git a/arch/arm/mach-s3c64xx/s3c6400.c b/arch/arm/mach-s3c64xx/s3c6400.c index 4869714c6f1..8c42807bf57 100644 --- a/arch/arm/mach-s3c64xx/s3c6400.c +++ b/arch/arm/mach-s3c64xx/s3c6400.c @@ -9,6 +9,10 @@ * published by the Free Software Foundation. */ +/* + * NOTE: Code in this file is not used when booting with Device Tree support. + */ + #include <linux/kernel.h> #include <linux/types.h> #include <linux/interrupt.h> @@ -19,7 +23,9 @@ #include <linux/io.h> #include <linux/device.h> #include <linux/serial_core.h> +#include <linux/serial_s3c.h> #include <linux/platform_device.h> +#include <linux/of.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -29,7 +35,6 @@ #include <asm/irq.h> #include <plat/cpu-freq.h> -#include <plat/regs-serial.h> #include <mach/regs-clock.h> #include <plat/cpu.h> @@ -58,12 +63,6 @@ void __init s3c6400_map_io(void) s3c64xx_onenand1_setname("s3c6400-onenand"); } -void __init s3c6400_init_clocks(int xtal) -{ - s3c64xx_register_clocks(xtal, S3C6400_CLKDIV0_ARM_MASK); - s3c64xx_setup_clocks(); -} - void __init s3c6400_init_irq(void) { /* VIC0 does not have IRQS 5..7, @@ -82,6 +81,10 @@ static struct device s3c6400_dev = { static int __init s3c6400_core_init(void) { + /* Not applicable when using DT. */ + if (of_have_populated_dt()) + return 0; + return subsys_system_register(&s3c6400_subsys, NULL); } diff --git a/arch/arm/mach-s3c64xx/s3c6410.c b/arch/arm/mach-s3c64xx/s3c6410.c index 31c29fdf180..5be3f09bac9 100644 --- a/arch/arm/mach-s3c64xx/s3c6410.c +++ b/arch/arm/mach-s3c64xx/s3c6410.c @@ -10,6 +10,10 @@ * published by the Free Software Foundation. */ +/* + * NOTE: Code in this file is not used when booting with Device Tree support. + */ + #include <linux/kernel.h> #include <linux/types.h> #include <linux/interrupt.h> @@ -20,7 +24,9 @@ #include <linux/io.h> #include <linux/device.h> #include <linux/serial_core.h> +#include <linux/serial_s3c.h> #include <linux/platform_device.h> +#include <linux/of.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -30,7 +36,6 @@ #include <asm/irq.h> #include <plat/cpu-freq.h> -#include <plat/regs-serial.h> #include <mach/regs-clock.h> #include <plat/cpu.h> @@ -62,13 +67,6 @@ void __init s3c6410_map_io(void) s3c_cfcon_setname("s3c64xx-pata"); } -void __init s3c6410_init_clocks(int xtal) -{ - printk(KERN_DEBUG "%s: initialising clocks\n", __func__); - s3c64xx_register_clocks(xtal, S3C6410_CLKDIV0_ARM_MASK); - s3c64xx_setup_clocks(); -} - void __init s3c6410_init_irq(void) { /* VIC0 is missing IRQ7, VIC1 is fully populated. */ @@ -86,6 +84,10 @@ static struct device s3c6410_dev = { static int __init s3c6410_core_init(void) { + /* Not applicable when using DT. */ + if (of_have_populated_dt()) + return 0; + return subsys_system_register(&s3c6410_subsys, NULL); } diff --git a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c index 2cf80026c58..9d17bff12d4 100644 --- a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c +++ b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c @@ -19,6 +19,7 @@ #include <plat/fb.h> #include <plat/gpio-cfg.h> +#include <mach/gpio-samsung.h> void s3c64xx_fb_gpio_setup_24bpp(void) { diff --git a/arch/arm/mach-s3c64xx/setup-i2c0.c b/arch/arm/mach-s3c64xx/setup-i2c0.c index 241af94a9e7..4b8c1cfdd1f 100644 --- a/arch/arm/mach-s3c64xx/setup-i2c0.c +++ b/arch/arm/mach-s3c64xx/setup-i2c0.c @@ -18,8 +18,9 @@ struct platform_device; /* don't need the contents */ -#include <plat/iic.h> +#include <linux/platform_data/i2c-s3c2410.h> #include <plat/gpio-cfg.h> +#include <mach/gpio-samsung.h> void s3c_i2c0_cfg_gpio(struct platform_device *dev) { diff --git a/arch/arm/mach-s3c64xx/setup-i2c1.c b/arch/arm/mach-s3c64xx/setup-i2c1.c index 3d13a961986..cd1df71ee13 100644 --- a/arch/arm/mach-s3c64xx/setup-i2c1.c +++ b/arch/arm/mach-s3c64xx/setup-i2c1.c @@ -18,8 +18,9 @@ struct platform_device; /* don't need the contents */ -#include <plat/iic.h> +#include <linux/platform_data/i2c-s3c2410.h> #include <plat/gpio-cfg.h> +#include <mach/gpio-samsung.h> void s3c_i2c1_cfg_gpio(struct platform_device *dev) { diff --git a/arch/arm/mach-s3c64xx/setup-ide.c b/arch/arm/mach-s3c64xx/setup-ide.c index 41b425602d8..689fb72e715 100644 --- a/arch/arm/mach-s3c64xx/setup-ide.c +++ b/arch/arm/mach-s3c64xx/setup-ide.c @@ -17,7 +17,8 @@ #include <mach/map.h> #include <mach/regs-clock.h> #include <plat/gpio-cfg.h> -#include <plat/ata.h> +#include <mach/gpio-samsung.h> +#include <linux/platform_data/ata-samsung_cf.h> void s3c64xx_ide_setup_gpio(void) { diff --git a/arch/arm/mach-s3c64xx/setup-keypad.c b/arch/arm/mach-s3c64xx/setup-keypad.c index 1d4d0ee9e87..6ad9a89dfdd 100644 --- a/arch/arm/mach-s3c64xx/setup-keypad.c +++ b/arch/arm/mach-s3c64xx/setup-keypad.c @@ -13,6 +13,7 @@ #include <linux/gpio.h> #include <plat/gpio-cfg.h> #include <plat/keypad.h> +#include <mach/gpio-samsung.h> void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) { diff --git a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c index 6eac071afae..f426b7a16c1 100644 --- a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c +++ b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c @@ -20,6 +20,7 @@ #include <plat/gpio-cfg.h> #include <plat/sdhci.h> +#include <mach/gpio-samsung.h> void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) { diff --git a/arch/arm/mach-s3c64xx/setup-spi.c b/arch/arm/mach-s3c64xx/setup-spi.c index d9592ad7a82..5fd1a315c90 100644 --- a/arch/arm/mach-s3c64xx/setup-spi.c +++ b/arch/arm/mach-s3c64xx/setup-spi.c @@ -9,19 +9,11 @@ */ #include <linux/gpio.h> -#include <linux/platform_device.h> - #include <plat/gpio-cfg.h> -#include <plat/s3c64xx-spi.h> +#include <mach/gpio-samsung.h> #ifdef CONFIG_S3C64XX_DEV_SPI0 -struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = { - .fifo_lvl_mask = 0x7f, - .rx_lvl_offset = 13, - .tx_st_done = 21, -}; - -int s3c64xx_spi0_cfg_gpio(struct platform_device *dev) +int s3c64xx_spi0_cfg_gpio(void) { s3c_gpio_cfgall_range(S3C64XX_GPC(0), 3, S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); @@ -30,13 +22,7 @@ int s3c64xx_spi0_cfg_gpio(struct platform_device *dev) #endif #ifdef CONFIG_S3C64XX_DEV_SPI1 -struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = { - .fifo_lvl_mask = 0x7f, - .rx_lvl_offset = 13, - .tx_st_done = 21, -}; - -int s3c64xx_spi1_cfg_gpio(struct platform_device *dev) +int s3c64xx_spi1_cfg_gpio(void) { s3c_gpio_cfgall_range(S3C64XX_GPC(4), 3, S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); diff --git a/arch/arm/mach-s3c64xx/setup-usb-phy.c b/arch/arm/mach-s3c64xx/setup-usb-phy.c new file mode 100644 index 00000000000..ca960bda02f --- /dev/null +++ b/arch/arm/mach-s3c64xx/setup-usb-phy.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2011 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim <jy0922.shim@samsung.com> + * + * 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. + * + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <mach/map.h> +#include <plat/cpu.h> +#include <plat/regs-usb-hsotg-phy.h> +#include <plat/usb-phy.h> + +#include "regs-sys.h" + +static int s3c_usb_otgphy_init(struct platform_device *pdev) +{ + struct clk *xusbxti; + u32 phyclk; + + writel(readl(S3C64XX_OTHERS) | S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS); + + /* set clock frequency for PLL */ + phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK; + + xusbxti = clk_get(&pdev->dev, "xusbxti"); + if (xusbxti && !IS_ERR(xusbxti)) { + switch (clk_get_rate(xusbxti)) { + case 12 * MHZ: + phyclk |= S3C_PHYCLK_CLKSEL_12M; + break; + case 24 * MHZ: + phyclk |= S3C_PHYCLK_CLKSEL_24M; + break; + default: + case 48 * MHZ: + /* default reference clock */ + break; + } + clk_put(xusbxti); + } + + /* TODO: select external clock/oscillator */ + writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK); + + /* set to normal OTG PHY */ + writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR); + mdelay(1); + + /* reset OTG PHY and Link */ + writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK, + S3C_RSTCON); + udelay(20); /* at-least 10uS */ + writel(0, S3C_RSTCON); + + return 0; +} + +static int s3c_usb_otgphy_exit(struct platform_device *pdev) +{ + writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN | + S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR); + + writel(readl(S3C64XX_OTHERS) & ~S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS); + + return 0; +} + +int s5p_usb_phy_init(struct platform_device *pdev, int type) +{ + if (type == USB_PHY_TYPE_DEVICE) + return s3c_usb_otgphy_init(pdev); + + return -EINVAL; +} + +int s5p_usb_phy_exit(struct platform_device *pdev, int type) +{ + if (type == USB_PHY_TYPE_DEVICE) + return s3c_usb_otgphy_exit(pdev); + + return -EINVAL; +} |
