diff options
Diffstat (limited to 'arch/arm/plat-samsung')
137 files changed, 6514 insertions, 9217 deletions
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index be72100b81b..301b892d97d 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -6,42 +6,44 @@ config PLAT_SAMSUNG bool - depends on PLAT_S3C24XX || ARCH_S3C64XX || PLAT_S5P - select NO_IOPORT + depends on PLAT_S3C24XX || ARCH_S3C64XX || PLAT_S5P || ARCH_EXYNOS default y + select GENERIC_IRQ_CHIP + select NO_IOPORT_MAP help Base platform code for all Samsung SoC based systems -if PLAT_SAMSUNG - -# boot configurations - -comment "Boot options" - -config S3C_BOOT_WATCHDOG - bool "S3C Initialisation watchdog" - depends on S3C2410_WATCHDOG +config PLAT_S5P + bool + depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210) + default y + select ARCH_REQUIRE_GPIOLIB + select ARM_VIC + select NO_IOPORT_MAP + select PLAT_SAMSUNG + select S3C_GPIO_TRACK + select S5P_GPIO_DRVSTR + select SAMSUNG_CLKSRC if !COMMON_CLK help - Say y to enable the watchdog during the kernel decompression - stage. If the kernel fails to uncompress, then the watchdog - will trigger a reset and the system should restart. + Base platform code for Samsung's S5P series SoC. -config S3C_BOOT_ERROR_RESET - bool "S3C Reboot on decompression error" +config SAMSUNG_PM + bool + depends on PM && (PLAT_S3C24XX || ARCH_S3C64XX || ARCH_S5P64X0 || S5P_PM) + default y help - Say y here to use the watchdog to reset the system if the - kernel decompressor detects an error during decompression. + Base platform power management code for samsung code -config S3C_BOOT_UART_FORCE_FIFO - bool "Force UART FIFO on during boot process" - default y - help - Say Y here to force the UART FIFOs on during the kernel - uncompressor +if PLAT_SAMSUNG +menu "Samsung Common options" +# boot configurations + +comment "Boot options" config S3C_LOWLEVEL_UART_PORT int "S3C UART to use for low-level messages" + depends on ARCH_S3C64XX default 0 help Choice of which UART port to use for the low-level messages, @@ -49,67 +51,56 @@ config S3C_LOWLEVEL_UART_PORT this configuration should be between zero and two. The port must have been initialised by the boot-loader before use. -# clock options - -config SAMSUNG_CLKSRC - bool +config SAMSUNG_ATAGS + def_bool n + depends on !ARCH_MULTIPLATFORM + depends on ATAGS help - Select the clock code for the clksrc implementation - used by newer systems such as the S3C64XX. - -# options for IRQ support + This option enables ATAGS based boot support code for + Samsung platforms, including static platform devices, legacy + clock, timer and interrupt initialization, etc. -config SAMSUNG_IRQ_VIC_TIMER - bool - help - Internal configuration to build the VIC timer interrupt code. + Platforms that support only DT based boot need not to select + this option. -config SAMSUNG_IRQ_UART - bool - help - Internal configuration to build the IRQ UART demux code. +if SAMSUNG_ATAGS -# options for gpio configuration support +# clock options -config SAMSUNG_GPIOLIB_4BIT +config SAMSUNG_CLOCK bool - help - GPIOlib file contains the 4 bit modification functions for gpio - configuration. GPIOlib shall be compiled only for S3C64XX and S5P - series of processors. + default y if !COMMON_CLK -config S3C_GPIO_CFG_S3C24XX +config SAMSUNG_CLKSRC bool help - Internal configuration to enable S3C24XX style GPIO configuration - functions. + Select the clock code for the clksrc implementation + used by newer systems such as the S3C64XX. -config S3C_GPIO_CFG_S3C64XX - bool +config S5P_CLOCK + def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210) help - Internal configuration to enable S3C64XX style GPIO configuration - functions. + Support common clock part for ARCH_S5P and ARCH_EXYNOS SoCs -config S3C_GPIO_PULL_UPDOWN - bool - help - Internal configuration to enable the correct GPIO pull helper +# options for IRQ support -config S3C_GPIO_PULL_S3C2443 - bool - select S3C_GPIO_PULL_UPDOWN +config S5P_IRQ + def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210) help - Internal configuration to enable the correct GPIO pull helper for S3C2443-style GPIO + Support common interrupt part for ARCH_S5P SoCs -config S3C_GPIO_PULL_DOWN +config S5P_EXT_INT bool help - Internal configuration to enable the correct GPIO pull helper + Use the external interrupts (other than GPIO interrupts.) + Note: Do not choose this for S5P6440 and S5P6450. -config S3C_GPIO_PULL_UP +config S5P_GPIO_INT bool help - Internal configuration to enable the correct GPIO pull helper + Common code for the GPIO interrupts (other than external interrupts.) + +# options for gpio configuration support config S5P_GPIO_DRVSTR bool @@ -119,12 +110,20 @@ config S5P_GPIO_DRVSTR config SAMSUNG_GPIO_EXTRA int "Number of additional GPIO pins" + default 128 if SAMSUNG_GPIO_EXTRA128 + default 64 if SAMSUNG_GPIO_EXTRA64 default 0 help Use additional GPIO space in addition to the GPIO's the SOC provides. This allows expanding the GPIO space for use with GPIO expanders. +config SAMSUNG_GPIO_EXTRA64 + bool + +config SAMSUNG_GPIO_EXTRA128 + bool + config S3C_GPIO_SPACE int "Space between gpio banks" default 0 @@ -140,6 +139,12 @@ config S3C_GPIO_TRACK Internal configuration option to enable the s3c specific gpio chip tracking if the platform requires it. +# uart options + +config S5P_DEV_UART + def_bool y + depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210) + # ADC driver config S3C_ADC @@ -228,7 +233,7 @@ config S3C_DEV_USB_HSOTG config S3C_DEV_WDT bool - default y if ARCH_S3C2410 + default y if ARCH_S3C24XX help Complie in platform device definition for Watchdog Timer @@ -257,11 +262,23 @@ config SAMSUNG_DEV_IDE help Compile in platform device definitions for IDE -config S3C64XX_DEV_SPI +config S3C64XX_DEV_SPI0 bool help Compile in platform device definitions for S3C64XX's type - SPI controllers. + SPI controller 0 + +config S3C64XX_DEV_SPI1 + bool + help + Compile in platform device definitions for S3C64XX's type + SPI controller 1 + +config S3C64XX_DEV_SPI2 + bool + help + Compile in platform device definitions for S3C64XX's type + SPI controller 2 config SAMSUNG_DEV_TS bool @@ -275,17 +292,89 @@ config SAMSUNG_DEV_KEYPAD config SAMSUNG_DEV_PWM bool - default y if ARCH_S3C2410 + default y if ARCH_S3C24XX help Compile in platform device definition for PWM Timer +config SAMSUNG_DEV_BACKLIGHT + bool + depends on SAMSUNG_DEV_PWM + help + Compile in platform device definition LCD backlight with PWM Timer + +config S5P_DEV_CSIS0 + bool + help + Compile in platform device definitions for MIPI-CSIS channel 0 + +config S5P_DEV_CSIS1 + bool + help + Compile in platform device definitions for MIPI-CSIS channel 1 + +config S5P_DEV_FIMC0 + bool + help + Compile in platform device definitions for FIMC controller 0 + +config S5P_DEV_FIMC1 + bool + help + Compile in platform device definitions for FIMC controller 1 + +config S5P_DEV_FIMC2 + bool + help + Compile in platform device definitions for FIMC controller 2 + +config S5P_DEV_FIMC3 + bool + help + Compile in platform device definitions for FIMC controller 3 + +config S5P_DEV_FIMD0 + bool + help + Compile in platform device definitions for FIMD controller 0 + +config S5P_DEV_G2D + bool + help + Compile in platform device definitions for G2D device + +config S5P_DEV_I2C_HDMIPHY + bool + help + Compile in platform device definitions for I2C HDMIPHY controller + +config S5P_DEV_JPEG + bool + help + Compile in platform device definitions for JPEG codec + +config S5P_DEV_ONENAND + bool + help + Compile in platform device definition for OneNAND controller + +config S5P_DEV_TV + bool + help + Compile in platform device definition for TV interface + config S3C24XX_PWM bool "PWM device support" - select HAVE_PWM + select PWM + select PWM_SAMSUNG help Support for exporting the PWM timer blocks via the pwm device system +config S3C_SETUP_CAMIF + bool + help + Compile in common setup code for S3C CAMIF devices + # DMA config S3C_DMA @@ -293,17 +382,39 @@ config S3C_DMA help Internal configuration for S3C DMA core -config S3C_PL330_DMA +config S5P_IRQ_PM + bool + default y if S5P_PM + help + Legacy IRQ power management for S5P platforms + +config SAMSUNG_PM_GPIO + bool + default y if GPIO_SAMSUNG && PM + help + Include legacy GPIO power management code for platforms not using + pinctrl-samsung driver. + +config SAMSUNG_DMADEV + bool "Use legacy Samsung DMA abstraction" + depends on CPU_S5PV210 || CPU_S5PC100 || ARCH_S5P64X0 || ARCH_S3C64XX + select DMADEVICES + default y + help + Use DMA device engine for PL330 DMAC. + +endif + +config S5P_DEV_MFC bool - select PL330 help - S3C DMA API Driver for PL330 DMAC. + Compile in setup memory (init) code for MFC comment "Power management" config SAMSUNG_PM_DEBUG bool "S3C2410 PM Suspend debug" - depends on PM + depends on PM && DEBUG_KERNEL && DEBUG_S3C_UART help Say Y here if you want verbose debugging from the PM Suspend and Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> @@ -320,7 +431,8 @@ config S3C_PM_DEBUG_LED_SMDK config SAMSUNG_PM_CHECK bool "S3C2410 PM Suspend Memory CRC" - depends on PM && CRC32 + depends on PM + select CRC32 help Enable the PM code's memory area checksum over sleep. This option will generate CRCs of all blocks of memory, and store them before @@ -352,12 +464,31 @@ config SAMSUNG_WAKEMASK and above. This code allows a set of interrupt to wakeup-mask mappings. See <plat/wakeup-mask.h> -comment "Power Domain" +config SAMSUNG_WDT_RESET + bool + help + Compile support for system restart by triggering watchdog reset. + Used on SoCs that do not provide dedicated reset control. -config SAMSUNG_PD - bool "Samsung Power Domain" - depends on PM_RUNTIME +config S5P_PM + bool help - Say Y here if you want to control Power Domain by Runtime PM. + Common code for power management support on S5P and newer SoCs + Note: Do not select this for S5P6440 and S5P6450. + +config S5P_SLEEP + bool + help + Internal config node to apply common S5P sleep management code. + Can be selected by S5P and newer SoCs with similar sleep procedure. + +config DEBUG_S3C_UART + depends on PLAT_SAMSUNG + int + default "0" if DEBUG_S3C_UART0 + default "1" if DEBUG_S3C_UART1 + default "2" if DEBUG_S3C_UART2 + default "3" if DEBUG_S3C_UART3 +endmenu endif diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index e9de58a2e29..5e5beaa9ae1 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -1,9 +1,12 @@ -# arch/arm/plat-s3c64xx/Makefile +# arch/arm/plat-samsung/Makefile # # Copyright 2009 Simtec Electronics # # Licensed under GPLv2 +ccflags-$(CONFIG_ARCH_MULTI_V7) += -I$(srctree)/$(src)/include +ccflags-$(CONFIG_ARCH_EXYNOS) += -I$(srctree)/arch/arm/mach-exynos/include + obj-y := obj-m := obj-n := dummy.o @@ -11,19 +14,16 @@ obj- := # Objects we always build independent of SoC choice -obj-y += init.o -obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o -obj-y += clock.o -obj-y += pwm-clock.o -obj-y += gpio.o -obj-y += gpio-config.o -obj-y += dev-asocdma.o +obj-y += init.o cpu.o + +obj-$(CONFIG_SAMSUNG_CLOCK) += clock.o -obj-$(CONFIG_SAMSUNG_GPIOLIB_4BIT) += gpiolib.o obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o +obj-$(CONFIG_S5P_CLOCK) += s5p-clock.o -obj-$(CONFIG_SAMSUNG_IRQ_UART) += irq-uart.o -obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o +obj-$(CONFIG_S5P_IRQ) += s5p-irq.o +obj-$(CONFIG_S5P_EXT_INT) += s5p-irq-eint.o +obj-$(CONFIG_S5P_GPIO_INT) += s5p-irq-gpioint.o # ADC @@ -31,54 +31,34 @@ obj-$(CONFIG_S3C_ADC) += adc.o # devices -obj-y += platformdata.o - -obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o -obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o -obj-$(CONFIG_S3C_DEV_HSMMC2) += dev-hsmmc2.o -obj-$(CONFIG_S3C_DEV_HSMMC3) += dev-hsmmc3.o -obj-$(CONFIG_S3C_DEV_HWMON) += dev-hwmon.o -obj-y += dev-i2c0.o -obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o -obj-$(CONFIG_S3C_DEV_I2C2) += dev-i2c2.o -obj-$(CONFIG_S3C_DEV_I2C3) += dev-i2c3.o -obj-$(CONFIG_S3C_DEV_I2C4) += dev-i2c4.o -obj-$(CONFIG_S3C_DEV_I2C5) += dev-i2c5.o -obj-$(CONFIG_S3C_DEV_I2C6) += dev-i2c6.o -obj-$(CONFIG_S3C_DEV_I2C7) += dev-i2c7.o -obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o -obj-y += dev-uart.o -obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o -obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o -obj-$(CONFIG_S3C_DEV_WDT) += dev-wdt.o -obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o -obj-$(CONFIG_S3C_DEV_ONENAND) += dev-onenand.o -obj-$(CONFIG_S3C_DEV_RTC) += dev-rtc.o - -obj-$(CONFIG_SAMSUNG_DEV_ADC) += dev-adc.o -obj-$(CONFIG_SAMSUNG_DEV_IDE) += dev-ide.o -obj-$(CONFIG_SAMSUNG_DEV_TS) += dev-ts.o -obj-$(CONFIG_SAMSUNG_DEV_KEYPAD) += dev-keypad.o -obj-$(CONFIG_SAMSUNG_DEV_PWM) += dev-pwm.o +obj-$(CONFIG_SAMSUNG_ATAGS) += platformdata.o + +obj-$(CONFIG_SAMSUNG_ATAGS) += devs.o +obj-$(CONFIG_SAMSUNG_ATAGS) += dev-uart.o +obj-$(CONFIG_S5P_DEV_MFC) += s5p-dev-mfc.o +obj-$(CONFIG_S5P_DEV_UART) += s5p-dev-uart.o + +obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o + +obj-$(CONFIG_S3C_SETUP_CAMIF) += setup-camif.o # DMA support -obj-$(CONFIG_S3C_DMA) += dma.o +obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o -obj-$(CONFIG_S3C_PL330_DMA) += s3c-pl330.o +obj-$(CONFIG_SAMSUNG_DMADEV) += dma-ops.o # PM support -obj-$(CONFIG_PM) += pm.o -obj-$(CONFIG_PM) += pm-gpio.o +obj-$(CONFIG_PM_SLEEP) += pm-common.o +obj-$(CONFIG_SAMSUNG_PM) += pm.o +obj-$(CONFIG_SAMSUNG_PM_GPIO) += pm-gpio.o obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o +obj-$(CONFIG_SAMSUNG_PM_DEBUG) += pm-debug.o obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o +obj-$(CONFIG_SAMSUNG_WDT_RESET) += watchdog-reset.o -# PD support - -obj-$(CONFIG_SAMSUNG_PD) += pd.o - -# PWM support - -obj-$(CONFIG_HAVE_PWM) += pwm.o +obj-$(CONFIG_S5P_PM) += s5p-pm.o +obj-$(CONFIG_S5P_IRQ_PM) += s5p-irq-pm.o +obj-$(CONFIG_S5P_SLEEP) += s5p-sleep.o diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c index e8f2be2d67f..79690f2f6d3 100644 --- a/arch/arm/plat-samsung/adc.c +++ b/arch/arm/plat-samsung/adc.c @@ -21,6 +21,7 @@ #include <linux/clk.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <linux/regulator/consumer.h> #include <plat/regs-adc.h> #include <plat/adc.h> @@ -39,8 +40,11 @@ */ enum s3c_cpu_type { - TYPE_S3C24XX, - TYPE_S3C64XX + TYPE_ADCV1, /* S3C24XX */ + TYPE_ADCV11, /* S3C2443 */ + TYPE_ADCV12, /* S3C2416, S3C2450 */ + TYPE_ADCV2, /* S3C64XX, S5P64X0, S5PC100 */ + TYPE_ADCV3, /* S5PV210, S5PC110, EXYNOS4210 */ }; struct s3c_adc_client { @@ -71,6 +75,7 @@ struct adc_device { unsigned int prescale; int irq; + struct regulator *vdd; }; static struct adc_device *adc_dev; @@ -91,15 +96,24 @@ static inline void s3c_adc_select(struct adc_device *adc, struct s3c_adc_client *client) { unsigned con = readl(adc->regs + S3C2410_ADCCON); + enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data; client->select_cb(client, 1); - con &= ~S3C2410_ADCCON_MUXMASK; + if (cpu == TYPE_ADCV1 || cpu == TYPE_ADCV2) + con &= ~S3C2410_ADCCON_MUXMASK; con &= ~S3C2410_ADCCON_STDBM; con &= ~S3C2410_ADCCON_STARTMASK; - if (!client->is_ts) - con |= S3C2410_ADCCON_SELMUX(client->channel); + if (!client->is_ts) { + if (cpu == TYPE_ADCV3) + writel(client->channel & 0xf, adc->regs + S5P_ADCMUX); + else if (cpu == TYPE_ADCV11 || cpu == TYPE_ADCV12) + writel(client->channel & 0xf, + adc->regs + S3C2443_ADCMUX); + else + con |= S3C2410_ADCCON_SELMUX(client->channel); + } writel(con, adc->regs + S3C2410_ADCCON); } @@ -143,11 +157,13 @@ int s3c_adc_start(struct s3c_adc_client *client, return -EINVAL; } - if (client->is_ts && adc->ts_pend) - return -EAGAIN; - spin_lock_irqsave(&adc->lock, flags); + if (client->is_ts && adc->ts_pend) { + spin_unlock_irqrestore(&adc->lock, flags); + return -EAGAIN; + } + client->channel = channel; client->nr_samples = nr_samples; @@ -285,13 +301,13 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw) client->nr_samples--; - if (cpu == TYPE_S3C64XX) { - /* S3C64XX ADC resolution is 12-bit */ - data0 &= 0xfff; - data1 &= 0xfff; - } else { + if (cpu == TYPE_ADCV1 || cpu == TYPE_ADCV11) { data0 &= 0x3ff; data1 &= 0x3ff; + } else { + /* S3C2416/S3C64XX/S5P ADC resolution is 12-bit */ + data0 &= 0xfff; + data1 &= 0xfff; } if (client->convert_cb) @@ -312,7 +328,7 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw) } exit: - if (cpu == TYPE_S3C64XX) { + if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3) { /* Clear ADC interrupt */ writel(0, adc->regs + S3C64XX_ADCCLRINT); } @@ -324,10 +340,11 @@ static int s3c_adc_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct adc_device *adc; struct resource *regs; + enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data; int ret; unsigned tmp; - adc = kzalloc(sizeof(struct adc_device), GFP_KERNEL); + adc = devm_kzalloc(dev, sizeof(struct adc_device), GFP_KERNEL); if (adc == NULL) { dev_err(dev, "failed to allocate adc_device\n"); return -ENOMEM; @@ -338,47 +355,50 @@ static int s3c_adc_probe(struct platform_device *pdev) adc->pdev = pdev; adc->prescale = S3C2410_ADCCON_PRSCVL(49); + adc->vdd = devm_regulator_get(dev, "vdd"); + if (IS_ERR(adc->vdd)) { + dev_err(dev, "operating without regulator \"vdd\" .\n"); + return PTR_ERR(adc->vdd); + } + adc->irq = platform_get_irq(pdev, 1); if (adc->irq <= 0) { dev_err(dev, "failed to get adc irq\n"); - ret = -ENOENT; - goto err_alloc; + return -ENOENT; } - ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc); + ret = devm_request_irq(dev, adc->irq, s3c_adc_irq, 0, dev_name(dev), + adc); if (ret < 0) { dev_err(dev, "failed to attach adc irq\n"); - goto err_alloc; + return ret; } - adc->clk = clk_get(dev, "adc"); + adc->clk = devm_clk_get(dev, "adc"); if (IS_ERR(adc->clk)) { dev_err(dev, "failed to get adc clock\n"); - ret = PTR_ERR(adc->clk); - goto err_irq; + return PTR_ERR(adc->clk); } regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) { - dev_err(dev, "failed to find registers\n"); - ret = -ENXIO; - goto err_clk; - } + adc->regs = devm_ioremap_resource(dev, regs); + if (IS_ERR(adc->regs)) + return PTR_ERR(adc->regs); - adc->regs = ioremap(regs->start, resource_size(regs)); - if (!adc->regs) { - dev_err(dev, "failed to map registers\n"); - ret = -ENXIO; - goto err_clk; - } + ret = regulator_enable(adc->vdd); + if (ret) + return ret; clk_enable(adc->clk); tmp = adc->prescale | S3C2410_ADCCON_PRSCEN; - if (platform_get_device_id(pdev)->driver_data == TYPE_S3C64XX) { - /* Enable 12-bit ADC resolution */ + + /* Enable 12-bit ADC resolution */ + if (cpu == TYPE_ADCV12) + tmp |= S3C2416_ADCCON_RESSEL; + if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3) tmp |= S3C64XX_ADCCON_RESSEL; - } + writel(tmp, adc->regs + S3C2410_ADCCON); dev_info(dev, "attached adc driver\n"); @@ -387,34 +407,23 @@ static int s3c_adc_probe(struct platform_device *pdev) adc_dev = adc; return 0; - - err_clk: - clk_put(adc->clk); - - err_irq: - free_irq(adc->irq, adc); - - err_alloc: - kfree(adc); - return ret; } -static int __devexit s3c_adc_remove(struct platform_device *pdev) +static int s3c_adc_remove(struct platform_device *pdev) { struct adc_device *adc = platform_get_drvdata(pdev); - iounmap(adc->regs); - free_irq(adc->irq, adc); clk_disable(adc->clk); - clk_put(adc->clk); - kfree(adc); + regulator_disable(adc->vdd); return 0; } #ifdef CONFIG_PM -static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state) +static int s3c_adc_suspend(struct device *dev) { + struct platform_device *pdev = container_of(dev, + struct platform_device, dev); struct adc_device *adc = platform_get_drvdata(pdev); unsigned long flags; u32 con; @@ -428,19 +437,35 @@ static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state) disable_irq(adc->irq); spin_unlock_irqrestore(&adc->lock, flags); clk_disable(adc->clk); + regulator_disable(adc->vdd); return 0; } -static int s3c_adc_resume(struct platform_device *pdev) +static int s3c_adc_resume(struct device *dev) { + struct platform_device *pdev = container_of(dev, + struct platform_device, dev); struct adc_device *adc = platform_get_drvdata(pdev); + enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data; + int ret; + unsigned long tmp; + ret = regulator_enable(adc->vdd); + if (ret) + return ret; clk_enable(adc->clk); enable_irq(adc->irq); - writel(adc->prescale | S3C2410_ADCCON_PRSCEN, - adc->regs + S3C2410_ADCCON); + tmp = adc->prescale | S3C2410_ADCCON_PRSCEN; + + /* Enable 12-bit ADC resolution */ + if (cpu == TYPE_ADCV12) + tmp |= S3C2416_ADCCON_RESSEL; + if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3) + tmp |= S3C64XX_ADCCON_RESSEL; + + writel(tmp, adc->regs + S3C2410_ADCCON); return 0; } @@ -453,25 +478,38 @@ static int s3c_adc_resume(struct platform_device *pdev) static struct platform_device_id s3c_adc_driver_ids[] = { { .name = "s3c24xx-adc", - .driver_data = TYPE_S3C24XX, + .driver_data = TYPE_ADCV1, + }, { + .name = "s3c2443-adc", + .driver_data = TYPE_ADCV11, + }, { + .name = "s3c2416-adc", + .driver_data = TYPE_ADCV12, }, { .name = "s3c64xx-adc", - .driver_data = TYPE_S3C64XX, + .driver_data = TYPE_ADCV2, + }, { + .name = "samsung-adc-v3", + .driver_data = TYPE_ADCV3, }, { } }; MODULE_DEVICE_TABLE(platform, s3c_adc_driver_ids); +static const struct dev_pm_ops adc_pm_ops = { + .suspend = s3c_adc_suspend, + .resume = s3c_adc_resume, +}; + static struct platform_driver s3c_adc_driver = { .id_table = s3c_adc_driver_ids, .driver = { .name = "s3c-adc", .owner = THIS_MODULE, + .pm = &adc_pm_ops, }, .probe = s3c_adc_probe, - .remove = __devexit_p(s3c_adc_remove), - .suspend = s3c_adc_suspend, - .resume = s3c_adc_resume, + .remove = s3c_adc_remove, }; static int __init adc_init(void) @@ -485,4 +523,4 @@ static int __init adc_init(void) return ret; } -arch_initcall(adc_init); +module_init(adc_init); diff --git a/arch/arm/plat-samsung/clock-clksrc.c b/arch/arm/plat-samsung/clock-clksrc.c index ae8b8507663..786a4107a15 100644 --- a/arch/arm/plat-samsung/clock-clksrc.c +++ b/arch/arm/plat-samsung/clock-clksrc.c @@ -16,7 +16,7 @@ #include <linux/errno.h> #include <linux/err.h> #include <linux/clk.h> -#include <linux/sysdev.h> +#include <linux/device.h> #include <linux/io.h> #include <plat/clock.h> diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c index 772892826ff..d103ac1a52a 100644 --- a/arch/arm/plat-samsung/clock.c +++ b/arch/arm/plat-samsung/clock.c @@ -33,7 +33,7 @@ #include <linux/errno.h> #include <linux/err.h> #include <linux/platform_device.h> -#include <linux/sysdev.h> +#include <linux/device.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/clk.h> @@ -43,7 +43,6 @@ #include <linux/debugfs.h> #endif -#include <mach/hardware.h> #include <asm/irq.h> #include <plat/cpu-freq.h> @@ -52,7 +51,7 @@ #include <plat/cpu.h> #include <linux/serial_core.h> -#include <plat/regs-serial.h> /* for s3c24xx_uart_devs */ +#include <linux/serial_s3c.h> /* for s3c24xx_uart_devs */ /* clock information */ @@ -64,115 +63,62 @@ static LIST_HEAD(clocks); */ DEFINE_SPINLOCK(clocks_lock); -/* enable and disable calls for use with the clk struct */ - -static int clk_null_enable(struct clk *clk, int enable) -{ - return 0; -} - -static int dev_is_s3c_uart(struct device *dev) +/* Global watchdog clock used by arch_wtd_reset() callback */ +struct clk *s3c2410_wdtclk; +static int __init s3c_wdt_reset_init(void) { - struct platform_device **pdev = s3c24xx_uart_devs; - int i; - for (i = 0; i < ARRAY_SIZE(s3c24xx_uart_devs); i++, pdev++) - if (*pdev && dev == &(*pdev)->dev) - return 1; + s3c2410_wdtclk = clk_get(NULL, "watchdog"); + if (IS_ERR(s3c2410_wdtclk)) + printk(KERN_WARNING "%s: warning: cannot get watchdog clock\n", __func__); return 0; } +arch_initcall(s3c_wdt_reset_init); -/* - * Serial drivers call get_clock() very early, before platform bus - * has been set up, this requires a special check to let them get - * a proper clock - */ - -static int dev_is_platform_device(struct device *dev) -{ - return dev->bus == &platform_bus_type || - (dev->bus == NULL && dev_is_s3c_uart(dev)); -} - -/* Clock API calls */ - -struct clk *clk_get(struct device *dev, const char *id) -{ - struct clk *p; - struct clk *clk = ERR_PTR(-ENOENT); - int idno; - - if (dev == NULL || !dev_is_platform_device(dev)) - idno = -1; - else - idno = to_platform_device(dev)->id; - - spin_lock(&clocks_lock); - - list_for_each_entry(p, &clocks, list) { - if (p->id == idno && - strcmp(id, p->name) == 0 && - try_module_get(p->owner)) { - clk = p; - break; - } - } - - /* check for the case where a device was supplied, but the - * clock that was being searched for is not device specific */ - - if (IS_ERR(clk)) { - list_for_each_entry(p, &clocks, list) { - if (p->id == -1 && strcmp(id, p->name) == 0 && - try_module_get(p->owner)) { - clk = p; - break; - } - } - } - - spin_unlock(&clocks_lock); - return clk; -} +/* enable and disable calls for use with the clk struct */ -void clk_put(struct clk *clk) +static int clk_null_enable(struct clk *clk, int enable) { - module_put(clk->owner); + return 0; } int clk_enable(struct clk *clk) { + unsigned long flags; + if (IS_ERR(clk) || clk == NULL) return -EINVAL; clk_enable(clk->parent); - spin_lock(&clocks_lock); + spin_lock_irqsave(&clocks_lock, flags); if ((clk->usage++) == 0) (clk->enable)(clk, 1); - spin_unlock(&clocks_lock); + spin_unlock_irqrestore(&clocks_lock, flags); return 0; } void clk_disable(struct clk *clk) { + unsigned long flags; + if (IS_ERR(clk) || clk == NULL) return; - spin_lock(&clocks_lock); + spin_lock_irqsave(&clocks_lock, flags); if ((--clk->usage) == 0) (clk->enable)(clk, 0); - spin_unlock(&clocks_lock); + spin_unlock_irqrestore(&clocks_lock, flags); clk_disable(clk->parent); } unsigned long clk_get_rate(struct clk *clk) { - if (IS_ERR(clk)) + if (IS_ERR_OR_NULL(clk)) return 0; if (clk->rate != 0) @@ -189,7 +135,7 @@ unsigned long clk_get_rate(struct clk *clk) long clk_round_rate(struct clk *clk, unsigned long rate) { - if (!IS_ERR(clk) && clk->ops && clk->ops->round_rate) + if (!IS_ERR_OR_NULL(clk) && clk->ops && clk->ops->round_rate) return (clk->ops->round_rate)(clk, rate); return rate; @@ -197,9 +143,10 @@ long clk_round_rate(struct clk *clk, unsigned long rate) int clk_set_rate(struct clk *clk, unsigned long rate) { + unsigned long flags; int ret; - if (IS_ERR(clk)) + if (IS_ERR_OR_NULL(clk)) return -EINVAL; /* We do not default just do a clk->rate = rate as @@ -212,9 +159,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate) if (clk->ops == NULL || clk->ops->set_rate == NULL) return -EINVAL; - spin_lock(&clocks_lock); + spin_lock_irqsave(&clocks_lock, flags); ret = (clk->ops->set_rate)(clk, rate); - spin_unlock(&clocks_lock); + spin_unlock_irqrestore(&clocks_lock, flags); return ret; } @@ -226,23 +173,22 @@ struct clk *clk_get_parent(struct clk *clk) int clk_set_parent(struct clk *clk, struct clk *parent) { + unsigned long flags; int ret = 0; - if (IS_ERR(clk)) + if (IS_ERR_OR_NULL(clk) || IS_ERR_OR_NULL(parent)) return -EINVAL; - spin_lock(&clocks_lock); + spin_lock_irqsave(&clocks_lock, flags); if (clk->ops && clk->ops->set_parent) ret = (clk->ops->set_parent)(clk, parent); - spin_unlock(&clocks_lock); + spin_unlock_irqrestore(&clocks_lock, flags); return ret; } -EXPORT_SYMBOL(clk_get); -EXPORT_SYMBOL(clk_put); EXPORT_SYMBOL(clk_enable); EXPORT_SYMBOL(clk_disable); EXPORT_SYMBOL(clk_get_rate); @@ -265,7 +211,6 @@ struct clk_ops clk_ops_def_setrate = { struct clk clk_xtal = { .name = "xtal", - .id = -1, .rate = 0, .parent = NULL, .ctrlbit = 0, @@ -273,30 +218,25 @@ struct clk clk_xtal = { struct clk clk_ext = { .name = "ext", - .id = -1, }; struct clk clk_epll = { .name = "epll", - .id = -1, }; struct clk clk_mpll = { .name = "mpll", - .id = -1, .ops = &clk_ops_def_setrate, }; struct clk clk_upll = { .name = "upll", - .id = -1, .parent = NULL, .ctrlbit = 0, }; struct clk clk_f = { .name = "fclk", - .id = -1, .rate = 0, .parent = &clk_mpll, .ctrlbit = 0, @@ -304,7 +244,6 @@ struct clk clk_f = { struct clk clk_h = { .name = "hclk", - .id = -1, .rate = 0, .parent = NULL, .ctrlbit = 0, @@ -313,7 +252,6 @@ struct clk clk_h = { struct clk clk_p = { .name = "pclk", - .id = -1, .rate = 0, .parent = NULL, .ctrlbit = 0, @@ -322,7 +260,6 @@ struct clk clk_p = { struct clk clk_usb_bus = { .name = "usb-bus", - .id = -1, .rate = 0, .parent = &clk_upll, }; @@ -330,7 +267,6 @@ struct clk clk_usb_bus = { struct clk s3c24xx_uclk = { .name = "uclk", - .id = -1, }; /* initialise the clock system */ @@ -346,14 +282,11 @@ int s3c24xx_register_clock(struct clk *clk) if (clk->enable == NULL) clk->enable = clk_null_enable; - /* add to the list of available clocks */ - - /* Quick check to see if this clock has already been registered. */ - BUG_ON(clk->list.prev != clk->list.next); - - spin_lock(&clocks_lock); - list_add(&clk->list, &clocks); - spin_unlock(&clocks_lock); + /* fill up the clk_lookup structure and register it*/ + clk->lookup.dev_id = clk->devname; + clk->lookup.con_id = clk->name; + clk->lookup.clk = clk; + clkdev_add(&clk->lookup); return 0; } @@ -455,18 +388,81 @@ int __init s3c24xx_register_baseclocks(unsigned long xtal) static struct dentry *clk_debugfs_root; +static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level) +{ + struct clk *child; + const char *state; + char buf[255] = { 0 }; + int n = 0; + + if (c->name) + n = snprintf(buf, sizeof(buf) - 1, "%s", c->name); + + if (c->devname) + n += snprintf(buf + n, sizeof(buf) - 1 - n, ":%s", c->devname); + + state = (c->usage > 0) ? "on" : "off"; + + seq_printf(s, "%*s%-*s %-6s %-3d %-10lu\n", + level * 3 + 1, "", + 50 - level * 3, buf, + state, c->usage, clk_get_rate(c)); + + list_for_each_entry(child, &clocks, list) { + if (child->parent != c) + continue; + + clock_tree_show_one(s, child, level + 1); + } +} + +static int clock_tree_show(struct seq_file *s, void *data) +{ + struct clk *c; + unsigned long flags; + + seq_printf(s, " clock state ref rate\n"); + seq_printf(s, "----------------------------------------------------\n"); + + spin_lock_irqsave(&clocks_lock, flags); + + list_for_each_entry(c, &clocks, list) + if (c->parent == NULL) + clock_tree_show_one(s, c, 0); + + spin_unlock_irqrestore(&clocks_lock, flags); + return 0; +} + +static int clock_tree_open(struct inode *inode, struct file *file) +{ + return single_open(file, clock_tree_show, inode->i_private); +} + +static const struct file_operations clock_tree_fops = { + .open = clock_tree_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int clock_rate_show(void *data, u64 *val) +{ + struct clk *c = data; + *val = clk_get_rate(c); + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_rate_show, NULL, "%llu\n"); + static int clk_debugfs_register_one(struct clk *c) { int err; - struct dentry *d, *child, *child_tmp; + struct dentry *d; struct clk *pa = c->parent; char s[255]; char *p = s; - p += sprintf(p, "%s", c->name); - - if (c->id >= 0) - sprintf(p, ":%d", c->id); + p += sprintf(p, "%s", c->devname); d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root); if (!d) @@ -480,7 +476,7 @@ static int clk_debugfs_register_one(struct clk *c) goto err_out; } - d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate); + d = debugfs_create_file("rate", S_IRUGO, c->dent, c, &clock_rate_fops); if (!d) { err = -ENOMEM; goto err_out; @@ -488,10 +484,7 @@ static int clk_debugfs_register_one(struct clk *c) return 0; err_out: - d = c->dent; - list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child) - debugfs_remove(child); - debugfs_remove(c->dent); + debugfs_remove_recursive(c->dent); return err; } @@ -518,13 +511,18 @@ static int __init clk_debugfs_init(void) { struct clk *c; struct dentry *d; - int err; + int err = -ENOMEM; d = debugfs_create_dir("clock", NULL); if (!d) return -ENOMEM; clk_debugfs_root = d; + d = debugfs_create_file("clock_tree", S_IRUGO, clk_debugfs_root, NULL, + &clock_tree_fops); + if (!d) + goto err_out; + list_for_each_entry(c, &clocks, list) { err = clk_debugfs_register(c); if (err) diff --git a/arch/arm/plat-samsung/cpu.c b/arch/arm/plat-samsung/cpu.c new file mode 100644 index 00000000000..364963a0a34 --- /dev/null +++ b/arch/arm/plat-samsung/cpu.c @@ -0,0 +1,50 @@ +/* linux/arch/arm/plat-samsung/cpu.c + * + * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Samsung CPU 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/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> + + +#include <mach/map.h> +#include <plat/cpu.h> + +unsigned long samsung_cpu_id; +static unsigned int samsung_cpu_rev; + +unsigned int samsung_rev(void) +{ + return samsung_cpu_rev; +} +EXPORT_SYMBOL(samsung_rev); + +void __init s3c64xx_init_cpu(void) +{ + samsung_cpu_id = __raw_readl(S3C_VA_SYS + 0x118); + if (!samsung_cpu_id) { + /* + * S3C6400 has the ID register in a different place, + * and needs a write before it can be read. + */ + __raw_writel(0x0, S3C_VA_SYS + 0xA1C); + samsung_cpu_id = __raw_readl(S3C_VA_SYS + 0xA1C); + } + + samsung_cpu_rev = 0; +} + +void __init s5p_init_cpu(void __iomem *cpuid_addr) +{ + samsung_cpu_id = __raw_readl(cpuid_addr); + samsung_cpu_rev = samsung_cpu_id & 0xFF; +} diff --git a/arch/arm/plat-samsung/dev-adc.c b/arch/arm/plat-samsung/dev-adc.c deleted file mode 100644 index 9d903d4095e..00000000000 --- a/arch/arm/plat-samsung/dev-adc.c +++ /dev/null @@ -1,46 +0,0 @@ -/* linux/arch/arm/plat-samsung/dev-adc.c - * - * Copyright 2010 Maurus Cuelenaere - * - * S3C64xx series device definition for ADC device - * - * 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/string.h> -#include <linux/platform_device.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -#include <plat/adc.h> -#include <plat/devs.h> -#include <plat/cpu.h> - -static struct resource s3c_adc_resource[] = { - [0] = { - .start = SAMSUNG_PA_ADC, - .end = SAMSUNG_PA_ADC + SZ_256 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_TC, - .end = IRQ_TC, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = IRQ_ADC, - .end = IRQ_ADC, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device s3c_device_adc = { - .name = "samsung-adc", - .id = -1, - .num_resources = ARRAY_SIZE(s3c_adc_resource), - .resource = s3c_adc_resource, -}; diff --git a/arch/arm/plat-samsung/dev-asocdma.c b/arch/arm/plat-samsung/dev-asocdma.c deleted file mode 100644 index a068c4f42d5..00000000000 --- a/arch/arm/plat-samsung/dev-asocdma.c +++ /dev/null @@ -1,25 +0,0 @@ -/* linux/arch/arm/plat-samsung/dev-asocdma.c - * - * Copyright (c) 2010 Samsung Electronics Co. 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. - */ - -#include <linux/platform_device.h> -#include <linux/dma-mapping.h> -#include <plat/devs.h> - -static u64 audio_dmamask = DMA_BIT_MASK(32); - -struct platform_device samsung_asoc_dma = { - .name = "samsung-audio", - .id = -1, - .dev = { - .dma_mask = &audio_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - } -}; -EXPORT_SYMBOL(samsung_asoc_dma); diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c new file mode 100644 index 00000000000..2157c5b539e --- /dev/null +++ b/arch/arm/plat-samsung/dev-backlight.c @@ -0,0 +1,152 @@ +/* linux/arch/arm/plat-samsung/dev-backlight.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Common infrastructure for PWM Backlight for Samsung boards + * + * 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/gpio.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/pwm_backlight.h> + +#include <plat/devs.h> +#include <plat/gpio-cfg.h> +#include <plat/backlight.h> + +struct samsung_bl_drvdata { + struct platform_pwm_backlight_data plat_data; + struct samsung_bl_gpio_info *gpio_info; +}; + +static int samsung_bl_init(struct device *dev) +{ + int ret = 0; + struct platform_pwm_backlight_data *pdata = dev->platform_data; + struct samsung_bl_drvdata *drvdata = container_of(pdata, + struct samsung_bl_drvdata, plat_data); + struct samsung_bl_gpio_info *bl_gpio_info = drvdata->gpio_info; + + ret = gpio_request(bl_gpio_info->no, "Backlight"); + if (ret) { + printk(KERN_ERR "failed to request GPIO for LCD Backlight\n"); + return ret; + } + + /* Configure GPIO pin with specific GPIO function for PWM timer */ + s3c_gpio_cfgpin(bl_gpio_info->no, bl_gpio_info->func); + + return 0; +} + +static void samsung_bl_exit(struct device *dev) +{ + struct platform_pwm_backlight_data *pdata = dev->platform_data; + struct samsung_bl_drvdata *drvdata = container_of(pdata, + struct samsung_bl_drvdata, plat_data); + struct samsung_bl_gpio_info *bl_gpio_info = drvdata->gpio_info; + + s3c_gpio_cfgpin(bl_gpio_info->no, S3C_GPIO_OUTPUT); + gpio_free(bl_gpio_info->no); +} + +/* Initialize few important fields of platform_pwm_backlight_data + * structure with default values. These fields can be overridden by + * board-specific values sent from machine file. + * For ease of operation, these fields are initialized with values + * used by most samsung boards. + * Users has the option of sending info about other parameters + * for their specific boards + */ + +static struct samsung_bl_drvdata samsung_dfl_bl_data __initdata = { + .plat_data = { + .max_brightness = 255, + .dft_brightness = 255, + .pwm_period_ns = 78770, + .enable_gpio = -1, + .init = samsung_bl_init, + .exit = samsung_bl_exit, + }, +}; + +static struct platform_device samsung_dfl_bl_device __initdata = { + .name = "pwm-backlight", +}; + +/* samsung_bl_set - Set board specific data (if any) provided by user for + * PWM Backlight control and register specific PWM and backlight device. + * @gpio_info: structure containing GPIO info for PWM timer + * @bl_data: structure containing Backlight control data + */ +void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, + struct platform_pwm_backlight_data *bl_data) +{ + int ret = 0; + struct platform_device *samsung_bl_device; + struct samsung_bl_drvdata *samsung_bl_drvdata; + struct platform_pwm_backlight_data *samsung_bl_data; + + samsung_bl_device = kmemdup(&samsung_dfl_bl_device, + sizeof(struct platform_device), GFP_KERNEL); + if (!samsung_bl_device) { + printk(KERN_ERR "%s: no memory for platform dev\n", __func__); + return; + } + + samsung_bl_drvdata = kmemdup(&samsung_dfl_bl_data, + sizeof(samsung_dfl_bl_data), GFP_KERNEL); + if (!samsung_bl_drvdata) { + printk(KERN_ERR "%s: no memory for platform dev\n", __func__); + goto err_data; + } + samsung_bl_device->dev.platform_data = &samsung_bl_drvdata->plat_data; + samsung_bl_drvdata->gpio_info = gpio_info; + samsung_bl_data = &samsung_bl_drvdata->plat_data; + + /* Copy board specific data provided by user */ + samsung_bl_data->pwm_id = bl_data->pwm_id; + samsung_bl_device->dev.parent = &samsung_device_pwm.dev; + + if (bl_data->max_brightness) + samsung_bl_data->max_brightness = bl_data->max_brightness; + if (bl_data->dft_brightness) + samsung_bl_data->dft_brightness = bl_data->dft_brightness; + if (bl_data->lth_brightness) + samsung_bl_data->lth_brightness = bl_data->lth_brightness; + if (bl_data->pwm_period_ns) + samsung_bl_data->pwm_period_ns = bl_data->pwm_period_ns; + if (bl_data->enable_gpio >= 0) + samsung_bl_data->enable_gpio = bl_data->enable_gpio; + if (bl_data->init) + samsung_bl_data->init = bl_data->init; + if (bl_data->notify) + samsung_bl_data->notify = bl_data->notify; + if (bl_data->notify_after) + samsung_bl_data->notify_after = bl_data->notify_after; + if (bl_data->exit) + samsung_bl_data->exit = bl_data->exit; + if (bl_data->check_fb) + samsung_bl_data->check_fb = bl_data->check_fb; + + /* Register the Backlight dev */ + ret = platform_device_register(samsung_bl_device); + if (ret) { + printk(KERN_ERR "failed to register backlight device: %d\n", ret); + goto err_plat_reg2; + } + + return; + +err_plat_reg2: + kfree(samsung_bl_data); +err_data: + kfree(samsung_bl_device); + return; +} diff --git a/arch/arm/plat-samsung/dev-fb.c b/arch/arm/plat-samsung/dev-fb.c deleted file mode 100644 index bf60204c629..00000000000 --- a/arch/arm/plat-samsung/dev-fb.c +++ /dev/null @@ -1,73 +0,0 @@ -/* linux/arch/arm/plat-s3c/dev-fb.c - * - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C series device definition for framebuffer device - * - * 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/string.h> -#include <linux/platform_device.h> -#include <linux/fb.h> -#include <linux/gfp.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -#include <plat/fb.h> -#include <plat/devs.h> -#include <plat/cpu.h> - -static struct resource s3c_fb_resource[] = { - [0] = { - .start = S3C_PA_FB, - .end = S3C_PA_FB + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_LCD_VSYNC, - .end = IRQ_LCD_VSYNC, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = IRQ_LCD_FIFO, - .end = IRQ_LCD_FIFO, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = IRQ_LCD_SYSTEM, - .end = IRQ_LCD_SYSTEM, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device s3c_device_fb = { - .name = "s3c-fb", - .id = -1, - .num_resources = ARRAY_SIZE(s3c_fb_resource), - .resource = s3c_fb_resource, - .dev.dma_mask = &s3c_device_fb.dev.coherent_dma_mask, - .dev.coherent_dma_mask = 0xffffffffUL, -}; - -void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd) -{ - struct s3c_fb_platdata *npd; - - if (!pd) { - printk(KERN_ERR "%s: no platform data\n", __func__); - return; - } - - npd = kmemdup(pd, sizeof(struct s3c_fb_platdata), GFP_KERNEL); - if (!npd) - printk(KERN_ERR "%s: no memory for platform data\n", __func__); - - s3c_device_fb.dev.platform_data = npd; -} diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c deleted file mode 100644 index db7a65c7f12..00000000000 --- a/arch/arm/plat-samsung/dev-hsmmc.c +++ /dev/null @@ -1,79 +0,0 @@ -/* linux/arch/arm/plat-s3c/dev-hsmmc.c - * - * Copyright (c) 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C series device definition for hsmmc devices - * - * 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/platform_device.h> -#include <linux/mmc/host.h> - -#include <mach/map.h> -#include <plat/sdhci.h> -#include <plat/devs.h> -#include <plat/cpu.h> - -#define S3C_SZ_HSMMC (0x1000) - -static struct resource s3c_hsmmc_resource[] = { - [0] = { - .start = S3C_PA_HSMMC0, - .end = S3C_PA_HSMMC0 + S3C_SZ_HSMMC - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_HSMMC0, - .end = IRQ_HSMMC0, - .flags = IORESOURCE_IRQ, - } -}; - -static u64 s3c_device_hsmmc_dmamask = 0xffffffffUL; - -struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = { - .max_width = 4, - .host_caps = (MMC_CAP_4_BIT_DATA | - MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), - .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, -}; - -struct platform_device s3c_device_hsmmc0 = { - .name = "s3c-sdhci", - .id = 0, - .num_resources = ARRAY_SIZE(s3c_hsmmc_resource), - .resource = s3c_hsmmc_resource, - .dev = { - .dma_mask = &s3c_device_hsmmc_dmamask, - .coherent_dma_mask = 0xffffffffUL, - .platform_data = &s3c_hsmmc0_def_platdata, - }, -}; - -void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd) -{ - struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata; - - set->cd_type = pd->cd_type; - set->ext_cd_init = pd->ext_cd_init; - set->ext_cd_cleanup = pd->ext_cd_cleanup; - set->ext_cd_gpio = pd->ext_cd_gpio; - set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; - - if (pd->max_width) - set->max_width = pd->max_width; - if (pd->cfg_gpio) - set->cfg_gpio = pd->cfg_gpio; - if (pd->cfg_card) - set->cfg_card = pd->cfg_card; - if (pd->host_caps) - set->host_caps |= pd->host_caps; - if (pd->clk_type) - set->clk_type = pd->clk_type; -} diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c deleted file mode 100644 index 2497321f08d..00000000000 --- a/arch/arm/plat-samsung/dev-hsmmc1.c +++ /dev/null @@ -1,79 +0,0 @@ -/* linux/arch/arm/plat-s3c/dev-hsmmc1.c - * - * Copyright (c) 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C series device definition for hsmmc device 1 - * - * 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/platform_device.h> -#include <linux/mmc/host.h> - -#include <mach/map.h> -#include <plat/sdhci.h> -#include <plat/devs.h> -#include <plat/cpu.h> - -#define S3C_SZ_HSMMC (0x1000) - -static struct resource s3c_hsmmc1_resource[] = { - [0] = { - .start = S3C_PA_HSMMC1, - .end = S3C_PA_HSMMC1 + S3C_SZ_HSMMC - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_HSMMC1, - .end = IRQ_HSMMC1, - .flags = IORESOURCE_IRQ, - } -}; - -static u64 s3c_device_hsmmc1_dmamask = 0xffffffffUL; - -struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = { - .max_width = 4, - .host_caps = (MMC_CAP_4_BIT_DATA | - MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), - .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, -}; - -struct platform_device s3c_device_hsmmc1 = { - .name = "s3c-sdhci", - .id = 1, - .num_resources = ARRAY_SIZE(s3c_hsmmc1_resource), - .resource = s3c_hsmmc1_resource, - .dev = { - .dma_mask = &s3c_device_hsmmc1_dmamask, - .coherent_dma_mask = 0xffffffffUL, - .platform_data = &s3c_hsmmc1_def_platdata, - }, -}; - -void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd) -{ - struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata; - - set->cd_type = pd->cd_type; - set->ext_cd_init = pd->ext_cd_init; - set->ext_cd_cleanup = pd->ext_cd_cleanup; - set->ext_cd_gpio = pd->ext_cd_gpio; - set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; - - if (pd->max_width) - set->max_width = pd->max_width; - if (pd->cfg_gpio) - set->cfg_gpio = pd->cfg_gpio; - if (pd->cfg_card) - set->cfg_card = pd->cfg_card; - if (pd->host_caps) - set->host_caps |= pd->host_caps; - if (pd->clk_type) - set->clk_type = pd->clk_type; -} diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c deleted file mode 100644 index f60aedba417..00000000000 --- a/arch/arm/plat-samsung/dev-hsmmc2.c +++ /dev/null @@ -1,80 +0,0 @@ -/* linux/arch/arm/plat-s3c/dev-hsmmc2.c - * - * Copyright (c) 2009 Samsung Electronics - * Copyright (c) 2009 Maurus Cuelenaere - * - * Based on arch/arm/plat-s3c/dev-hsmmc1.c - * original file Copyright (c) 2008 Simtec Electronics - * - * S3C series device definition for hsmmc device 2 - * - * 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/platform_device.h> -#include <linux/mmc/host.h> - -#include <mach/map.h> -#include <plat/sdhci.h> -#include <plat/devs.h> - -#define S3C_SZ_HSMMC (0x1000) - -static struct resource s3c_hsmmc2_resource[] = { - [0] = { - .start = S3C_PA_HSMMC2, - .end = S3C_PA_HSMMC2 + S3C_SZ_HSMMC - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_HSMMC2, - .end = IRQ_HSMMC2, - .flags = IORESOURCE_IRQ, - } -}; - -static u64 s3c_device_hsmmc2_dmamask = 0xffffffffUL; - -struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = { - .max_width = 4, - .host_caps = (MMC_CAP_4_BIT_DATA | - MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), - .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, -}; - -struct platform_device s3c_device_hsmmc2 = { - .name = "s3c-sdhci", - .id = 2, - .num_resources = ARRAY_SIZE(s3c_hsmmc2_resource), - .resource = s3c_hsmmc2_resource, - .dev = { - .dma_mask = &s3c_device_hsmmc2_dmamask, - .coherent_dma_mask = 0xffffffffUL, - .platform_data = &s3c_hsmmc2_def_platdata, - }, -}; - -void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd) -{ - struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata; - - set->cd_type = pd->cd_type; - set->ext_cd_init = pd->ext_cd_init; - set->ext_cd_cleanup = pd->ext_cd_cleanup; - set->ext_cd_gpio = pd->ext_cd_gpio; - set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; - - if (pd->max_width) - set->max_width = pd->max_width; - if (pd->cfg_gpio) - set->cfg_gpio = pd->cfg_gpio; - if (pd->cfg_card) - set->cfg_card = pd->cfg_card; - if (pd->host_caps) - set->host_caps |= pd->host_caps; - if (pd->clk_type) - set->clk_type = pd->clk_type; -} diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c deleted file mode 100644 index ede776f20e6..00000000000 --- a/arch/arm/plat-samsung/dev-hsmmc3.c +++ /dev/null @@ -1,83 +0,0 @@ -/* linux/arch/arm/plat-samsung/dev-hsmmc3.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Copyright (c) 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * Based on arch/arm/plat-samsung/dev-hsmmc1.c - * - * Samsung device definition for hsmmc device 3 - * - * 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/platform_device.h> -#include <linux/mmc/host.h> - -#include <mach/map.h> -#include <plat/sdhci.h> -#include <plat/devs.h> - -#define S3C_SZ_HSMMC (0x1000) - -static struct resource s3c_hsmmc3_resource[] = { - [0] = { - .start = S3C_PA_HSMMC3, - .end = S3C_PA_HSMMC3 + S3C_SZ_HSMMC - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_HSMMC3, - .end = IRQ_HSMMC3, - .flags = IORESOURCE_IRQ, - } -}; - -static u64 s3c_device_hsmmc3_dmamask = 0xffffffffUL; - -struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = { - .max_width = 4, - .host_caps = (MMC_CAP_4_BIT_DATA | - MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), - .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, -}; - -struct platform_device s3c_device_hsmmc3 = { - .name = "s3c-sdhci", - .id = 3, - .num_resources = ARRAY_SIZE(s3c_hsmmc3_resource), - .resource = s3c_hsmmc3_resource, - .dev = { - .dma_mask = &s3c_device_hsmmc3_dmamask, - .coherent_dma_mask = 0xffffffffUL, - .platform_data = &s3c_hsmmc3_def_platdata, - }, -}; - -void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd) -{ - struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata; - - set->cd_type = pd->cd_type; - set->ext_cd_init = pd->ext_cd_init; - set->ext_cd_cleanup = pd->ext_cd_cleanup; - set->ext_cd_gpio = pd->ext_cd_gpio; - set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; - - if (pd->max_width) - set->max_width = pd->max_width; - if (pd->cfg_gpio) - set->cfg_gpio = pd->cfg_gpio; - if (pd->cfg_card) - set->cfg_card = pd->cfg_card; - if (pd->host_caps) - set->host_caps |= pd->host_caps; - if (pd->clk_type) - set->clk_type = pd->clk_type; -} diff --git a/arch/arm/plat-samsung/dev-hwmon.c b/arch/arm/plat-samsung/dev-hwmon.c deleted file mode 100644 index b3ffb958725..00000000000 --- a/arch/arm/plat-samsung/dev-hwmon.c +++ /dev/null @@ -1,42 +0,0 @@ -/* linux/arch/arm/plat-samsung/dev-hwmon.c - * - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * Adapted for HWMON by Maurus Cuelenaere - * - * Samsung series device definition for HWMON - * - * 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/platform_device.h> - -#include <plat/devs.h> -#include <plat/hwmon.h> - -struct platform_device s3c_device_hwmon = { - .name = "s3c-hwmon", - .id = -1, - .dev.parent = &s3c_device_adc.dev, -}; - -void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd) -{ - struct s3c_hwmon_pdata *npd; - - if (!pd) { - printk(KERN_ERR "%s: no platform data\n", __func__); - return; - } - - npd = kmemdup(pd, sizeof(struct s3c_hwmon_pdata), GFP_KERNEL); - if (!npd) - printk(KERN_ERR "%s: no memory for platform data\n", __func__); - - s3c_device_hwmon.dev.platform_data = npd; -} diff --git a/arch/arm/plat-samsung/dev-i2c0.c b/arch/arm/plat-samsung/dev-i2c0.c deleted file mode 100644 index 3a601c16f03..00000000000 --- a/arch/arm/plat-samsung/dev-i2c0.c +++ /dev/null @@ -1,72 +0,0 @@ -/* linux/arch/arm/plat-s3c/dev-i2c0.c - * - * Copyright 2008-2009 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C series device definition for i2c device 0 - * - * 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/gfp.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/platform_device.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -#include <plat/regs-iic.h> -#include <plat/iic.h> -#include <plat/devs.h> -#include <plat/cpu.h> - -static struct resource s3c_i2c_resource[] = { - [0] = { - .start = S3C_PA_IIC, - .end = S3C_PA_IIC + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IIC, - .end = IRQ_IIC, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device s3c_device_i2c0 = { - .name = "s3c2410-i2c", -#ifdef CONFIG_S3C_DEV_I2C1 - .id = 0, -#else - .id = -1, -#endif - .num_resources = ARRAY_SIZE(s3c_i2c_resource), - .resource = s3c_i2c_resource, -}; - -static struct s3c2410_platform_i2c default_i2c_data0 __initdata = { - .flags = 0, - .slave_addr = 0x10, - .frequency = 100*1000, - .sda_delay = 100, -}; - -void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd) -{ - struct s3c2410_platform_i2c *npd; - - if (!pd) - pd = &default_i2c_data0; - - npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL); - if (!npd) - printk(KERN_ERR "%s: no memory for platform data\n", __func__); - else if (!npd->cfg_gpio) - npd->cfg_gpio = s3c_i2c0_cfg_gpio; - - s3c_device_i2c0.dev.platform_data = npd; -} diff --git a/arch/arm/plat-samsung/dev-i2c1.c b/arch/arm/plat-samsung/dev-i2c1.c deleted file mode 100644 index 858ee2a0414..00000000000 --- a/arch/arm/plat-samsung/dev-i2c1.c +++ /dev/null @@ -1,69 +0,0 @@ -/* linux/arch/arm/plat-s3c/dev-i2c1.c - * - * Copyright 2008-2009 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C series device definition for i2c device 1 - * - * 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/gfp.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/platform_device.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -#include <plat/regs-iic.h> -#include <plat/iic.h> -#include <plat/devs.h> -#include <plat/cpu.h> - -static struct resource s3c_i2c_resource[] = { - [0] = { - .start = S3C_PA_IIC1, - .end = S3C_PA_IIC1 + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IIC1, - .end = IRQ_IIC1, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device s3c_device_i2c1 = { - .name = "s3c2410-i2c", - .id = 1, - .num_resources = ARRAY_SIZE(s3c_i2c_resource), - .resource = s3c_i2c_resource, -}; - -static struct s3c2410_platform_i2c default_i2c_data1 __initdata = { - .flags = 0, - .bus_num = 1, - .slave_addr = 0x10, - .frequency = 100*1000, - .sda_delay = 100, -}; - -void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd) -{ - struct s3c2410_platform_i2c *npd; - - if (!pd) - pd = &default_i2c_data1; - - npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL); - if (!npd) - printk(KERN_ERR "%s: no memory for platform data\n", __func__); - else if (!npd->cfg_gpio) - npd->cfg_gpio = s3c_i2c1_cfg_gpio; - - s3c_device_i2c1.dev.platform_data = npd; -} diff --git a/arch/arm/plat-samsung/dev-i2c2.c b/arch/arm/plat-samsung/dev-i2c2.c deleted file mode 100644 index ff4ba69b683..00000000000 --- a/arch/arm/plat-samsung/dev-i2c2.c +++ /dev/null @@ -1,70 +0,0 @@ -/* linux/arch/arm/plat-s3c/dev-i2c2.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S3C series device definition for i2c device 2 - * - * Based on plat-samsung/dev-i2c0.c - * - * 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/gfp.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/platform_device.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -#include <plat/regs-iic.h> -#include <plat/iic.h> -#include <plat/devs.h> -#include <plat/cpu.h> - -static struct resource s3c_i2c_resource[] = { - [0] = { - .start = S3C_PA_IIC2, - .end = S3C_PA_IIC2 + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IIC2, - .end = IRQ_IIC2, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device s3c_device_i2c2 = { - .name = "s3c2410-i2c", - .id = 2, - .num_resources = ARRAY_SIZE(s3c_i2c_resource), - .resource = s3c_i2c_resource, -}; - -static struct s3c2410_platform_i2c default_i2c_data2 __initdata = { - .flags = 0, - .bus_num = 2, - .slave_addr = 0x10, - .frequency = 100*1000, - .sda_delay = 100, -}; - -void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd) -{ - struct s3c2410_platform_i2c *npd; - - if (!pd) - pd = &default_i2c_data2; - - npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL); - if (!npd) - printk(KERN_ERR "%s: no memory for platform data\n", __func__); - else if (!npd->cfg_gpio) - npd->cfg_gpio = s3c_i2c2_cfg_gpio; - - s3c_device_i2c2.dev.platform_data = npd; -} diff --git a/arch/arm/plat-samsung/dev-i2c3.c b/arch/arm/plat-samsung/dev-i2c3.c deleted file mode 100644 index 8586a10014b..00000000000 --- a/arch/arm/plat-samsung/dev-i2c3.c +++ /dev/null @@ -1,68 +0,0 @@ -/* linux/arch/arm/plat-samsung/dev-i2c3.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P series device definition for i2c device 3 - * - * 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/gfp.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/platform_device.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -#include <plat/regs-iic.h> -#include <plat/iic.h> -#include <plat/devs.h> -#include <plat/cpu.h> - -static struct resource s3c_i2c_resource[] = { - [0] = { - .start = S3C_PA_IIC3, - .end = S3C_PA_IIC3 + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IIC3, - .end = IRQ_IIC3, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device s3c_device_i2c3 = { - .name = "s3c2440-i2c", - .id = 3, - .num_resources = ARRAY_SIZE(s3c_i2c_resource), - .resource = s3c_i2c_resource, -}; - -static struct s3c2410_platform_i2c default_i2c_data3 __initdata = { - .flags = 0, - .bus_num = 3, - .slave_addr = 0x10, - .frequency = 100*1000, - .sda_delay = 100, -}; - -void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd) -{ - struct s3c2410_platform_i2c *npd; - - if (!pd) - pd = &default_i2c_data3; - - npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL); - if (!npd) - printk(KERN_ERR "%s: no memory for platform data\n", __func__); - else if (!npd->cfg_gpio) - npd->cfg_gpio = s3c_i2c3_cfg_gpio; - - s3c_device_i2c3.dev.platform_data = npd; -} diff --git a/arch/arm/plat-samsung/dev-i2c4.c b/arch/arm/plat-samsung/dev-i2c4.c deleted file mode 100644 index df2159e2daa..00000000000 --- a/arch/arm/plat-samsung/dev-i2c4.c +++ /dev/null @@ -1,68 +0,0 @@ -/* linux/arch/arm/plat-samsung/dev-i2c4.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P series device definition for i2c device 3 - * - * 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/gfp.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/platform_device.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -#include <plat/regs-iic.h> -#include <plat/iic.h> -#include <plat/devs.h> -#include <plat/cpu.h> - -static struct resource s3c_i2c_resource[] = { - [0] = { - .start = S3C_PA_IIC4, - .end = S3C_PA_IIC4 + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IIC4, - .end = IRQ_IIC4, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device s3c_device_i2c4 = { - .name = "s3c2440-i2c", - .id = 4, - .num_resources = ARRAY_SIZE(s3c_i2c_resource), - .resource = s3c_i2c_resource, -}; - -static struct s3c2410_platform_i2c default_i2c_data4 __initdata = { - .flags = 0, - .bus_num = 4, - .slave_addr = 0x10, - .frequency = 100*1000, - .sda_delay = 100, -}; - -void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd) -{ - struct s3c2410_platform_i2c *npd; - - if (!pd) - pd = &default_i2c_data4; - - npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL); - if (!npd) - printk(KERN_ERR "%s: no memory for platform data\n", __func__); - else if (!npd->cfg_gpio) - npd->cfg_gpio = s3c_i2c4_cfg_gpio; - - s3c_device_i2c4.dev.platform_data = npd; -} diff --git a/arch/arm/plat-samsung/dev-i2c5.c b/arch/arm/plat-samsung/dev-i2c5.c deleted file mode 100644 index 0499c2c3877..00000000000 --- a/arch/arm/plat-samsung/dev-i2c5.c +++ /dev/null @@ -1,68 +0,0 @@ -/* linux/arch/arm/plat-samsung/dev-i2c3.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P series device definition for i2c device 3 - * - * 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/gfp.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/platform_device.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -#include <plat/regs-iic.h> -#include <plat/iic.h> -#include <plat/devs.h> -#include <plat/cpu.h> - -static struct resource s3c_i2c_resource[] = { - [0] = { - .start = S3C_PA_IIC5, - .end = S3C_PA_IIC5 + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IIC5, - .end = IRQ_IIC5, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device s3c_device_i2c5 = { - .name = "s3c2440-i2c", - .id = 5, - .num_resources = ARRAY_SIZE(s3c_i2c_resource), - .resource = s3c_i2c_resource, -}; - -static struct s3c2410_platform_i2c default_i2c_data5 __initdata = { - .flags = 0, - .bus_num = 5, - .slave_addr = 0x10, - .frequency = 100*1000, - .sda_delay = 100, -}; - -void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd) -{ - struct s3c2410_platform_i2c *npd; - - if (!pd) - pd = &default_i2c_data5; - - npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL); - if (!npd) - printk(KERN_ERR "%s: no memory for platform data\n", __func__); - else if (!npd->cfg_gpio) - npd->cfg_gpio = s3c_i2c5_cfg_gpio; - - s3c_device_i2c5.dev.platform_data = npd; -} diff --git a/arch/arm/plat-samsung/dev-i2c6.c b/arch/arm/plat-samsung/dev-i2c6.c deleted file mode 100644 index 4083108908a..00000000000 --- a/arch/arm/plat-samsung/dev-i2c6.c +++ /dev/null @@ -1,68 +0,0 @@ -/* linux/arch/arm/plat-samsung/dev-i2c6.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P series device definition for i2c device 6 - * - * 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/gfp.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/platform_device.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -#include <plat/regs-iic.h> -#include <plat/iic.h> -#include <plat/devs.h> -#include <plat/cpu.h> - -static struct resource s3c_i2c_resource[] = { - [0] = { - .start = S3C_PA_IIC6, - .end = S3C_PA_IIC6 + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IIC6, - .end = IRQ_IIC6, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device s3c_device_i2c6 = { - .name = "s3c2440-i2c", - .id = 6, - .num_resources = ARRAY_SIZE(s3c_i2c_resource), - .resource = s3c_i2c_resource, -}; - -static struct s3c2410_platform_i2c default_i2c_data6 __initdata = { - .flags = 0, - .bus_num = 6, - .slave_addr = 0x10, - .frequency = 100*1000, - .sda_delay = 100, -}; - -void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd) -{ - struct s3c2410_platform_i2c *npd; - - if (!pd) - pd = &default_i2c_data6; - - npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL); - if (!npd) - printk(KERN_ERR "%s: no memory for platform data\n", __func__); - else if (!npd->cfg_gpio) - npd->cfg_gpio = s3c_i2c6_cfg_gpio; - - s3c_device_i2c6.dev.platform_data = npd; -} diff --git a/arch/arm/plat-samsung/dev-i2c7.c b/arch/arm/plat-samsung/dev-i2c7.c deleted file mode 100644 index 1182451d7dc..00000000000 --- a/arch/arm/plat-samsung/dev-i2c7.c +++ /dev/null @@ -1,68 +0,0 @@ -/* linux/arch/arm/plat-samsung/dev-i2c7.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P series device definition for i2c device 7 - * - * 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/gfp.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/platform_device.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -#include <plat/regs-iic.h> -#include <plat/iic.h> -#include <plat/devs.h> -#include <plat/cpu.h> - -static struct resource s3c_i2c_resource[] = { - [0] = { - .start = S3C_PA_IIC7, - .end = S3C_PA_IIC7 + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IIC7, - .end = IRQ_IIC7, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device s3c_device_i2c7 = { - .name = "s3c2440-i2c", - .id = 7, - .num_resources = ARRAY_SIZE(s3c_i2c_resource), - .resource = s3c_i2c_resource, -}; - -static struct s3c2410_platform_i2c default_i2c_data7 __initdata = { - .flags = 0, - .bus_num = 7, - .slave_addr = 0x10, - .frequency = 100*1000, - .sda_delay = 100, -}; - -void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd) -{ - struct s3c2410_platform_i2c *npd; - - if (!pd) - pd = &default_i2c_data7; - - npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL); - if (!npd) - printk(KERN_ERR "%s: no memory for platform data\n", __func__); - else if (!npd->cfg_gpio) - npd->cfg_gpio = s3c_i2c7_cfg_gpio; - - s3c_device_i2c7.dev.platform_data = npd; -} diff --git a/arch/arm/plat-samsung/dev-ide.c b/arch/arm/plat-samsung/dev-ide.c deleted file mode 100644 index b497982795a..00000000000 --- a/arch/arm/plat-samsung/dev-ide.c +++ /dev/null @@ -1,44 +0,0 @@ -/* linux/arch/arm/plat-samsung/dev-ide.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Samsung CF-ATA device definition. - * - * 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/interrupt.h> -#include <linux/platform_device.h> - -#include <mach/map.h> -#include <plat/ata.h> -#include <plat/devs.h> - -static struct resource s3c_cfcon_resource[] = { - [0] = { - .start = SAMSUNG_PA_CFCON, - .end = SAMSUNG_PA_CFCON + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_CFCON, - .end = IRQ_CFCON, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device s3c_device_cfcon = { - .id = 0, - .num_resources = ARRAY_SIZE(s3c_cfcon_resource), - .resource = s3c_cfcon_resource, -}; - -void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata) -{ - s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata), - &s3c_device_cfcon); -} diff --git a/arch/arm/plat-samsung/dev-keypad.c b/arch/arm/plat-samsung/dev-keypad.c deleted file mode 100644 index 677c2d731b6..00000000000 --- a/arch/arm/plat-samsung/dev-keypad.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * linux/arch/arm/plat-samsung/dev-keypad.c - * - * Copyright (C) 2010 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/platform_device.h> -#include <mach/irqs.h> -#include <mach/map.h> -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/keypad.h> - -static struct resource samsung_keypad_resources[] = { - [0] = { - .start = SAMSUNG_PA_KEYPAD, - .end = SAMSUNG_PA_KEYPAD + 0x20 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_KEYPAD, - .end = IRQ_KEYPAD, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device samsung_device_keypad = { - .name = "samsung-keypad", - .id = -1, - .num_resources = ARRAY_SIZE(samsung_keypad_resources), - .resource = samsung_keypad_resources, -}; - -void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd) -{ - struct samsung_keypad_platdata *npd; - - npd = s3c_set_platdata(pd, sizeof(struct samsung_keypad_platdata), - &samsung_device_keypad); - - if (!npd->cfg_gpio) - npd->cfg_gpio = samsung_keypad_cfg_gpio; -} diff --git a/arch/arm/plat-samsung/dev-nand.c b/arch/arm/plat-samsung/dev-nand.c deleted file mode 100644 index 6927ae8fd11..00000000000 --- a/arch/arm/plat-samsung/dev-nand.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * S3C series device definition for nand device - * - * 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/gfp.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> - -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> - -#include <mach/map.h> -#include <plat/devs.h> -#include <plat/nand.h> - -static struct resource s3c_nand_resource[] = { - [0] = { - .start = S3C_PA_NAND, - .end = S3C_PA_NAND + SZ_1M, - .flags = IORESOURCE_MEM, - } -}; - -struct platform_device s3c_device_nand = { - .name = "s3c2410-nand", - .id = -1, - .num_resources = ARRAY_SIZE(s3c_nand_resource), - .resource = s3c_nand_resource, -}; - -EXPORT_SYMBOL(s3c_device_nand); - -/** - * s3c_nand_copy_set() - copy nand set data - * @set: The new structure, directly copied from the old. - * - * Copy all the fields from the NAND set field from what is probably __initdata - * to new kernel memory. The code returns 0 if the copy happened correctly or - * an error code for the calling function to display. - * - * Note, we currently do not try and look to see if we've already copied the - * data in a previous set. - */ -static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set) -{ - void *ptr; - int size; - - size = sizeof(struct mtd_partition) * set->nr_partitions; - if (size) { - ptr = kmemdup(set->partitions, size, GFP_KERNEL); - set->partitions = ptr; - - if (!ptr) - return -ENOMEM; - } - - if (set->nr_map && set->nr_chips) { - size = sizeof(int) * set->nr_chips; - ptr = kmemdup(set->nr_map, size, GFP_KERNEL); - set->nr_map = ptr; - - if (!ptr) - return -ENOMEM; - } - - if (set->ecc_layout) { - ptr = kmemdup(set->ecc_layout, - sizeof(struct nand_ecclayout), GFP_KERNEL); - set->ecc_layout = ptr; - - if (!ptr) - return -ENOMEM; - } - - return 0; -} - -void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand) -{ - struct s3c2410_platform_nand *npd; - int size; - int ret; - - /* note, if we get a failure in allocation, we simply drop out of the - * function. If there is so little memory available at initialisation - * time then there is little chance the system is going to run. - */ - - npd = kmemdup(nand, sizeof(struct s3c2410_platform_nand), GFP_KERNEL); - if (!npd) { - printk(KERN_ERR "%s: failed copying platform data\n", __func__); - return; - } - - /* now see if we need to copy any of the nand set data */ - - size = sizeof(struct s3c2410_nand_set) * npd->nr_sets; - if (size) { - struct s3c2410_nand_set *from = npd->sets; - struct s3c2410_nand_set *to; - int i; - - to = kmemdup(from, size, GFP_KERNEL); - npd->sets = to; /* set, even if we failed */ - - if (!to) { - printk(KERN_ERR "%s: no memory for sets\n", __func__); - return; - } - - for (i = 0; i < npd->nr_sets; i++) { - ret = s3c_nand_copy_set(to); - if (ret) { - printk(KERN_ERR "%s: failed to copy set %d\n", - __func__, i); - return; - } - to++; - } - } - - s3c_device_nand.dev.platform_data = npd; -} diff --git a/arch/arm/plat-samsung/dev-onenand.c b/arch/arm/plat-samsung/dev-onenand.c deleted file mode 100644 index 45ec73287d8..00000000000 --- a/arch/arm/plat-samsung/dev-onenand.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * linux/arch/arm/plat-samsung/dev-onenand.c - * - * Copyright (c) 2008-2010 Samsung Electronics - * Kyungmin Park <kyungmin.park@samsung.com> - * - * S3C64XX/S5PC100 series device definition for OneNAND devices - * - * 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/platform_device.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/onenand.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -static struct resource s3c_onenand_resources[] = { - [0] = { - .start = S3C_PA_ONENAND, - .end = S3C_PA_ONENAND + 0x400 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = S3C_PA_ONENAND_BUF, - .end = S3C_PA_ONENAND_BUF + S3C_SZ_ONENAND_BUF - 1, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = IRQ_ONENAND, - .end = IRQ_ONENAND, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device s3c_device_onenand = { - .name = "samsung-onenand", - .id = 0, - .num_resources = ARRAY_SIZE(s3c_onenand_resources), - .resource = s3c_onenand_resources, -}; - -void s3c_onenand_set_platdata(struct onenand_platform_data *pdata) -{ - struct onenand_platform_data *pd; - - pd = kmemdup(pdata, sizeof(struct onenand_platform_data), GFP_KERNEL); - if (!pd) - printk(KERN_ERR "%s: no memory for platform data\n", __func__); - s3c_device_onenand.dev.platform_data = pd; -} diff --git a/arch/arm/plat-samsung/dev-pwm.c b/arch/arm/plat-samsung/dev-pwm.c deleted file mode 100644 index dab47b0e190..00000000000 --- a/arch/arm/plat-samsung/dev-pwm.c +++ /dev/null @@ -1,53 +0,0 @@ -/* linux/arch/arm/plat-samsung/dev-pwm.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Copyright (c) 2007 Ben Dooks - * Copyright (c) 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org> - * - * S3C series device definition for the PWM timer - * - * 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/platform_device.h> - -#include <mach/irqs.h> - -#include <plat/devs.h> - -#define TIMER_RESOURCE_SIZE (1) - -#define TIMER_RESOURCE(_tmr, _irq) \ - (struct resource [TIMER_RESOURCE_SIZE]) { \ - [0] = { \ - .start = _irq, \ - .end = _irq, \ - .flags = IORESOURCE_IRQ \ - } \ - } - -#define DEFINE_S3C_TIMER(_tmr_no, _irq) \ - .name = "s3c24xx-pwm", \ - .id = _tmr_no, \ - .num_resources = TIMER_RESOURCE_SIZE, \ - .resource = TIMER_RESOURCE(_tmr_no, _irq), \ - -/* - * since we already have an static mapping for the timer, - * we do not bother setting any IO resource for the base. - */ - -struct platform_device s3c_device_timer[] = { - [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) }, - [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) }, - [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) }, - [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) }, - [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) }, -}; -EXPORT_SYMBOL(s3c_device_timer); diff --git a/arch/arm/plat-samsung/dev-rtc.c b/arch/arm/plat-samsung/dev-rtc.c deleted file mode 100644 index bf4e2267333..00000000000 --- a/arch/arm/plat-samsung/dev-rtc.c +++ /dev/null @@ -1,43 +0,0 @@ -/* linux/arch/arm/plat-samsung/dev-rtc.c - * - * Copyright 2009 by Maurus Cuelenaere <mcuelenaere@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/string.h> -#include <linux/platform_device.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -#include <plat/devs.h> - -static struct resource s3c_rtc_resource[] = { - [0] = { - .start = S3C_PA_RTC, - .end = S3C_PA_RTC + 0xff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_RTC_ALARM, - .end = IRQ_RTC_ALARM, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = IRQ_RTC_TIC, - .end = IRQ_RTC_TIC, - .flags = IORESOURCE_IRQ - } -}; - -struct platform_device s3c_device_rtc = { - .name = "s3c64xx-rtc", - .id = -1, - .num_resources = ARRAY_SIZE(s3c_rtc_resource), - .resource = s3c_rtc_resource, -}; -EXPORT_SYMBOL(s3c_device_rtc); diff --git a/arch/arm/plat-samsung/dev-ts.c b/arch/arm/plat-samsung/dev-ts.c deleted file mode 100644 index 3e4bd8147bf..00000000000 --- a/arch/arm/plat-samsung/dev-ts.c +++ /dev/null @@ -1,60 +0,0 @@ -/* linux/arch/arm/mach-s3c64xx/dev-ts.c - * - * Copyright (c) 2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org> - * - * Adapted by Maurus Cuelenaere for s3c64xx - * - * S3C64XX series device definition for touchscreen device - * - * 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/string.h> -#include <linux/platform_device.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -#include <plat/devs.h> -#include <plat/ts.h> - -static struct resource s3c_ts_resource[] = { - [0] = { - .start = SAMSUNG_PA_ADC, - .end = SAMSUNG_PA_ADC + SZ_256 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_TC, - .end = IRQ_TC, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device s3c_device_ts = { - .name = "s3c64xx-ts", - .id = -1, - .num_resources = ARRAY_SIZE(s3c_ts_resource), - .resource = s3c_ts_resource, -}; - -void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd) -{ - struct s3c2410_ts_mach_info *npd; - - if (!pd) { - printk(KERN_ERR "%s: no platform data\n", __func__); - return; - } - - npd = kmemdup(pd, sizeof(struct s3c2410_ts_mach_info), GFP_KERNEL); - if (!npd) - printk(KERN_ERR "%s: no memory for platform data\n", __func__); - - s3c_device_ts.dev.platform_data = npd; -} diff --git a/arch/arm/plat-samsung/dev-usb-hsotg.c b/arch/arm/plat-samsung/dev-usb-hsotg.c deleted file mode 100644 index 33a844ab691..00000000000 --- a/arch/arm/plat-samsung/dev-usb-hsotg.c +++ /dev/null @@ -1,48 +0,0 @@ -/* linux/arch/arm/plat-s3c/dev-usb-hsotg.c - * - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C series device definition for USB high-speed UDC/OtG block - * - * 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/string.h> -#include <linux/platform_device.h> -#include <linux/dma-mapping.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -#include <plat/devs.h> - -static struct resource s3c_usb_hsotg_resources[] = { - [0] = { - .start = S3C_PA_USB_HSOTG, - .end = S3C_PA_USB_HSOTG + 0x10000 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_OTG, - .end = IRQ_OTG, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 s3c_hsotg_dmamask = DMA_BIT_MASK(32); - -struct platform_device s3c_device_usb_hsotg = { - .name = "s3c-hsotg", - .id = -1, - .num_resources = ARRAY_SIZE(s3c_usb_hsotg_resources), - .resource = s3c_usb_hsotg_resources, - .dev = { - .dma_mask = &s3c_hsotg_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, -}; diff --git a/arch/arm/plat-samsung/dev-usb.c b/arch/arm/plat-samsung/dev-usb.c deleted file mode 100644 index 0e0a3bf5c98..00000000000 --- a/arch/arm/plat-samsung/dev-usb.c +++ /dev/null @@ -1,70 +0,0 @@ -/* linux/arch/arm/plat-s3c/dev-usb.c - * - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C series device definition for USB host - * - * 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/gfp.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/platform_device.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -#include <plat/devs.h> -#include <plat/usb-control.h> - -static struct resource s3c_usb_resource[] = { - [0] = { - .start = S3C_PA_USBHOST, - .end = S3C_PA_USBHOST + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_USBH, - .end = IRQ_USBH, - .flags = IORESOURCE_IRQ, - } -}; - -static u64 s3c_device_usb_dmamask = 0xffffffffUL; - -struct platform_device s3c_device_ohci = { - .name = "s3c2410-ohci", - .id = -1, - .num_resources = ARRAY_SIZE(s3c_usb_resource), - .resource = s3c_usb_resource, - .dev = { - .dma_mask = &s3c_device_usb_dmamask, - .coherent_dma_mask = 0xffffffffUL - } -}; - -EXPORT_SYMBOL(s3c_device_ohci); - -/** - * s3c_ohci_set_platdata - initialise OHCI device platform data - * @info: The platform data. - * - * This call copies the @info passed in and sets the device .platform_data - * field to that copy. The @info is copied so that the original can be marked - * __initdata. - */ -void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info) -{ - struct s3c2410_hcd_info *npd; - - npd = kmemdup(info, sizeof(struct s3c2410_hcd_info), GFP_KERNEL); - if (!npd) - printk(KERN_ERR "%s: no memory for platform data\n", __func__); - - s3c_device_ohci.dev.platform_data = npd; -} diff --git a/arch/arm/plat-samsung/dev-wdt.c b/arch/arm/plat-samsung/dev-wdt.c deleted file mode 100644 index 019b5b8cf14..00000000000 --- a/arch/arm/plat-samsung/dev-wdt.c +++ /dev/null @@ -1,40 +0,0 @@ -/* linux/arch/arm/plat-samsung/dev-wdt.c - * - * Copyright (c) 2004 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * S3C series device definition for the watchdog timer - * - * 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/platform_device.h> - -#include <mach/irqs.h> -#include <mach/map.h> - -#include <plat/devs.h> - -static struct resource s3c_wdt_resource[] = { - [0] = { - .start = S3C_PA_WDT, - .end = S3C_PA_WDT + SZ_1K, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_WDT, - .end = IRQ_WDT, - .flags = IORESOURCE_IRQ, - } -}; - -struct platform_device s3c_device_wdt = { - .name = "s3c2410-wdt", - .id = -1, - .num_resources = ARRAY_SIZE(s3c_wdt_resource), - .resource = s3c_wdt_resource, -}; -EXPORT_SYMBOL(s3c_device_wdt); diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c new file mode 100644 index 00000000000..ead4f1c9405 --- /dev/null +++ b/arch/arm/plat-samsung/devs.c @@ -0,0 +1,1559 @@ +/* linux/arch/arm/plat-samsung/devs.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Base SAMSUNG platform device 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. +*/ + +#include <linux/amba/pl330.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#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/slab.h> +#include <linux/string.h> +#include <linux/dma-mapping.h> +#include <linux/fb.h> +#include <linux/gfp.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/onenand.h> +#include <linux/mtd/partitions.h> +#include <linux/mmc/host.h> +#include <linux/ioport.h> +#include <linux/sizes.h> +#include <linux/platform_data/s3c-hsudc.h> +#include <linux/platform_data/s3c-hsotg.h> +#include <linux/platform_data/dma-s3c24xx.h> + +#include <media/s5p_hdmi.h> + +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/dma.h> +#include <mach/irqs.h> +#include <mach/map.h> + +#include <plat/cpu.h> +#include <plat/devs.h> +#include <plat/adc.h> +#include <linux/platform_data/ata-samsung_cf.h> +#include <plat/fb.h> +#include <plat/fb-s3c2410.h> +#include <plat/hdmi.h> +#include <linux/platform_data/hwmon-s3c.h> +#include <linux/platform_data/i2c-s3c2410.h> +#include <plat/keypad.h> +#include <linux/platform_data/mmc-s3cmci.h> +#include <linux/platform_data/mtd-nand-s3c2410.h> +#include <plat/pwm-core.h> +#include <plat/sdhci.h> +#include <linux/platform_data/touchscreen-s3c2410.h> +#include <linux/platform_data/usb-s3c2410_udc.h> +#include <linux/platform_data/usb-ohci-s3c2410.h> +#include <plat/usb-phy.h> +#include <plat/regs-spi.h> +#include <linux/platform_data/spi-s3c64xx.h> + +static u64 samsung_device_dma_mask = DMA_BIT_MASK(32); + +/* AC97 */ +#ifdef CONFIG_CPU_S3C2440 +static struct resource s3c_ac97_resource[] = { + [0] = DEFINE_RES_MEM(S3C2440_PA_AC97, S3C2440_SZ_AC97), + [1] = DEFINE_RES_IRQ(IRQ_S3C244X_AC97), + [2] = DEFINE_RES_DMA_NAMED(DMACH_PCM_OUT, "PCM out"), + [3] = DEFINE_RES_DMA_NAMED(DMACH_PCM_IN, "PCM in"), + [4] = DEFINE_RES_DMA_NAMED(DMACH_MIC_IN, "Mic in"), +}; + +struct platform_device s3c_device_ac97 = { + .name = "samsung-ac97", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_ac97_resource), + .resource = s3c_ac97_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; +#endif /* CONFIG_CPU_S3C2440 */ + +/* ADC */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_adc_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC), + [1] = DEFINE_RES_IRQ(IRQ_TC), + [2] = DEFINE_RES_IRQ(IRQ_ADC), +}; + +struct platform_device s3c_device_adc = { + .name = "s3c24xx-adc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_adc_resource), + .resource = s3c_adc_resource, +}; +#endif /* CONFIG_PLAT_S3C24XX */ + +#if defined(CONFIG_SAMSUNG_DEV_ADC) +static struct resource s3c_adc_resource[] = { + [0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_TC), + [2] = DEFINE_RES_IRQ(IRQ_ADC), +}; + +struct platform_device s3c_device_adc = { + .name = "samsung-adc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_adc_resource), + .resource = s3c_adc_resource, +}; +#endif /* CONFIG_SAMSUNG_DEV_ADC */ + +/* Camif Controller */ + +#ifdef CONFIG_CPU_S3C2440 +static struct resource s3c_camif_resource[] = { + [0] = DEFINE_RES_MEM(S3C2440_PA_CAMIF, S3C2440_SZ_CAMIF), + [1] = DEFINE_RES_IRQ(IRQ_S3C2440_CAM_C), + [2] = DEFINE_RES_IRQ(IRQ_S3C2440_CAM_P), +}; + +struct platform_device s3c_device_camif = { + .name = "s3c2440-camif", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_camif_resource), + .resource = s3c_camif_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; +#endif /* CONFIG_CPU_S3C2440 */ + +/* ASOC DMA */ + +#ifdef CONFIG_PLAT_S5P +static struct resource samsung_asoc_idma_resource = DEFINE_RES_IRQ(IRQ_I2S0); + +struct platform_device samsung_asoc_idma = { + .name = "samsung-idma", + .id = -1, + .num_resources = 1, + .resource = &samsung_asoc_idma_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; +#endif + +/* FB */ + +#ifdef CONFIG_S3C_DEV_FB +static struct resource s3c_fb_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_FB, SZ_16K), + [1] = DEFINE_RES_IRQ(IRQ_LCD_VSYNC), + [2] = DEFINE_RES_IRQ(IRQ_LCD_FIFO), + [3] = DEFINE_RES_IRQ(IRQ_LCD_SYSTEM), +}; + +struct platform_device s3c_device_fb = { + .name = "s3c-fb", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_fb_resource), + .resource = s3c_fb_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd) +{ + s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata), + &s3c_device_fb); +} +#endif /* CONFIG_S3C_DEV_FB */ + +/* FIMC */ + +#ifdef CONFIG_S5P_DEV_FIMC0 +static struct resource s5p_fimc0_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_FIMC0, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_FIMC0), +}; + +struct platform_device s5p_device_fimc0 = { + .name = "s5p-fimc", + .id = 0, + .num_resources = ARRAY_SIZE(s5p_fimc0_resource), + .resource = s5p_fimc0_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +struct platform_device s5p_device_fimc_md = { + .name = "s5p-fimc-md", + .id = -1, +}; +#endif /* CONFIG_S5P_DEV_FIMC0 */ + +#ifdef CONFIG_S5P_DEV_FIMC1 +static struct resource s5p_fimc1_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_FIMC1, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_FIMC1), +}; + +struct platform_device s5p_device_fimc1 = { + .name = "s5p-fimc", + .id = 1, + .num_resources = ARRAY_SIZE(s5p_fimc1_resource), + .resource = s5p_fimc1_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; +#endif /* CONFIG_S5P_DEV_FIMC1 */ + +#ifdef CONFIG_S5P_DEV_FIMC2 +static struct resource s5p_fimc2_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_FIMC2, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_FIMC2), +}; + +struct platform_device s5p_device_fimc2 = { + .name = "s5p-fimc", + .id = 2, + .num_resources = ARRAY_SIZE(s5p_fimc2_resource), + .resource = s5p_fimc2_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; +#endif /* CONFIG_S5P_DEV_FIMC2 */ + +#ifdef CONFIG_S5P_DEV_FIMC3 +static struct resource s5p_fimc3_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_FIMC3, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_FIMC3), +}; + +struct platform_device s5p_device_fimc3 = { + .name = "s5p-fimc", + .id = 3, + .num_resources = ARRAY_SIZE(s5p_fimc3_resource), + .resource = s5p_fimc3_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; +#endif /* CONFIG_S5P_DEV_FIMC3 */ + +/* G2D */ + +#ifdef CONFIG_S5P_DEV_G2D +static struct resource s5p_g2d_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_G2D, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_2D), +}; + +struct platform_device s5p_device_g2d = { + .name = "s5p-g2d", + .id = 0, + .num_resources = ARRAY_SIZE(s5p_g2d_resource), + .resource = s5p_g2d_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; +#endif /* CONFIG_S5P_DEV_G2D */ + +#ifdef CONFIG_S5P_DEV_JPEG +static struct resource s5p_jpeg_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_JPEG, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_JPEG), +}; + +struct platform_device s5p_device_jpeg = { + .name = "s5p-jpeg", + .id = 0, + .num_resources = ARRAY_SIZE(s5p_jpeg_resource), + .resource = s5p_jpeg_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; +#endif /* CONFIG_S5P_DEV_JPEG */ + +/* FIMD0 */ + +#ifdef CONFIG_S5P_DEV_FIMD0 +static struct resource s5p_fimd0_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_FIMD0, SZ_32K), + [1] = DEFINE_RES_IRQ_NAMED(IRQ_FIMD0_VSYNC, "vsync"), + [2] = DEFINE_RES_IRQ_NAMED(IRQ_FIMD0_FIFO, "fifo"), + [3] = DEFINE_RES_IRQ_NAMED(IRQ_FIMD0_SYSTEM, "lcd_sys"), +}; + +struct platform_device s5p_device_fimd0 = { + .name = "s5p-fb", + .id = 0, + .num_resources = ARRAY_SIZE(s5p_fimd0_resource), + .resource = s5p_fimd0_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd) +{ + s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata), + &s5p_device_fimd0); +} +#endif /* CONFIG_S5P_DEV_FIMD0 */ + +/* HWMON */ + +#ifdef CONFIG_S3C_DEV_HWMON +struct platform_device s3c_device_hwmon = { + .name = "s3c-hwmon", + .id = -1, + .dev.parent = &s3c_device_adc.dev, +}; + +void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd) +{ + s3c_set_platdata(pd, sizeof(struct s3c_hwmon_pdata), + &s3c_device_hwmon); +} +#endif /* CONFIG_S3C_DEV_HWMON */ + +/* HSMMC */ + +#ifdef CONFIG_S3C_DEV_HSMMC +static struct resource s3c_hsmmc_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_HSMMC0, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_HSMMC0), +}; + +struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = { + .max_width = 4, + .host_caps = (MMC_CAP_4_BIT_DATA | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), +}; + +struct platform_device s3c_device_hsmmc0 = { + .name = "s3c-sdhci", + .id = 0, + .num_resources = ARRAY_SIZE(s3c_hsmmc_resource), + .resource = s3c_hsmmc_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s3c_hsmmc0_def_platdata, + }, +}; + +void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd) +{ + s3c_sdhci_set_platdata(pd, &s3c_hsmmc0_def_platdata); +} +#endif /* CONFIG_S3C_DEV_HSMMC */ + +#ifdef CONFIG_S3C_DEV_HSMMC1 +static struct resource s3c_hsmmc1_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_HSMMC1, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_HSMMC1), +}; + +struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = { + .max_width = 4, + .host_caps = (MMC_CAP_4_BIT_DATA | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), +}; + +struct platform_device s3c_device_hsmmc1 = { + .name = "s3c-sdhci", + .id = 1, + .num_resources = ARRAY_SIZE(s3c_hsmmc1_resource), + .resource = s3c_hsmmc1_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s3c_hsmmc1_def_platdata, + }, +}; + +void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd) +{ + s3c_sdhci_set_platdata(pd, &s3c_hsmmc1_def_platdata); +} +#endif /* CONFIG_S3C_DEV_HSMMC1 */ + +/* HSMMC2 */ + +#ifdef CONFIG_S3C_DEV_HSMMC2 +static struct resource s3c_hsmmc2_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_HSMMC2, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_HSMMC2), +}; + +struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = { + .max_width = 4, + .host_caps = (MMC_CAP_4_BIT_DATA | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), +}; + +struct platform_device s3c_device_hsmmc2 = { + .name = "s3c-sdhci", + .id = 2, + .num_resources = ARRAY_SIZE(s3c_hsmmc2_resource), + .resource = s3c_hsmmc2_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s3c_hsmmc2_def_platdata, + }, +}; + +void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd) +{ + s3c_sdhci_set_platdata(pd, &s3c_hsmmc2_def_platdata); +} +#endif /* CONFIG_S3C_DEV_HSMMC2 */ + +#ifdef CONFIG_S3C_DEV_HSMMC3 +static struct resource s3c_hsmmc3_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_HSMMC3, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_HSMMC3), +}; + +struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = { + .max_width = 4, + .host_caps = (MMC_CAP_4_BIT_DATA | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), +}; + +struct platform_device s3c_device_hsmmc3 = { + .name = "s3c-sdhci", + .id = 3, + .num_resources = ARRAY_SIZE(s3c_hsmmc3_resource), + .resource = s3c_hsmmc3_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s3c_hsmmc3_def_platdata, + }, +}; + +void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd) +{ + s3c_sdhci_set_platdata(pd, &s3c_hsmmc3_def_platdata); +} +#endif /* CONFIG_S3C_DEV_HSMMC3 */ + +/* I2C */ + +static struct resource s3c_i2c0_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC), +}; + +struct platform_device s3c_device_i2c0 = { + .name = "s3c2410-i2c", + .id = 0, + .num_resources = ARRAY_SIZE(s3c_i2c0_resource), + .resource = s3c_i2c0_resource, +}; + +struct s3c2410_platform_i2c default_i2c_data __initdata = { + .flags = 0, + .slave_addr = 0x10, + .frequency = 100*1000, + .sda_delay = 100, +}; + +void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 0; + } + + npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), + &s3c_device_i2c0); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c0_cfg_gpio; +} + +#ifdef CONFIG_S3C_DEV_I2C1 +static struct resource s3c_i2c1_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC1, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC1), +}; + +struct platform_device s3c_device_i2c1 = { + .name = "s3c2410-i2c", + .id = 1, + .num_resources = ARRAY_SIZE(s3c_i2c1_resource), + .resource = s3c_i2c1_resource, +}; + +void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 1; + } + + npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), + &s3c_device_i2c1); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c1_cfg_gpio; +} +#endif /* CONFIG_S3C_DEV_I2C1 */ + +#ifdef CONFIG_S3C_DEV_I2C2 +static struct resource s3c_i2c2_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC2, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC2), +}; + +struct platform_device s3c_device_i2c2 = { + .name = "s3c2410-i2c", + .id = 2, + .num_resources = ARRAY_SIZE(s3c_i2c2_resource), + .resource = s3c_i2c2_resource, +}; + +void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 2; + } + + npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), + &s3c_device_i2c2); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c2_cfg_gpio; +} +#endif /* CONFIG_S3C_DEV_I2C2 */ + +#ifdef CONFIG_S3C_DEV_I2C3 +static struct resource s3c_i2c3_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC3, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC3), +}; + +struct platform_device s3c_device_i2c3 = { + .name = "s3c2440-i2c", + .id = 3, + .num_resources = ARRAY_SIZE(s3c_i2c3_resource), + .resource = s3c_i2c3_resource, +}; + +void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 3; + } + + npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), + &s3c_device_i2c3); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c3_cfg_gpio; +} +#endif /*CONFIG_S3C_DEV_I2C3 */ + +#ifdef CONFIG_S3C_DEV_I2C4 +static struct resource s3c_i2c4_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC4, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC4), +}; + +struct platform_device s3c_device_i2c4 = { + .name = "s3c2440-i2c", + .id = 4, + .num_resources = ARRAY_SIZE(s3c_i2c4_resource), + .resource = s3c_i2c4_resource, +}; + +void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 4; + } + + npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), + &s3c_device_i2c4); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c4_cfg_gpio; +} +#endif /*CONFIG_S3C_DEV_I2C4 */ + +#ifdef CONFIG_S3C_DEV_I2C5 +static struct resource s3c_i2c5_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC5, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC5), +}; + +struct platform_device s3c_device_i2c5 = { + .name = "s3c2440-i2c", + .id = 5, + .num_resources = ARRAY_SIZE(s3c_i2c5_resource), + .resource = s3c_i2c5_resource, +}; + +void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 5; + } + + npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), + &s3c_device_i2c5); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c5_cfg_gpio; +} +#endif /*CONFIG_S3C_DEV_I2C5 */ + +#ifdef CONFIG_S3C_DEV_I2C6 +static struct resource s3c_i2c6_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC6, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC6), +}; + +struct platform_device s3c_device_i2c6 = { + .name = "s3c2440-i2c", + .id = 6, + .num_resources = ARRAY_SIZE(s3c_i2c6_resource), + .resource = s3c_i2c6_resource, +}; + +void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 6; + } + + npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), + &s3c_device_i2c6); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c6_cfg_gpio; +} +#endif /* CONFIG_S3C_DEV_I2C6 */ + +#ifdef CONFIG_S3C_DEV_I2C7 +static struct resource s3c_i2c7_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC7, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC7), +}; + +struct platform_device s3c_device_i2c7 = { + .name = "s3c2440-i2c", + .id = 7, + .num_resources = ARRAY_SIZE(s3c_i2c7_resource), + .resource = s3c_i2c7_resource, +}; + +void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 7; + } + + npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), + &s3c_device_i2c7); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c7_cfg_gpio; +} +#endif /* CONFIG_S3C_DEV_I2C7 */ + +/* I2C HDMIPHY */ + +#ifdef CONFIG_S5P_DEV_I2C_HDMIPHY +static struct resource s5p_i2c_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_IIC_HDMIPHY, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC_HDMIPHY), +}; + +struct platform_device s5p_device_i2c_hdmiphy = { + .name = "s3c2440-hdmiphy-i2c", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_i2c_resource), + .resource = s5p_i2c_resource, +}; + +void __init s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + + if (soc_is_s5pv210()) + pd->bus_num = 3; + else + pd->bus_num = 0; + } + + npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), + &s5p_device_i2c_hdmiphy); +} + +static struct s5p_hdmi_platform_data s5p_hdmi_def_platdata; + +void __init s5p_hdmi_set_platdata(struct i2c_board_info *hdmiphy_info, + struct i2c_board_info *mhl_info, int mhl_bus) +{ + struct s5p_hdmi_platform_data *pd = &s5p_hdmi_def_platdata; + + if (soc_is_s5pv210()) + pd->hdmiphy_bus = 3; + else + pd->hdmiphy_bus = 0; + + pd->hdmiphy_info = hdmiphy_info; + pd->mhl_info = mhl_info; + pd->mhl_bus = mhl_bus; + + s3c_set_platdata(pd, sizeof(struct s5p_hdmi_platform_data), + &s5p_device_hdmi); +} + +#endif /* CONFIG_S5P_DEV_I2C_HDMIPHY */ + +/* I2S */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_iis_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_IIS, S3C24XX_SZ_IIS), +}; + +struct platform_device s3c_device_iis = { + .name = "s3c24xx-iis", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_iis_resource), + .resource = s3c_iis_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; +#endif /* CONFIG_PLAT_S3C24XX */ + +/* IDE CFCON */ + +#ifdef CONFIG_SAMSUNG_DEV_IDE +static struct resource s3c_cfcon_resource[] = { + [0] = DEFINE_RES_MEM(SAMSUNG_PA_CFCON, SZ_16K), + [1] = DEFINE_RES_IRQ(IRQ_CFCON), +}; + +struct platform_device s3c_device_cfcon = { + .id = 0, + .num_resources = ARRAY_SIZE(s3c_cfcon_resource), + .resource = s3c_cfcon_resource, +}; + +void __init s3c_ide_set_platdata(struct s3c_ide_platdata *pdata) +{ + s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata), + &s3c_device_cfcon); +} +#endif /* CONFIG_SAMSUNG_DEV_IDE */ + +/* KEYPAD */ + +#ifdef CONFIG_SAMSUNG_DEV_KEYPAD +static struct resource samsung_keypad_resources[] = { + [0] = DEFINE_RES_MEM(SAMSUNG_PA_KEYPAD, SZ_32), + [1] = DEFINE_RES_IRQ(IRQ_KEYPAD), +}; + +struct platform_device samsung_device_keypad = { + .name = "samsung-keypad", + .id = -1, + .num_resources = ARRAY_SIZE(samsung_keypad_resources), + .resource = samsung_keypad_resources, +}; + +void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd) +{ + struct samsung_keypad_platdata *npd; + + npd = s3c_set_platdata(pd, sizeof(struct samsung_keypad_platdata), + &samsung_device_keypad); + + if (!npd->cfg_gpio) + npd->cfg_gpio = samsung_keypad_cfg_gpio; +} +#endif /* CONFIG_SAMSUNG_DEV_KEYPAD */ + +/* LCD Controller */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_lcd_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_LCD, S3C24XX_SZ_LCD), + [1] = DEFINE_RES_IRQ(IRQ_LCD), +}; + +struct platform_device s3c_device_lcd = { + .name = "s3c2410-lcd", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_lcd_resource), + .resource = s3c_lcd_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; + +void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd) +{ + struct s3c2410fb_mach_info *npd; + + npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_lcd); + if (npd) { + npd->displays = kmemdup(pd->displays, + sizeof(struct s3c2410fb_display) * npd->num_displays, + GFP_KERNEL); + if (!npd->displays) + printk(KERN_ERR "no memory for LCD display data\n"); + } else { + printk(KERN_ERR "no memory for LCD platform data\n"); + } +} +#endif /* CONFIG_PLAT_S3C24XX */ + +/* MIPI CSIS */ + +#ifdef CONFIG_S5P_DEV_CSIS0 +static struct resource s5p_mipi_csis0_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS0, SZ_16K), + [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS0), +}; + +struct platform_device s5p_device_mipi_csis0 = { + .name = "s5p-mipi-csis", + .id = 0, + .num_resources = ARRAY_SIZE(s5p_mipi_csis0_resource), + .resource = s5p_mipi_csis0_resource, +}; +#endif /* CONFIG_S5P_DEV_CSIS0 */ + +#ifdef CONFIG_S5P_DEV_CSIS1 +static struct resource s5p_mipi_csis1_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS1, SZ_16K), + [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS1), +}; + +struct platform_device s5p_device_mipi_csis1 = { + .name = "s5p-mipi-csis", + .id = 1, + .num_resources = ARRAY_SIZE(s5p_mipi_csis1_resource), + .resource = s5p_mipi_csis1_resource, +}; +#endif + +/* NAND */ + +#ifdef CONFIG_S3C_DEV_NAND +static struct resource s3c_nand_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_NAND, SZ_1M), +}; + +struct platform_device s3c_device_nand = { + .name = "s3c2410-nand", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_nand_resource), + .resource = s3c_nand_resource, +}; + +/* + * s3c_nand_copy_set() - copy nand set data + * @set: The new structure, directly copied from the old. + * + * Copy all the fields from the NAND set field from what is probably __initdata + * to new kernel memory. The code returns 0 if the copy happened correctly or + * an error code for the calling function to display. + * + * Note, we currently do not try and look to see if we've already copied the + * data in a previous set. + */ +static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set) +{ + void *ptr; + int size; + + size = sizeof(struct mtd_partition) * set->nr_partitions; + if (size) { + ptr = kmemdup(set->partitions, size, GFP_KERNEL); + set->partitions = ptr; + + if (!ptr) + return -ENOMEM; + } + + if (set->nr_map && set->nr_chips) { + size = sizeof(int) * set->nr_chips; + ptr = kmemdup(set->nr_map, size, GFP_KERNEL); + set->nr_map = ptr; + + if (!ptr) + return -ENOMEM; + } + + if (set->ecc_layout) { + ptr = kmemdup(set->ecc_layout, + sizeof(struct nand_ecclayout), GFP_KERNEL); + set->ecc_layout = ptr; + + if (!ptr) + return -ENOMEM; + } + + return 0; +} + +void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand) +{ + struct s3c2410_platform_nand *npd; + int size; + int ret; + + /* note, if we get a failure in allocation, we simply drop out of the + * function. If there is so little memory available at initialisation + * time then there is little chance the system is going to run. + */ + + npd = s3c_set_platdata(nand, sizeof(struct s3c2410_platform_nand), + &s3c_device_nand); + if (!npd) + return; + + /* now see if we need to copy any of the nand set data */ + + size = sizeof(struct s3c2410_nand_set) * npd->nr_sets; + if (size) { + struct s3c2410_nand_set *from = npd->sets; + struct s3c2410_nand_set *to; + int i; + + to = kmemdup(from, size, GFP_KERNEL); + npd->sets = to; /* set, even if we failed */ + + if (!to) { + printk(KERN_ERR "%s: no memory for sets\n", __func__); + return; + } + + for (i = 0; i < npd->nr_sets; i++) { + ret = s3c_nand_copy_set(to); + if (ret) { + printk(KERN_ERR "%s: failed to copy set %d\n", + __func__, i); + return; + } + to++; + } + } +} +#endif /* CONFIG_S3C_DEV_NAND */ + +/* ONENAND */ + +#ifdef CONFIG_S3C_DEV_ONENAND +static struct resource s3c_onenand_resources[] = { + [0] = DEFINE_RES_MEM(S3C_PA_ONENAND, SZ_1K), + [1] = DEFINE_RES_MEM(S3C_PA_ONENAND_BUF, S3C_SZ_ONENAND_BUF), + [2] = DEFINE_RES_IRQ(IRQ_ONENAND), +}; + +struct platform_device s3c_device_onenand = { + .name = "samsung-onenand", + .id = 0, + .num_resources = ARRAY_SIZE(s3c_onenand_resources), + .resource = s3c_onenand_resources, +}; +#endif /* CONFIG_S3C_DEV_ONENAND */ + +#ifdef CONFIG_S3C64XX_DEV_ONENAND1 +static struct resource s3c64xx_onenand1_resources[] = { + [0] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1, SZ_1K), + [1] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1_BUF, S3C64XX_SZ_ONENAND1_BUF), + [2] = DEFINE_RES_IRQ(IRQ_ONENAND1), +}; + +struct platform_device s3c64xx_device_onenand1 = { + .name = "samsung-onenand", + .id = 1, + .num_resources = ARRAY_SIZE(s3c64xx_onenand1_resources), + .resource = s3c64xx_onenand1_resources, +}; + +void __init s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata) +{ + s3c_set_platdata(pdata, sizeof(struct onenand_platform_data), + &s3c64xx_device_onenand1); +} +#endif /* CONFIG_S3C64XX_DEV_ONENAND1 */ + +#ifdef CONFIG_S5P_DEV_ONENAND +static struct resource s5p_onenand_resources[] = { + [0] = DEFINE_RES_MEM(S5P_PA_ONENAND, SZ_128K), + [1] = DEFINE_RES_MEM(S5P_PA_ONENAND_DMA, SZ_8K), + [2] = DEFINE_RES_IRQ(IRQ_ONENAND_AUDI), +}; + +struct platform_device s5p_device_onenand = { + .name = "s5pc110-onenand", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_onenand_resources), + .resource = s5p_onenand_resources, +}; +#endif /* CONFIG_S5P_DEV_ONENAND */ + +/* PMU */ + +#if defined(CONFIG_PLAT_S5P) && !defined(CONFIG_ARCH_EXYNOS) +static struct resource s5p_pmu_resource[] = { + DEFINE_RES_IRQ(IRQ_PMU) +}; + +static struct platform_device s5p_device_pmu = { + .name = "arm-pmu", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_pmu_resource), + .resource = s5p_pmu_resource, +}; + +static int __init s5p_pmu_init(void) +{ + platform_device_register(&s5p_device_pmu); + return 0; +} +arch_initcall(s5p_pmu_init); +#endif /* CONFIG_PLAT_S5P */ + +/* PWM Timer */ + +#ifdef CONFIG_SAMSUNG_DEV_PWM +static struct resource samsung_pwm_resource[] = { + DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K), +}; + +struct platform_device samsung_device_pwm = { + .name = "samsung-pwm", + .id = -1, + .num_resources = ARRAY_SIZE(samsung_pwm_resource), + .resource = samsung_pwm_resource, +}; + +void __init samsung_pwm_set_platdata(struct samsung_pwm_variant *pd) +{ + samsung_device_pwm.dev.platform_data = pd; +} +#endif /* CONFIG_SAMSUNG_DEV_PWM */ + +/* RTC */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_rtc_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_RTC, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_RTC), + [2] = DEFINE_RES_IRQ(IRQ_TICK), +}; + +struct platform_device s3c_device_rtc = { + .name = "s3c2410-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_rtc_resource), + .resource = s3c_rtc_resource, +}; +#endif /* CONFIG_PLAT_S3C24XX */ + +#ifdef CONFIG_S3C_DEV_RTC +static struct resource s3c_rtc_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_RTC, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_RTC_ALARM), + [2] = DEFINE_RES_IRQ(IRQ_RTC_TIC), +}; + +struct platform_device s3c_device_rtc = { + .name = "s3c64xx-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_rtc_resource), + .resource = s3c_rtc_resource, +}; +#endif /* CONFIG_S3C_DEV_RTC */ + +/* SDI */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_sdi_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_SDI, S3C24XX_SZ_SDI), + [1] = DEFINE_RES_IRQ(IRQ_SDI), +}; + +struct platform_device s3c_device_sdi = { + .name = "s3c2410-sdi", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_sdi_resource), + .resource = s3c_sdi_resource, +}; + +void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata) +{ + s3c_set_platdata(pdata, sizeof(struct s3c24xx_mci_pdata), + &s3c_device_sdi); +} +#endif /* CONFIG_PLAT_S3C24XX */ + +/* SPI */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_spi0_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI, SZ_32), + [1] = DEFINE_RES_IRQ(IRQ_SPI0), +}; + +struct platform_device s3c_device_spi0 = { + .name = "s3c2410-spi", + .id = 0, + .num_resources = ARRAY_SIZE(s3c_spi0_resource), + .resource = s3c_spi0_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; + +static struct resource s3c_spi1_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI1, SZ_32), + [1] = DEFINE_RES_IRQ(IRQ_SPI1), +}; + +struct platform_device s3c_device_spi1 = { + .name = "s3c2410-spi", + .id = 1, + .num_resources = ARRAY_SIZE(s3c_spi1_resource), + .resource = s3c_spi1_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; +#endif /* CONFIG_PLAT_S3C24XX */ + +/* Touchscreen */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_ts_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC), + [1] = DEFINE_RES_IRQ(IRQ_TC), +}; + +struct platform_device s3c_device_ts = { + .name = "s3c2410-ts", + .id = -1, + .dev.parent = &s3c_device_adc.dev, + .num_resources = ARRAY_SIZE(s3c_ts_resource), + .resource = s3c_ts_resource, +}; + +void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info) +{ + s3c_set_platdata(hard_s3c2410ts_info, + sizeof(struct s3c2410_ts_mach_info), &s3c_device_ts); +} +#endif /* CONFIG_PLAT_S3C24XX */ + +#ifdef CONFIG_SAMSUNG_DEV_TS +static struct resource s3c_ts_resource[] = { + [0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_TC), +}; + +static struct s3c2410_ts_mach_info default_ts_data __initdata = { + .delay = 10000, + .presc = 49, + .oversampling_shift = 2, +}; + +struct platform_device s3c_device_ts = { + .name = "s3c64xx-ts", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_ts_resource), + .resource = s3c_ts_resource, +}; + +void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd) +{ + if (!pd) + pd = &default_ts_data; + + s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info), + &s3c_device_ts); +} +#endif /* CONFIG_SAMSUNG_DEV_TS */ + +/* TV */ + +#ifdef CONFIG_S5P_DEV_TV + +static struct resource s5p_hdmi_resources[] = { + [0] = DEFINE_RES_MEM(S5P_PA_HDMI, SZ_1M), + [1] = DEFINE_RES_IRQ(IRQ_HDMI), +}; + +struct platform_device s5p_device_hdmi = { + .name = "s5p-hdmi", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_hdmi_resources), + .resource = s5p_hdmi_resources, +}; + +static struct resource s5p_sdo_resources[] = { + [0] = DEFINE_RES_MEM(S5P_PA_SDO, SZ_64K), + [1] = DEFINE_RES_IRQ(IRQ_SDO), +}; + +struct platform_device s5p_device_sdo = { + .name = "s5p-sdo", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_sdo_resources), + .resource = s5p_sdo_resources, +}; + +static struct resource s5p_mixer_resources[] = { + [0] = DEFINE_RES_MEM_NAMED(S5P_PA_MIXER, SZ_64K, "mxr"), + [1] = DEFINE_RES_MEM_NAMED(S5P_PA_VP, SZ_64K, "vp"), + [2] = DEFINE_RES_IRQ_NAMED(IRQ_MIXER, "irq"), +}; + +struct platform_device s5p_device_mixer = { + .name = "s5p-mixer", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_mixer_resources), + .resource = s5p_mixer_resources, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; +#endif /* CONFIG_S5P_DEV_TV */ + +/* USB */ + +#ifdef CONFIG_S3C_DEV_USB_HOST +static struct resource s3c_usb_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_USBHOST, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_USBH), +}; + +struct platform_device s3c_device_ohci = { + .name = "s3c2410-ohci", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_usb_resource), + .resource = s3c_usb_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; + +/* + * s3c_ohci_set_platdata - initialise OHCI device platform data + * @info: The platform data. + * + * This call copies the @info passed in and sets the device .platform_data + * field to that copy. The @info is copied so that the original can be marked + * __initdata. + */ + +void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info) +{ + s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info), + &s3c_device_ohci); +} +#endif /* CONFIG_S3C_DEV_USB_HOST */ + +/* USB Device (Gadget) */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_usbgadget_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_USBDEV, S3C24XX_SZ_USBDEV), + [1] = DEFINE_RES_IRQ(IRQ_USBD), +}; + +struct platform_device s3c_device_usbgadget = { + .name = "s3c2410-usbgadget", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_usbgadget_resource), + .resource = s3c_usbgadget_resource, +}; + +void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd) +{ + s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usbgadget); +} +#endif /* CONFIG_PLAT_S3C24XX */ + +/* USB HSOTG */ + +#ifdef CONFIG_S3C_DEV_USB_HSOTG +static struct resource s3c_usb_hsotg_resources[] = { + [0] = DEFINE_RES_MEM(S3C_PA_USB_HSOTG, SZ_128K), + [1] = DEFINE_RES_IRQ(IRQ_OTG), +}; + +struct platform_device s3c_device_usb_hsotg = { + .name = "s3c-hsotg", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_usb_hsotg_resources), + .resource = s3c_usb_hsotg_resources, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd) +{ + struct s3c_hsotg_plat *npd; + + npd = s3c_set_platdata(pd, sizeof(struct s3c_hsotg_plat), + &s3c_device_usb_hsotg); + + if (!npd->phy_init) + npd->phy_init = s5p_usb_phy_init; + if (!npd->phy_exit) + npd->phy_exit = s5p_usb_phy_exit; +} +#endif /* CONFIG_S3C_DEV_USB_HSOTG */ + +/* USB High Spped 2.0 Device (Gadget) */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_hsudc_resource[] = { + [0] = DEFINE_RES_MEM(S3C2416_PA_HSUDC, S3C2416_SZ_HSUDC), + [1] = DEFINE_RES_IRQ(IRQ_USBD), +}; + +struct platform_device s3c_device_usb_hsudc = { + .name = "s3c-hsudc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_hsudc_resource), + .resource = s3c_hsudc_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd) +{ + s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usb_hsudc); +} +#endif /* CONFIG_PLAT_S3C24XX */ + +/* WDT */ + +#ifdef CONFIG_S3C_DEV_WDT +static struct resource s3c_wdt_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_WDT, SZ_1K), + [1] = DEFINE_RES_IRQ(IRQ_WDT), +}; + +struct platform_device s3c_device_wdt = { + .name = "s3c2410-wdt", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_wdt_resource), + .resource = s3c_wdt_resource, +}; +#endif /* CONFIG_S3C_DEV_WDT */ + +#ifdef CONFIG_S3C64XX_DEV_SPI0 +static struct resource s3c64xx_spi0_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_SPI0, SZ_256), + [1] = DEFINE_RES_DMA(DMACH_SPI0_TX), + [2] = DEFINE_RES_DMA(DMACH_SPI0_RX), + [3] = DEFINE_RES_IRQ(IRQ_SPI0), +}; + +struct platform_device s3c64xx_device_spi0 = { + .name = "s3c6410-spi", + .id = 0, + .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource), + .resource = s3c64xx_spi0_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, + int num_cs) +{ + struct s3c64xx_spi_info pd; + + /* Reject invalid configuration */ + if (!num_cs || src_clk_nr < 0) { + pr_err("%s: Invalid SPI configuration\n", __func__); + return; + } + + pd.num_cs = num_cs; + pd.src_clk_nr = src_clk_nr; + pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio; +#if defined(CONFIG_PL330_DMA) + pd.filter = pl330_filter; +#elif defined(CONFIG_S3C64XX_PL080) + pd.filter = pl08x_filter_id; +#elif defined(CONFIG_S3C24XX_DMAC) + pd.filter = s3c24xx_dma_filter; +#endif + + s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0); +} +#endif /* CONFIG_S3C64XX_DEV_SPI0 */ + +#ifdef CONFIG_S3C64XX_DEV_SPI1 +static struct resource s3c64xx_spi1_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_SPI1, SZ_256), + [1] = DEFINE_RES_DMA(DMACH_SPI1_TX), + [2] = DEFINE_RES_DMA(DMACH_SPI1_RX), + [3] = DEFINE_RES_IRQ(IRQ_SPI1), +}; + +struct platform_device s3c64xx_device_spi1 = { + .name = "s3c6410-spi", + .id = 1, + .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource), + .resource = s3c64xx_spi1_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, + int num_cs) +{ + struct s3c64xx_spi_info pd; + + /* Reject invalid configuration */ + if (!num_cs || src_clk_nr < 0) { + pr_err("%s: Invalid SPI configuration\n", __func__); + return; + } + + pd.num_cs = num_cs; + pd.src_clk_nr = src_clk_nr; + pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio; +#if defined(CONFIG_PL330_DMA) + pd.filter = pl330_filter; +#elif defined(CONFIG_S3C64XX_PL080) + pd.filter = pl08x_filter_id; +#endif + + s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1); +} +#endif /* CONFIG_S3C64XX_DEV_SPI1 */ + +#ifdef CONFIG_S3C64XX_DEV_SPI2 +static struct resource s3c64xx_spi2_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_SPI2, SZ_256), + [1] = DEFINE_RES_DMA(DMACH_SPI2_TX), + [2] = DEFINE_RES_DMA(DMACH_SPI2_RX), + [3] = DEFINE_RES_IRQ(IRQ_SPI2), +}; + +struct platform_device s3c64xx_device_spi2 = { + .name = "s3c6410-spi", + .id = 2, + .num_resources = ARRAY_SIZE(s3c64xx_spi2_resource), + .resource = s3c64xx_spi2_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, + int num_cs) +{ + struct s3c64xx_spi_info pd; + + /* Reject invalid configuration */ + if (!num_cs || src_clk_nr < 0) { + pr_err("%s: Invalid SPI configuration\n", __func__); + return; + } + + pd.num_cs = num_cs; + pd.src_clk_nr = src_clk_nr; + pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio; +#if defined(CONFIG_PL330_DMA) + pd.filter = pl330_filter; +#elif defined(CONFIG_S3C64XX_PL080) + pd.filter = pl08x_filter_id; +#endif + + s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2); +} +#endif /* CONFIG_S3C64XX_DEV_SPI2 */ diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c new file mode 100644 index 00000000000..886326ee6f6 --- /dev/null +++ b/arch/arm/plat-samsung/dma-ops.c @@ -0,0 +1,146 @@ +/* linux/arch/arm/plat-samsung/dma-ops.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Samsung DMA Operations + * + * 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/errno.h> +#include <linux/amba/pl330.h> +#include <linux/scatterlist.h> +#include <linux/export.h> + +#include <mach/dma.h> + +#if defined(CONFIG_PL330_DMA) +#define dma_filter pl330_filter +#elif defined(CONFIG_S3C64XX_PL080) +#define dma_filter pl08x_filter_id +#endif + +static unsigned samsung_dmadev_request(enum dma_ch dma_ch, + struct samsung_dma_req *param, + struct device *dev, char *ch_name) +{ + dma_cap_mask_t mask; + + dma_cap_zero(mask); + dma_cap_set(param->cap, mask); + + if (dev->of_node) + return (unsigned)dma_request_slave_channel(dev, ch_name); + else + return (unsigned)dma_request_channel(mask, dma_filter, + (void *)dma_ch); +} + +static int samsung_dmadev_release(unsigned ch, void *param) +{ + dma_release_channel((struct dma_chan *)ch); + + return 0; +} + +static int samsung_dmadev_config(unsigned ch, + struct samsung_dma_config *param) +{ + struct dma_chan *chan = (struct dma_chan *)ch; + struct dma_slave_config slave_config; + + if (param->direction == DMA_DEV_TO_MEM) { + memset(&slave_config, 0, sizeof(struct dma_slave_config)); + slave_config.direction = param->direction; + slave_config.src_addr = param->fifo; + slave_config.src_addr_width = param->width; + slave_config.src_maxburst = 1; + dmaengine_slave_config(chan, &slave_config); + } else if (param->direction == DMA_MEM_TO_DEV) { + memset(&slave_config, 0, sizeof(struct dma_slave_config)); + slave_config.direction = param->direction; + slave_config.dst_addr = param->fifo; + slave_config.dst_addr_width = param->width; + slave_config.dst_maxburst = 1; + dmaengine_slave_config(chan, &slave_config); + } else { + pr_warn("unsupported direction\n"); + return -EINVAL; + } + + return 0; +} + +static int samsung_dmadev_prepare(unsigned ch, + struct samsung_dma_prep *param) +{ + struct scatterlist sg; + struct dma_chan *chan = (struct dma_chan *)ch; + struct dma_async_tx_descriptor *desc; + + switch (param->cap) { + case DMA_SLAVE: + sg_init_table(&sg, 1); + sg_dma_len(&sg) = param->len; + sg_set_page(&sg, pfn_to_page(PFN_DOWN(param->buf)), + param->len, offset_in_page(param->buf)); + sg_dma_address(&sg) = param->buf; + + desc = dmaengine_prep_slave_sg(chan, + &sg, 1, param->direction, DMA_PREP_INTERRUPT); + break; + case DMA_CYCLIC: + desc = dmaengine_prep_dma_cyclic(chan, param->buf, + param->len, param->period, param->direction, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + break; + default: + dev_err(&chan->dev->device, "unsupported format\n"); + return -EFAULT; + } + + if (!desc) { + dev_err(&chan->dev->device, "cannot prepare cyclic dma\n"); + return -EFAULT; + } + + desc->callback = param->fp; + desc->callback_param = param->fp_param; + + dmaengine_submit((struct dma_async_tx_descriptor *)desc); + + return 0; +} + +static inline int samsung_dmadev_trigger(unsigned ch) +{ + dma_async_issue_pending((struct dma_chan *)ch); + + return 0; +} + +static inline int samsung_dmadev_flush(unsigned ch) +{ + return dmaengine_terminate_all((struct dma_chan *)ch); +} + +static struct samsung_dma_ops dmadev_ops = { + .request = samsung_dmadev_request, + .release = samsung_dmadev_release, + .config = samsung_dmadev_config, + .prepare = samsung_dmadev_prepare, + .trigger = samsung_dmadev_trigger, + .started = NULL, + .flush = samsung_dmadev_flush, + .stop = samsung_dmadev_flush, +}; + +void *samsung_dmadev_get_ops(void) +{ + return &dmadev_ops; +} +EXPORT_SYMBOL(samsung_dmadev_get_ops); diff --git a/arch/arm/plat-samsung/dma.c b/arch/arm/plat-samsung/dma.c index cb459dd9545..6143aa14768 100644 --- a/arch/arm/plat-samsung/dma.c +++ b/arch/arm/plat-samsung/dma.c @@ -41,7 +41,7 @@ struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel) * irq? */ -int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn) +int s3c2410_dma_set_opfn(enum dma_ch channel, s3c2410_dma_opfn_t rtn) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); @@ -56,7 +56,7 @@ int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn) } EXPORT_SYMBOL(s3c2410_dma_set_opfn); -int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn) +int s3c2410_dma_set_buffdone_fn(enum dma_ch channel, s3c2410_dma_cbfn_t rtn) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); @@ -71,7 +71,7 @@ int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn) } EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn); -int s3c2410_dma_setflags(unsigned int channel, unsigned int flags) +int s3c2410_dma_setflags(enum dma_ch channel, unsigned int flags) { struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c deleted file mode 100644 index 1c0b0401594..00000000000 --- a/arch/arm/plat-samsung/gpio-config.c +++ /dev/null @@ -1,431 +0,0 @@ -/* linux/arch/arm/plat-s3c/gpio-config.c - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008-2010 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C series GPIO configuration 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/gpio.h> -#include <linux/io.h> - -#include <plat/gpio-core.h> -#include <plat/gpio-cfg.h> -#include <plat/gpio-cfg-helpers.h> - -int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) -{ - struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); - unsigned long flags; - int offset; - int ret; - - if (!chip) - return -EINVAL; - - offset = pin - chip->chip.base; - - s3c_gpio_lock(chip, flags); - ret = s3c_gpio_do_setcfg(chip, offset, config); - s3c_gpio_unlock(chip, flags); - - return ret; -} -EXPORT_SYMBOL(s3c_gpio_cfgpin); - -int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr, - unsigned int cfg) -{ - int ret; - - for (; nr > 0; nr--, start++) { - ret = s3c_gpio_cfgpin(start, cfg); - if (ret != 0) - return ret; - } - - return 0; -} -EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range); - -int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr, - unsigned int cfg, s3c_gpio_pull_t pull) -{ - int ret; - - for (; nr > 0; nr--, start++) { - s3c_gpio_setpull(start, pull); - ret = s3c_gpio_cfgpin(start, cfg); - if (ret != 0) - return ret; - } - - return 0; -} -EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range); - -unsigned s3c_gpio_getcfg(unsigned int pin) -{ - struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); - unsigned long flags; - unsigned ret = 0; - int offset; - - if (chip) { - offset = pin - chip->chip.base; - - s3c_gpio_lock(chip, flags); - ret = s3c_gpio_do_getcfg(chip, offset); - s3c_gpio_unlock(chip, flags); - } - - return ret; -} -EXPORT_SYMBOL(s3c_gpio_getcfg); - - -int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) -{ - struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); - unsigned long flags; - int offset, ret; - - if (!chip) - return -EINVAL; - - offset = pin - chip->chip.base; - - s3c_gpio_lock(chip, flags); - ret = s3c_gpio_do_setpull(chip, offset, pull); - s3c_gpio_unlock(chip, flags); - - return ret; -} -EXPORT_SYMBOL(s3c_gpio_setpull); - -s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin) -{ - struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); - unsigned long flags; - int offset; - u32 pup = 0; - - if (chip) { - offset = pin - chip->chip.base; - - s3c_gpio_lock(chip, flags); - pup = s3c_gpio_do_getpull(chip, offset); - s3c_gpio_unlock(chip, flags); - } - - return (__force s3c_gpio_pull_t)pup; -} -EXPORT_SYMBOL(s3c_gpio_getpull); - -#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX -int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, - unsigned int off, unsigned int cfg) -{ - void __iomem *reg = chip->base; - unsigned int shift = off; - u32 con; - - if (s3c_gpio_is_cfg_special(cfg)) { - cfg &= 0xf; - - /* Map output to 0, and SFN2 to 1 */ - cfg -= 1; - if (cfg > 1) - return -EINVAL; - - cfg <<= shift; - } - - con = __raw_readl(reg); - con &= ~(0x1 << shift); - con |= cfg; - __raw_writel(con, reg); - - return 0; -} - -unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip, - unsigned int off) -{ - u32 con; - - con = __raw_readl(chip->base); - con >>= off; - con &= 1; - con++; - - return S3C_GPIO_SFN(con); -} - -int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, - unsigned int off, unsigned int cfg) -{ - void __iomem *reg = chip->base; - unsigned int shift = off * 2; - u32 con; - - if (s3c_gpio_is_cfg_special(cfg)) { - cfg &= 0xf; - if (cfg > 3) - return -EINVAL; - - cfg <<= shift; - } - - con = __raw_readl(reg); - con &= ~(0x3 << shift); - con |= cfg; - __raw_writel(con, reg); - - return 0; -} - -unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip, - unsigned int off) -{ - u32 con; - - con = __raw_readl(chip->base); - con >>= off * 2; - con &= 3; - - /* this conversion works for IN and OUT as well as special mode */ - return S3C_GPIO_SPECIAL(con); -} -#endif - -#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX -int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, - unsigned int off, unsigned int cfg) -{ - void __iomem *reg = chip->base; - unsigned int shift = (off & 7) * 4; - u32 con; - - if (off < 8 && chip->chip.ngpio > 8) - reg -= 4; - - if (s3c_gpio_is_cfg_special(cfg)) { - cfg &= 0xf; - cfg <<= shift; - } - - con = __raw_readl(reg); - con &= ~(0xf << shift); - con |= cfg; - __raw_writel(con, reg); - - return 0; -} - -unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, - unsigned int off) -{ - void __iomem *reg = chip->base; - unsigned int shift = (off & 7) * 4; - u32 con; - - if (off < 8 && chip->chip.ngpio > 8) - reg -= 4; - - con = __raw_readl(reg); - con >>= shift; - con &= 0xf; - - /* this conversion works for IN and OUT as well as special mode */ - return S3C_GPIO_SPECIAL(con); -} - -#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */ - -#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN -int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip, - unsigned int off, s3c_gpio_pull_t pull) -{ - void __iomem *reg = chip->base + 0x08; - int shift = off * 2; - u32 pup; - - pup = __raw_readl(reg); - pup &= ~(3 << shift); - pup |= pull << shift; - __raw_writel(pup, reg); - - return 0; -} - -s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip, - unsigned int off) -{ - void __iomem *reg = chip->base + 0x08; - int shift = off * 2; - u32 pup = __raw_readl(reg); - - pup >>= shift; - pup &= 0x3; - return (__force s3c_gpio_pull_t)pup; -} - -#ifdef CONFIG_S3C_GPIO_PULL_S3C2443 -int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip, - unsigned int off, s3c_gpio_pull_t pull) -{ - switch (pull) { - case S3C_GPIO_PULL_NONE: - pull = 0x01; - break; - case S3C_GPIO_PULL_UP: - pull = 0x00; - break; - case S3C_GPIO_PULL_DOWN: - pull = 0x02; - break; - } - return s3c_gpio_setpull_updown(chip, off, pull); -} - -s3c_gpio_pull_t s3c_gpio_getpull_s3c2443(struct s3c_gpio_chip *chip, - unsigned int off) -{ - s3c_gpio_pull_t pull; - - pull = s3c_gpio_getpull_updown(chip, off); - - switch (pull) { - case 0x00: - pull = S3C_GPIO_PULL_UP; - break; - case 0x01: - case 0x03: - pull = S3C_GPIO_PULL_NONE; - break; - case 0x02: - pull = S3C_GPIO_PULL_DOWN; - break; - } - - return pull; -} -#endif -#endif - -#if defined(CONFIG_S3C_GPIO_PULL_UP) || defined(CONFIG_S3C_GPIO_PULL_DOWN) -static int s3c_gpio_setpull_1(struct s3c_gpio_chip *chip, - unsigned int off, s3c_gpio_pull_t pull, - s3c_gpio_pull_t updown) -{ - void __iomem *reg = chip->base + 0x08; - u32 pup = __raw_readl(reg); - - if (pull == updown) - pup &= ~(1 << off); - else if (pull == S3C_GPIO_PULL_NONE) - pup |= (1 << off); - else - return -EINVAL; - - __raw_writel(pup, reg); - return 0; -} - -static s3c_gpio_pull_t s3c_gpio_getpull_1(struct s3c_gpio_chip *chip, - unsigned int off, s3c_gpio_pull_t updown) -{ - void __iomem *reg = chip->base + 0x08; - u32 pup = __raw_readl(reg); - - pup &= (1 << off); - return pup ? S3C_GPIO_PULL_NONE : updown; -} -#endif /* CONFIG_S3C_GPIO_PULL_UP || CONFIG_S3C_GPIO_PULL_DOWN */ - -#ifdef CONFIG_S3C_GPIO_PULL_UP -s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, - unsigned int off) -{ - return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP); -} - -int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, - unsigned int off, s3c_gpio_pull_t pull) -{ - return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP); -} -#endif /* CONFIG_S3C_GPIO_PULL_UP */ - -#ifdef CONFIG_S3C_GPIO_PULL_DOWN -s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip, - unsigned int off) -{ - return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN); -} - -int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip, - unsigned int off, s3c_gpio_pull_t pull) -{ - return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN); -} -#endif /* CONFIG_S3C_GPIO_PULL_DOWN */ - -#ifdef CONFIG_S5P_GPIO_DRVSTR -s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) -{ - struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); - unsigned int off; - void __iomem *reg; - int shift; - u32 drvstr; - - if (!chip) - return -EINVAL; - - off = pin - chip->chip.base; - shift = off * 2; - reg = chip->base + 0x0C; - - drvstr = __raw_readl(reg); - drvstr = drvstr >> shift; - drvstr &= 0x3; - - return (__force s5p_gpio_drvstr_t)drvstr; -} -EXPORT_SYMBOL(s5p_gpio_get_drvstr); - -int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr) -{ - struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); - unsigned int off; - void __iomem *reg; - int shift; - u32 tmp; - - if (!chip) - return -EINVAL; - - off = pin - chip->chip.base; - shift = off * 2; - reg = chip->base + 0x0C; - - tmp = __raw_readl(reg); - tmp &= ~(0x3 << shift); - tmp |= drvstr << shift; - - __raw_writel(tmp, reg); - - return 0; -} -EXPORT_SYMBOL(s5p_gpio_set_drvstr); -#endif /* CONFIG_S5P_GPIO_DRVSTR */ diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c deleted file mode 100644 index 7743c4b8b2f..00000000000 --- a/arch/arm/plat-samsung/gpio.c +++ /dev/null @@ -1,167 +0,0 @@ -/* linux/arch/arm/plat-s3c/gpio.c - * - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C series GPIO 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/init.h> -#include <linux/io.h> -#include <linux/gpio.h> -#include <linux/spinlock.h> - -#include <plat/gpio-core.h> - -#ifdef CONFIG_S3C_GPIO_TRACK -struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END]; - -static __init void s3c_gpiolib_track(struct s3c_gpio_chip *chip) -{ - unsigned int gpn; - int i; - - gpn = chip->chip.base; - for (i = 0; i < chip->chip.ngpio; i++, gpn++) { - BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios)); - s3c_gpios[gpn] = chip; - } -} -#endif /* CONFIG_S3C_GPIO_TRACK */ - -/* Default routines for controlling GPIO, based on the original S3C24XX - * GPIO functions which deal with the case where each gpio bank of the - * chip is as following: - * - * base + 0x00: Control register, 2 bits per gpio - * gpio n: 2 bits starting at (2*n) - * 00 = input, 01 = output, others mean special-function - * base + 0x04: Data register, 1 bit per gpio - * bit n: data bit n -*/ - -static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset) -{ - struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); - void __iomem *base = ourchip->base; - unsigned long flags; - unsigned long con; - - s3c_gpio_lock(ourchip, flags); - - con = __raw_readl(base + 0x00); - con &= ~(3 << (offset * 2)); - - __raw_writel(con, base + 0x00); - - s3c_gpio_unlock(ourchip, flags); - return 0; -} - -static int s3c_gpiolib_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); - void __iomem *base = ourchip->base; - unsigned long flags; - unsigned long dat; - unsigned long con; - - s3c_gpio_lock(ourchip, flags); - - dat = __raw_readl(base + 0x04); - dat &= ~(1 << offset); - if (value) - dat |= 1 << offset; - __raw_writel(dat, base + 0x04); - - con = __raw_readl(base + 0x00); - con &= ~(3 << (offset * 2)); - con |= 1 << (offset * 2); - - __raw_writel(con, base + 0x00); - __raw_writel(dat, base + 0x04); - - s3c_gpio_unlock(ourchip, flags); - return 0; -} - -static void s3c_gpiolib_set(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); - void __iomem *base = ourchip->base; - unsigned long flags; - unsigned long dat; - - s3c_gpio_lock(ourchip, flags); - - dat = __raw_readl(base + 0x04); - dat &= ~(1 << offset); - if (value) - dat |= 1 << offset; - __raw_writel(dat, base + 0x04); - - s3c_gpio_unlock(ourchip, flags); -} - -static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset) -{ - struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); - unsigned long val; - - val = __raw_readl(ourchip->base + 0x04); - val >>= offset; - val &= 1; - - return val; -} - -__init void s3c_gpiolib_add(struct s3c_gpio_chip *chip) -{ - struct gpio_chip *gc = &chip->chip; - int ret; - - BUG_ON(!chip->base); - BUG_ON(!gc->label); - BUG_ON(!gc->ngpio); - - spin_lock_init(&chip->lock); - - if (!gc->direction_input) - gc->direction_input = s3c_gpiolib_input; - if (!gc->direction_output) - gc->direction_output = s3c_gpiolib_output; - if (!gc->set) - gc->set = s3c_gpiolib_set; - if (!gc->get) - gc->get = s3c_gpiolib_get; - -#ifdef CONFIG_PM - if (chip->pm != NULL) { - if (!chip->pm->save || !chip->pm->resume) - printk(KERN_ERR "gpio: %s has missing PM functions\n", - gc->label); - } else - printk(KERN_ERR "gpio: %s has no PM function\n", gc->label); -#endif - - /* gpiochip_add() prints own failure message on error. */ - ret = gpiochip_add(gc); - if (ret >= 0) - s3c_gpiolib_track(chip); -} - -int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) -{ - struct s3c_gpio_chip *s3c_chip = container_of(chip, - struct s3c_gpio_chip, chip); - - return s3c_chip->irq_base + offset; -} diff --git a/arch/arm/plat-samsung/gpiolib.c b/arch/arm/plat-samsung/gpiolib.c deleted file mode 100644 index ea37c046178..00000000000 --- a/arch/arm/plat-samsung/gpiolib.c +++ /dev/null @@ -1,206 +0,0 @@ -/* arch/arm/plat-samsung/gpiolib.c - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * SAMSUNG - GPIOlib 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/kernel.h> -#include <linux/irq.h> -#include <linux/io.h> -#include <linux/gpio.h> -#include <plat/gpio-core.h> -#include <plat/gpio-cfg.h> -#include <plat/gpio-cfg-helpers.h> - -#ifndef DEBUG_GPIO -#define gpio_dbg(x...) do { } while (0) -#else -#define gpio_dbg(x...) printk(KERN_DEBUG x) -#endif - -/* The samsung_gpiolib_4bit routines are to control the gpio banks where - * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the - * following example: - * - * base + 0x00: Control register, 4 bits per gpio - * gpio n: 4 bits starting at (4*n) - * 0000 = input, 0001 = output, others mean special-function - * base + 0x04: Data register, 1 bit per gpio - * bit n: data bit n - * - * Note, since the data register is one bit per gpio and is at base + 0x4 - * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of - * the output. -*/ - -static int samsung_gpiolib_4bit_input(struct gpio_chip *chip, - unsigned int offset) -{ - struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); - void __iomem *base = ourchip->base; - unsigned long con; - - con = __raw_readl(base + GPIOCON_OFF); - con &= ~(0xf << con_4bit_shift(offset)); - __raw_writel(con, base + GPIOCON_OFF); - - gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con); - - return 0; -} - -static int samsung_gpiolib_4bit_output(struct gpio_chip *chip, - unsigned int offset, int value) -{ - struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); - void __iomem *base = ourchip->base; - unsigned long con; - unsigned long dat; - - con = __raw_readl(base + GPIOCON_OFF); - con &= ~(0xf << con_4bit_shift(offset)); - con |= 0x1 << con_4bit_shift(offset); - - dat = __raw_readl(base + GPIODAT_OFF); - - if (value) - dat |= 1 << offset; - else - dat &= ~(1 << offset); - - __raw_writel(dat, base + GPIODAT_OFF); - __raw_writel(con, base + GPIOCON_OFF); - __raw_writel(dat, base + GPIODAT_OFF); - - gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); - - return 0; -} - -/* The next set of routines are for the case where the GPIO configuration - * registers are 4 bits per GPIO but there is more than one register (the - * bank has more than 8 GPIOs. - * - * This case is the similar to the 4 bit case, but the registers are as - * follows: - * - * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs) - * gpio n: 4 bits starting at (4*n) - * 0000 = input, 0001 = output, others mean special-function - * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs) - * gpio n: 4 bits starting at (4*n) - * 0000 = input, 0001 = output, others mean special-function - * base + 0x08: Data register, 1 bit per gpio - * bit n: data bit n - * - * To allow us to use the s3c_gpiolib_get and s3c_gpiolib_set routines we - * store the 'base + 0x4' address so that these routines see the data - * register at ourchip->base + 0x04. - */ - -static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip, - unsigned int offset) -{ - struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); - void __iomem *base = ourchip->base; - void __iomem *regcon = base; - unsigned long con; - - if (offset > 7) - offset -= 8; - else - regcon -= 4; - - con = __raw_readl(regcon); - con &= ~(0xf << con_4bit_shift(offset)); - __raw_writel(con, regcon); - - gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con); - - return 0; -} - -static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip, - unsigned int offset, int value) -{ - struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); - void __iomem *base = ourchip->base; - void __iomem *regcon = base; - unsigned long con; - unsigned long dat; - unsigned con_offset = offset; - - if (con_offset > 7) - con_offset -= 8; - else - regcon -= 4; - - con = __raw_readl(regcon); - con &= ~(0xf << con_4bit_shift(con_offset)); - con |= 0x1 << con_4bit_shift(con_offset); - - dat = __raw_readl(base + GPIODAT_OFF); - - if (value) - dat |= 1 << offset; - else - dat &= ~(1 << offset); - - __raw_writel(dat, base + GPIODAT_OFF); - __raw_writel(con, regcon); - __raw_writel(dat, base + GPIODAT_OFF); - - gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); - - return 0; -} - -void __init samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip) -{ - chip->chip.direction_input = samsung_gpiolib_4bit_input; - chip->chip.direction_output = samsung_gpiolib_4bit_output; - chip->pm = __gpio_pm(&s3c_gpio_pm_4bit); -} - -void __init samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip) -{ - chip->chip.direction_input = samsung_gpiolib_4bit2_input; - chip->chip.direction_output = samsung_gpiolib_4bit2_output; - chip->pm = __gpio_pm(&s3c_gpio_pm_4bit); -} - -void __init samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip, - int nr_chips) -{ - for (; nr_chips > 0; nr_chips--, chip++) { - samsung_gpiolib_add_4bit(chip); - s3c_gpiolib_add(chip); - } -} - -void __init samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip, - int nr_chips) -{ - for (; nr_chips > 0; nr_chips--, chip++) { - samsung_gpiolib_add_4bit2(chip); - s3c_gpiolib_add(chip); - } -} - -void __init samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip, - int nr_chips) -{ - for (; nr_chips > 0; nr_chips--, chip++) - s3c_gpiolib_add(chip); -} diff --git a/arch/arm/plat-samsung/include/plat/adc-core.h b/arch/arm/plat-samsung/include/plat/adc-core.h index a281568d585..a927bee5535 100644 --- a/arch/arm/plat-samsung/include/plat/adc-core.h +++ b/arch/arm/plat-samsung/include/plat/adc-core.h @@ -20,7 +20,7 @@ /* re-define device name depending on support. */ static inline void s3c_adc_setname(char *name) { -#ifdef CONFIG_SAMSUNG_DEV_ADC +#if defined(CONFIG_SAMSUNG_DEV_ADC) || defined(CONFIG_PLAT_S3C24XX) s3c_device_adc.name = name; #endif } diff --git a/arch/arm/plat-samsung/include/plat/adc.h b/arch/arm/plat-samsung/include/plat/adc.h index b258a08de59..2fc89315553 100644 --- a/arch/arm/plat-samsung/include/plat/adc.h +++ b/arch/arm/plat-samsung/include/plat/adc.h @@ -15,6 +15,7 @@ #define __ASM_PLAT_ADC_H __FILE__ struct s3c_adc_client; +struct platform_device; extern int s3c_adc_start(struct s3c_adc_client *client, unsigned int channel, unsigned int nr_samples); diff --git a/arch/arm/plat-samsung/include/plat/ata.h b/arch/arm/plat-samsung/include/plat/ata.h deleted file mode 100644 index 2a3855a8372..00000000000 --- a/arch/arm/plat-samsung/include/plat/ata.h +++ /dev/null @@ -1,36 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/ata.h - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Samsung CF-ATA platform_device info - * - * 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_PLAT_ATA_H -#define __ASM_PLAT_ATA_H __FILE__ - -/** - * struct s3c_ide_platdata - S3C IDE driver platform data. - * @setup_gpio: Setup the external GPIO pins to the right state for data - * transfer in true-ide mode. - */ -struct s3c_ide_platdata { - void (*setup_gpio)(void); -}; - -/* - * s3c_ide_set_platdata() - Setup the platform specifc data for IDE driver. - * @pdata: Platform data for IDE driver. - */ -extern void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata); - -/* architecture-specific IDE configuration */ -extern void s3c64xx_ide_setup_gpio(void); -extern void s5pc100_ide_setup_gpio(void); -extern void s5pv210_ide_setup_gpio(void); - -#endif /*__ASM_PLAT_ATA_H */ diff --git a/arch/arm/plat-samsung/include/plat/audio.h b/arch/arm/plat-samsung/include/plat/audio.h deleted file mode 100644 index a0826ed2f9f..00000000000 --- a/arch/arm/plat-samsung/include/plat/audio.h +++ /dev/null @@ -1,58 +0,0 @@ -/* arch/arm/plat-samsung/include/plat/audio.h - * - * Copyright (c) 2009 Samsung Electronics Co. Ltd - * Author: 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. - */ - -/* The machine init code calls s3c*_ac97_setup_gpio with - * one of these defines in order to select appropriate bank - * of GPIO for AC97 pins - */ -#define S3C64XX_AC97_GPD 0 -#define S3C64XX_AC97_GPE 1 -extern void s3c64xx_ac97_setup_gpio(int); - -/* - * The machine init code calls s5p*_spdif_setup_gpio with - * one of these defines in order to select appropriate bank - * of GPIO for S/PDIF pins - */ -#define S5PC100_SPDIF_GPD 0 -#define S5PC100_SPDIF_GPG3 1 -extern void s5pc100_spdif_setup_gpio(int); - -struct samsung_i2s { -/* If the Primary DAI has 5.1 Channels */ -#define QUIRK_PRI_6CHAN (1 << 0) -/* If the I2S block has a Stereo Overlay Channel */ -#define QUIRK_SEC_DAI (1 << 1) -/* - * If the I2S block has no internal prescalar or MUX (I2SMOD[10] bit) - * The Machine driver must provide suitably set clock to the I2S block. - */ -#define QUIRK_NO_MUXPSR (1 << 2) -#define QUIRK_NEED_RSTCLR (1 << 3) - /* Quirks of the I2S controller */ - u32 quirks; - - /* - * Array of clock names that can be used to generate I2S signals. - * Also corresponds to clocks of I2SMOD[10] - */ - const char **src_clk; -}; - -/** - * struct s3c_audio_pdata - common platform data for audio device drivers - * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode - */ -struct s3c_audio_pdata { - int (*cfg_gpio)(struct platform_device *); - union { - struct samsung_i2s i2s; - } type; -}; diff --git a/arch/arm/plat-samsung/include/plat/backlight.h b/arch/arm/plat-samsung/include/plat/backlight.h new file mode 100644 index 00000000000..ad530c78fe8 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/backlight.h @@ -0,0 +1,26 @@ +/* linux/arch/arm/plat-samsung/include/plat/backlight.h + * + * 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. + */ + +#ifndef __ASM_PLAT_BACKLIGHT_H +#define __ASM_PLAT_BACKLIGHT_H __FILE__ + +/* samsung_bl_gpio_info - GPIO info for PWM Backlight control + * @no: GPIO number for PWM timer out + * @func: Special function of GPIO line for PWM timer + */ +struct samsung_bl_gpio_info { + int no; + int func; +}; + +extern void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, + struct platform_pwm_backlight_data *bl_data); + +#endif /* __ASM_PLAT_BACKLIGHT_H */ diff --git a/arch/arm/plat-samsung/include/plat/camport.h b/arch/arm/plat-samsung/include/plat/camport.h new file mode 100644 index 00000000000..a5708bf84b3 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/camport.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2011 Samsung Electronics Co., Ltd. + * + * S5P series camera interface helper functions + * + * 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_SAMSUNG_CAMPORT_H_ +#define __PLAT_SAMSUNG_CAMPORT_H_ __FILE__ + +enum s5p_camport_id { + S5P_CAMPORT_A, + S5P_CAMPORT_B, +}; + +/* + * The helper functions to configure GPIO for the camera parallel bus. + * The camera port can be multiplexed with any FIMC entity, even multiple + * FIMC entities are allowed to be attached to a single port simultaneously. + * These functions are to be used in the board setup code. + */ +int s5pv210_fimc_setup_gpio(enum s5p_camport_id id); +int exynos4_fimc_setup_gpio(enum s5p_camport_id id); + +#endif /* __PLAT_SAMSUNG_CAMPORT_H */ diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h index 9a82b887491..63239f40980 100644 --- a/arch/arm/plat-samsung/include/plat/clock.h +++ b/arch/arm/plat-samsung/include/plat/clock.h @@ -9,7 +9,11 @@ * published by the Free Software Foundation. */ +#ifndef __ASM_PLAT_CLOCK_H +#define __ASM_PLAT_CLOCK_H __FILE__ + #include <linux/spinlock.h> +#include <linux/clkdev.h> struct clk; @@ -21,7 +25,7 @@ struct clk; * @set_parent: set the clock's parent, see clk_set_parent(). * * Group the common clock implementations together so that we - * don't have to keep setting the same fiels again. We leave + * don't have to keep setting the same fields again. We leave * enable in struct clk. * * Adding an extra layer of indirection into the process should @@ -40,6 +44,7 @@ struct clk { struct module *owner; struct clk *parent; const char *name; + const char *devname; int id; int usage; unsigned long rate; @@ -47,6 +52,7 @@ struct clk { struct clk_ops *ops; int (*enable)(struct clk *, int enable); + struct clk_lookup lookup; #if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) struct dentry *dent; /* For visible tree hierarchy */ #endif @@ -73,6 +79,15 @@ extern struct clk clk_epll; extern struct clk clk_xtal; extern struct clk clk_ext; +/* S3C2443/S3C2416 specific clocks */ +extern struct clksrc_clk clk_epllref; +extern struct clksrc_clk clk_esysclk; + +/* S3C24XX UART clocks */ +extern struct clk s3c24xx_clk_uart0; +extern struct clk s3c24xx_clk_uart1; +extern struct clk s3c24xx_clk_uart2; + /* S3C64XX specific clocks */ extern struct clk clk_h2; extern struct clk clk_27m; @@ -108,13 +123,30 @@ extern void s3c24xx_setup_clocks(unsigned long fclk, extern void s3c2410_setup_clocks(void); extern void s3c2412_setup_clocks(void); extern void s3c244x_setup_clocks(void); -extern void s3c2443_setup_clocks(void); + +/* S3C2410 specific clock functions */ + +extern int s3c2410_baseclk_add(void); + +/* S3C2443/S3C2416 specific clock functions */ + +typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base); + +extern void s3c2443_common_setup_clocks(pll_fn get_mpll); +extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, + unsigned int *divs, int nr_divs, + int divmask); + +extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable); +extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable); +extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable); /* S3C64XX specific functions and clocks */ extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable); -/* Init for pwm clock code */ +/* Global watchdog clock used by arch_wtd_reset() callback */ -extern void s3c_pwmclk_init(void); +extern struct clk *s3c2410_wdtclk; +#endif /* __ASM_PLAT_CLOCK_H */ diff --git a/arch/arm/plat-samsung/include/plat/cpu-freq-core.h b/arch/arm/plat-samsung/include/plat/cpu-freq-core.h new file mode 100644 index 00000000000..72d4178ad23 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/cpu-freq-core.h @@ -0,0 +1,294 @@ +/* arch/arm/plat-samsung/include/plat/cpu-freq-core.h + * + * Copyright (c) 2006-2009 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks <ben@simtec.co.uk> + * + * S3C CPU frequency scaling support - core 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 <plat/cpu-freq.h> + +struct seq_file; + +#define MAX_BANKS (8) +#define S3C2412_MAX_IO (8) + +/** + * struct s3c2410_iobank_timing - IO bank timings for S3C2410 style timings + * @bankcon: The cached version of settings in this structure. + * @tacp: + * @tacs: Time from address valid to nCS asserted. + * @tcos: Time from nCS asserted to nOE or nWE asserted. + * @tacc: Time that nOE or nWE is asserted. + * @tcoh: Time nCS is held after nOE or nWE are released. + * @tcah: Time address is held for after + * @nwait_en: Whether nWAIT is enabled for this bank. + * + * This structure represents the IO timings for a S3C2410 style IO bank + * used by the CPU frequency support if it needs to change the settings + * of the IO. + */ +struct s3c2410_iobank_timing { + unsigned long bankcon; + unsigned int tacp; + unsigned int tacs; + unsigned int tcos; + unsigned int tacc; + unsigned int tcoh; /* nCS hold afrer nOE/nWE */ + unsigned int tcah; /* Address hold after nCS */ + unsigned char nwait_en; /* nWait enabled for bank. */ +}; + +/** + * struct s3c2412_iobank_timing - io timings for PL092 (S3C2412) style IO + * @idcy: The idle cycle time between transactions. + * @wstrd: nCS release to end of read cycle. + * @wstwr: nCS release to end of write cycle. + * @wstoen: nCS assertion to nOE assertion time. + * @wstwen: nCS assertion to nWE assertion time. + * @wstbrd: Burst ready delay. + * @smbidcyr: Register cache for smbidcyr value. + * @smbwstrd: Register cache for smbwstrd value. + * @smbwstwr: Register cache for smbwstwr value. + * @smbwstoen: Register cache for smbwstoen value. + * @smbwstwen: Register cache for smbwstwen value. + * @smbwstbrd: Register cache for smbwstbrd value. + * + * Timing information for a IO bank on an S3C2412 or similar system which + * uses a PL093 block. + */ +struct s3c2412_iobank_timing { + unsigned int idcy; + unsigned int wstrd; + unsigned int wstwr; + unsigned int wstoen; + unsigned int wstwen; + unsigned int wstbrd; + + /* register cache */ + unsigned char smbidcyr; + unsigned char smbwstrd; + unsigned char smbwstwr; + unsigned char smbwstoen; + unsigned char smbwstwen; + unsigned char smbwstbrd; +}; + +union s3c_iobank { + struct s3c2410_iobank_timing *io_2410; + struct s3c2412_iobank_timing *io_2412; +}; + +/** + * struct s3c_iotimings - Chip IO timings holder + * @bank: The timings for each IO bank. + */ +struct s3c_iotimings { + union s3c_iobank bank[MAX_BANKS]; +}; + +/** + * struct s3c_plltab - PLL table information. + * @vals: List of PLL values. + * @size: Size of the PLL table @vals. + */ +struct s3c_plltab { + struct s3c_pllval *vals; + int size; +}; + +/** + * struct s3c_cpufreq_config - current cpu frequency configuration + * @freq: The current settings for the core clocks. + * @max: Maxium settings, derived from core, board and user settings. + * @pll: The PLL table entry for the current PLL settings. + * @divs: The divisor settings for the core clocks. + * @info: The current core driver information. + * @board: The information for the board we are running on. + * @lock_pll: Set if the PLL settings cannot be changed. + * + * This is for the core drivers that need to know information about + * the current settings and values. It should not be needed by any + * device drivers. +*/ +struct s3c_cpufreq_config { + struct s3c_freq freq; + struct s3c_freq max; + struct clk *mpll; + struct cpufreq_frequency_table pll; + struct s3c_clkdivs divs; + struct s3c_cpufreq_info *info; /* for core, not drivers */ + struct s3c_cpufreq_board *board; + + unsigned int lock_pll:1; +}; + +/** + * struct s3c_cpufreq_info - Information for the CPU frequency driver. + * @name: The name of this implementation. + * @max: The maximum frequencies for the system. + * @latency: Transition latency to give to cpufreq. + * @locktime_m: The lock-time in uS for the MPLL. + * @locktime_u: The lock-time in uS for the UPLL. + * @locttime_bits: The number of bits each LOCKTIME field. + * @need_pll: Set if this driver needs to change the PLL values to achieve + * any frequency changes. This is really only need by devices like the + * S3C2410 where there is no or limited divider between the PLL and the + * ARMCLK. + * @resume_clocks: Update the clocks on resume. + * @get_iotiming: Get the current IO timing data, mainly for use at start. + * @set_iotiming: Update the IO timings from the cached copies calculated + * from the @calc_iotiming entry when changing the frequency. + * @calc_iotiming: Calculate and update the cached copies of the IO timings + * from the newly calculated frequencies. + * @calc_freqtable: Calculate (fill in) the given frequency table from the + * current frequency configuration. If the table passed in is NULL, + * then the return is the number of elements to be filled for allocation + * of the table. + * @set_refresh: Set the memory refresh configuration. + * @set_fvco: Set the PLL frequencies. + * @set_divs: Update the clock divisors. + * @calc_divs: Calculate the clock divisors. + */ +struct s3c_cpufreq_info { + const char *name; + struct s3c_freq max; + + unsigned int latency; + + unsigned int locktime_m; + unsigned int locktime_u; + unsigned char locktime_bits; + + unsigned int need_pll:1; + + /* driver routines */ + + void (*resume_clocks)(void); + + int (*get_iotiming)(struct s3c_cpufreq_config *cfg, + struct s3c_iotimings *timings); + + void (*set_iotiming)(struct s3c_cpufreq_config *cfg, + struct s3c_iotimings *timings); + + int (*calc_iotiming)(struct s3c_cpufreq_config *cfg, + struct s3c_iotimings *timings); + + int (*calc_freqtable)(struct s3c_cpufreq_config *cfg, + struct cpufreq_frequency_table *t, + size_t table_size); + + void (*debug_io_show)(struct seq_file *seq, + struct s3c_cpufreq_config *cfg, + union s3c_iobank *iob); + + void (*set_refresh)(struct s3c_cpufreq_config *cfg); + void (*set_fvco)(struct s3c_cpufreq_config *cfg); + void (*set_divs)(struct s3c_cpufreq_config *cfg); + int (*calc_divs)(struct s3c_cpufreq_config *cfg); +}; + +extern int s3c_cpufreq_register(struct s3c_cpufreq_info *info); + +extern int s3c_plltab_register(struct cpufreq_frequency_table *plls, + unsigned int plls_no); + +/* exports and utilities for debugfs */ +extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void); +extern struct s3c_iotimings *s3c_cpufreq_getiotimings(void); + +#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS +#define s3c_cpufreq_debugfs_call(x) x +#else +#define s3c_cpufreq_debugfs_call(x) NULL +#endif + +/* Useful utility functions. */ + +extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *); + +/* S3C2410 and compatible exported functions */ + +extern void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg); +extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg); + +#ifdef CONFIG_S3C2410_IOTIMING +extern void s3c2410_iotiming_debugfs(struct seq_file *seq, + struct s3c_cpufreq_config *cfg, + union s3c_iobank *iob); + +extern int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg, + struct s3c_iotimings *iot); + +extern int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg, + struct s3c_iotimings *timings); + +extern void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg, + struct s3c_iotimings *iot); +#else +#define s3c2410_iotiming_debugfs NULL +#define s3c2410_iotiming_calc NULL +#define s3c2410_iotiming_get NULL +#define s3c2410_iotiming_set NULL +#endif /* CONFIG_S3C2410_IOTIMING */ + +/* S3C2412 compatible routines */ + +#ifdef CONFIG_S3C2412_IOTIMING +extern void s3c2412_iotiming_debugfs(struct seq_file *seq, + struct s3c_cpufreq_config *cfg, + union s3c_iobank *iob); + +extern int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg, + struct s3c_iotimings *timings); + +extern int s3c2412_iotiming_calc(struct s3c_cpufreq_config *cfg, + struct s3c_iotimings *iot); + +extern void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg, + struct s3c_iotimings *iot); +#else +#define s3c2412_iotiming_debugfs NULL +#define s3c2412_iotiming_calc NULL +#define s3c2412_iotiming_get NULL +#define s3c2412_iotiming_set NULL +#endif /* CONFIG_S3C2412_IOTIMING */ + +#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_DEBUG +#define s3c_freq_dbg(x...) printk(KERN_INFO x) +#else +#define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0) +#endif /* CONFIG_ARM_S3C24XX_CPUFREQ_DEBUG */ + +#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_IODEBUG +#define s3c_freq_iodbg(x...) printk(KERN_INFO x) +#else +#define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0) +#endif /* CONFIG_ARM_S3C24XX_CPUFREQ_IODEBUG */ + +static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table, + int index, size_t table_size, + unsigned int freq) +{ + if (index < 0) + return index; + + if (table) { + if (index >= table_size) + return -ENOMEM; + + s3c_freq_dbg("%s: { %d = %u kHz }\n", + __func__, index, freq); + + table[index].driver_data = index; + table[index].frequency = freq; + } + + return index + 1; +} diff --git a/arch/arm/plat-samsung/include/plat/cpu-freq.h b/arch/arm/plat-samsung/include/plat/cpu-freq.h index 80c4a809c72..85517ab962a 100644 --- a/arch/arm/plat-samsung/include/plat/cpu-freq.h +++ b/arch/arm/plat-samsung/include/plat/cpu-freq.h @@ -126,7 +126,7 @@ struct s3c_cpufreq_board { }; /* Things depending on frequency scaling. */ -#ifdef CONFIG_CPU_FREQ_S3C +#ifdef CONFIG_ARM_S3C_CPUFREQ #define __init_or_cpufreq #else #define __init_or_cpufreq __init @@ -134,7 +134,7 @@ struct s3c_cpufreq_board { /* Board functions */ -#ifdef CONFIG_CPU_FREQ_S3C +#ifdef CONFIG_ARM_S3C_CPUFREQ extern int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board); #else @@ -142,4 +142,4 @@ static inline int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board) { return 0; } -#endif /* CONFIG_CPU_FREQ_S3C */ +#endif /* CONFIG_ARM_S3C_CPUFREQ */ diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index cedfff51c82..5a237db9f9e 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h @@ -1,9 +1,12 @@ /* linux/arch/arm/plat-samsung/include/plat/cpu.h * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * * Copyright (c) 2004-2005 Simtec Electronics * Ben Dooks <ben@simtec.co.uk> * - * Header file for S3C24XX CPU support + * Header file for Samsung CPU 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 @@ -15,8 +18,104 @@ #ifndef __SAMSUNG_PLAT_CPU_H #define __SAMSUNG_PLAT_CPU_H +extern unsigned long samsung_cpu_id; + +#define S3C2410_CPU_ID 0x32410000 +#define S3C2410_CPU_MASK 0xFFFFFFFF + +#define S3C24XX_CPU_ID 0x32400000 +#define S3C24XX_CPU_MASK 0xFFF00000 + +#define S3C2412_CPU_ID 0x32412000 +#define S3C2412_CPU_MASK 0xFFFFF000 + +#define S3C6400_CPU_ID 0x36400000 +#define S3C6410_CPU_ID 0x36410000 +#define S3C64XX_CPU_MASK 0xFFFFF000 + +#define S5P6440_CPU_ID 0x56440000 +#define S5P6450_CPU_ID 0x36450000 +#define S5P64XX_CPU_MASK 0xFFFFF000 + +#define S5PC100_CPU_ID 0x43100000 +#define S5PC100_CPU_MASK 0xFFFFF000 + +#define S5PV210_CPU_ID 0x43110000 +#define S5PV210_CPU_MASK 0xFFFFF000 + +#define IS_SAMSUNG_CPU(name, id, mask) \ +static inline int is_samsung_##name(void) \ +{ \ + return ((samsung_cpu_id & mask) == (id & mask)); \ +} + +IS_SAMSUNG_CPU(s3c2410, S3C2410_CPU_ID, S3C2410_CPU_MASK) +IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK) +IS_SAMSUNG_CPU(s3c2412, S3C2412_CPU_ID, S3C2412_CPU_MASK) +IS_SAMSUNG_CPU(s3c6400, S3C6400_CPU_ID, S3C64XX_CPU_MASK) +IS_SAMSUNG_CPU(s3c6410, S3C6410_CPU_ID, S3C64XX_CPU_MASK) +IS_SAMSUNG_CPU(s5p6440, S5P6440_CPU_ID, S5P64XX_CPU_MASK) +IS_SAMSUNG_CPU(s5p6450, S5P6450_CPU_ID, S5P64XX_CPU_MASK) +IS_SAMSUNG_CPU(s5pc100, S5PC100_CPU_ID, S5PC100_CPU_MASK) +IS_SAMSUNG_CPU(s5pv210, S5PV210_CPU_ID, S5PV210_CPU_MASK) + +#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \ + defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2440) || \ + defined(CONFIG_CPU_S3C2442) || defined(CONFIG_CPU_S3C244X) || \ + defined(CONFIG_CPU_S3C2443) +# define soc_is_s3c24xx() is_samsung_s3c24xx() +# define soc_is_s3c2410() is_samsung_s3c2410() +#else +# define soc_is_s3c24xx() 0 +# define soc_is_s3c2410() 0 +#endif + +#if defined(CONFIG_CPU_S3C2412) +# define soc_is_s3c2412() is_samsung_s3c2412() +#else +# define soc_is_s3c2412() 0 +#endif + +#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) +# define soc_is_s3c6400() is_samsung_s3c6400() +# define soc_is_s3c6410() is_samsung_s3c6410() +# define soc_is_s3c64xx() (is_samsung_s3c6400() || is_samsung_s3c6410()) +#else +# define soc_is_s3c6400() 0 +# define soc_is_s3c6410() 0 +# define soc_is_s3c64xx() 0 +#endif + +#if defined(CONFIG_CPU_S5P6440) +# define soc_is_s5p6440() is_samsung_s5p6440() +#else +# define soc_is_s5p6440() 0 +#endif + +#if defined(CONFIG_CPU_S5P6450) +# define soc_is_s5p6450() is_samsung_s5p6450() +#else +# define soc_is_s5p6450() 0 +#endif + +#if defined(CONFIG_CPU_S5PC100) +# define soc_is_s5pc100() is_samsung_s5pc100() +#else +# define soc_is_s5pc100() 0 +#endif + +#if defined(CONFIG_CPU_S5PV210) +# define soc_is_s5pv210() is_samsung_s5pv210() +#else +# define soc_is_s5pv210() 0 +#endif + #define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE } +#ifndef KHZ +#define KHZ (1000) +#endif + #ifndef MHZ #define MHZ (1000*1000) #endif @@ -46,14 +145,14 @@ extern void s3c_init_cpu(unsigned long idcode, /* core initialisation functions */ -extern void s3c24xx_init_irq(void); -extern void s3c64xx_init_irq(u32 vic0, u32 vic1); extern void s5p_init_irq(u32 *vic, u32 num_vic); extern void s3c24xx_init_io(struct map_desc *mach_desc, int size); -extern void s3c64xx_init_io(struct map_desc *mach_desc, int size); -extern void s5p_init_io(struct map_desc *mach_desc, - int size, void __iomem *cpuid_addr); + +extern void s3c64xx_init_cpu(void); +extern void s5p_init_cpu(void __iomem *cpuid_addr); + +extern unsigned int samsung_rev(void); extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no); @@ -63,26 +162,23 @@ extern void s3c24xx_init_uartdevs(char *name, struct s3c24xx_uart_resources *res, struct s3c2410_uartcfg *cfg, int no); -/* timer for 2410/2440 */ - -struct sys_timer; -extern struct sys_timer s3c24xx_timer; - -/* system device classes */ - -extern struct sysdev_class s3c2410_sysclass; -extern struct sysdev_class s3c2410a_sysclass; -extern struct sysdev_class s3c2412_sysclass; -extern struct sysdev_class s3c2416_sysclass; -extern struct sysdev_class s3c2440_sysclass; -extern struct sysdev_class s3c2442_sysclass; -extern struct sysdev_class s3c2443_sysclass; -extern struct sysdev_class s3c6410_sysclass; -extern struct sysdev_class s3c64xx_sysclass; -extern struct sysdev_class s5p64x0_sysclass; -extern struct sysdev_class s5p6442_sysclass; -extern struct sysdev_class s5pv210_sysclass; -extern struct sysdev_class exynos4_sysclass; +extern struct syscore_ops s3c2410_pm_syscore_ops; +extern struct syscore_ops s3c2412_pm_syscore_ops; +extern struct syscore_ops s3c2416_pm_syscore_ops; +extern struct syscore_ops s3c244x_pm_syscore_ops; + +/* system device subsystems */ + +extern struct bus_type s3c2410_subsys; +extern struct bus_type s3c2410a_subsys; +extern struct bus_type s3c2412_subsys; +extern struct bus_type s3c2416_subsys; +extern struct bus_type s3c2440_subsys; +extern struct bus_type s3c2442_subsys; +extern struct bus_type s3c2443_subsys; +extern struct bus_type s3c6410_subsys; +extern struct bus_type s5p64x0_subsys; +extern struct bus_type s5pv210_subsys; extern void (*s5pc1xx_idle)(void); diff --git a/arch/arm/plat-samsung/include/plat/debug-macro.S b/arch/arm/plat-samsung/include/plat/debug-macro.S deleted file mode 100644 index dc6efd90e8f..00000000000 --- a/arch/arm/plat-samsung/include/plat/debug-macro.S +++ /dev/null @@ -1,87 +0,0 @@ -/* arch/arm/plat-samsung/include/plat/debug-macro.S - * - * Copyright 2005, 2007 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * 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 <plat/regs-serial.h> - -/* The S5PV210/S5PC110 and S5P6442 implementations are as belows. */ - - .macro fifo_level_s5pv210 rd, rx - ldr \rd, [ \rx, # S3C2410_UFSTAT ] - and \rd, \rd, #S5PV210_UFSTAT_TXMASK - .endm - - .macro fifo_full_s5pv210 rd, rx - ldr \rd, [ \rx, # S3C2410_UFSTAT ] - tst \rd, #S5PV210_UFSTAT_TXFULL - .endm - -/* The S3C2440 implementations are used by default as they are the - * most widely re-used */ - - .macro fifo_level_s3c2440 rd, rx - ldr \rd, [ \rx, # S3C2410_UFSTAT ] - and \rd, \rd, #S3C2440_UFSTAT_TXMASK - .endm - -#ifndef fifo_level -#define fifo_level fifo_level_s3c2440 -#endif - - .macro fifo_full_s3c2440 rd, rx - ldr \rd, [ \rx, # S3C2410_UFSTAT ] - tst \rd, #S3C2440_UFSTAT_TXFULL - .endm - -#ifndef fifo_full -#define fifo_full fifo_full_s3c2440 -#endif - - .macro senduart,rd,rx - strb \rd, [\rx, # S3C2410_UTXH ] - .endm - - .macro busyuart, rd, rx - ldr \rd, [ \rx, # S3C2410_UFCON ] - tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled? - beq 1001f @ - @ FIFO enabled... -1003: - fifo_full \rd, \rx - bne 1003b - b 1002f - -1001: - @ busy waiting for non fifo - ldr \rd, [ \rx, # S3C2410_UTRSTAT ] - tst \rd, #S3C2410_UTRSTAT_TXFE - beq 1001b - -1002: @ exit busyuart - .endm - - .macro waituart,rd,rx - ldr \rd, [ \rx, # S3C2410_UFCON ] - tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled? - beq 1001f @ - @ FIFO enabled... -1003: - fifo_level \rd, \rx - teq \rd, #0 - bne 1003b - b 1002f -1001: - @ idle waiting for non fifo - ldr \rd, [ \rx, # S3C2410_UTRSTAT ] - tst \rd, #S3C2410_UTRSTAT_TXFE - beq 1001b - -1002: @ exit busyuart - .endm diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index f0da6b70fba..eece188ed18 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -12,6 +12,10 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ + +#ifndef __PLAT_DEVS_H +#define __PLAT_DEVS_H __FILE__ + #include <linux/platform_device.h> struct s3c24xx_uart_resources { @@ -22,32 +26,31 @@ struct s3c24xx_uart_resources { extern struct s3c24xx_uart_resources s3c2410_uart_resources[]; extern struct s3c24xx_uart_resources s3c64xx_uart_resources[]; extern struct s3c24xx_uart_resources s5p_uart_resources[]; +extern struct s3c24xx_uart_resources exynos4_uart_resources[]; +extern struct s3c24xx_uart_resources exynos5_uart_resources[]; extern struct platform_device *s3c24xx_uart_devs[]; extern struct platform_device *s3c24xx_uart_src[]; -extern struct platform_device s3c_device_timer[]; - +extern struct platform_device s3c64xx_device_ac97; extern struct platform_device s3c64xx_device_iis0; extern struct platform_device s3c64xx_device_iis1; extern struct platform_device s3c64xx_device_iisv4; - -extern struct platform_device s3c64xx_device_spi0; -extern struct platform_device s3c64xx_device_spi1; - -extern struct platform_device samsung_asoc_dma; - +extern struct platform_device s3c64xx_device_onenand1; extern struct platform_device s3c64xx_device_pcm0; extern struct platform_device s3c64xx_device_pcm1; +extern struct platform_device s3c64xx_device_spi0; +extern struct platform_device s3c64xx_device_spi1; +extern struct platform_device s3c64xx_device_spi2; -extern struct platform_device s3c64xx_device_ac97; - -extern struct platform_device s3c_device_ts; - +extern struct platform_device s3c_device_adc; +extern struct platform_device s3c_device_cfcon; extern struct platform_device s3c_device_fb; -extern struct platform_device s3c_device_ohci; -extern struct platform_device s3c_device_lcd; -extern struct platform_device s3c_device_wdt; +extern struct platform_device s3c_device_hwmon; +extern struct platform_device s3c_device_hsmmc0; +extern struct platform_device s3c_device_hsmmc1; +extern struct platform_device s3c_device_hsmmc2; +extern struct platform_device s3c_device_hsmmc3; extern struct platform_device s3c_device_i2c0; extern struct platform_device s3c_device_i2c1; extern struct platform_device s3c_device_i2c2; @@ -56,93 +59,81 @@ extern struct platform_device s3c_device_i2c4; extern struct platform_device s3c_device_i2c5; extern struct platform_device s3c_device_i2c6; extern struct platform_device s3c_device_i2c7; +extern struct platform_device s3c_device_iis; +extern struct platform_device s3c_device_lcd; +extern struct platform_device s3c_device_nand; +extern struct platform_device s3c_device_ohci; +extern struct platform_device s3c_device_onenand; extern struct platform_device s3c_device_rtc; -extern struct platform_device s3c_device_adc; extern struct platform_device s3c_device_sdi; -extern struct platform_device s3c_device_iis; -extern struct platform_device s3c_device_hwmon; -extern struct platform_device s3c_device_hsmmc0; -extern struct platform_device s3c_device_hsmmc1; -extern struct platform_device s3c_device_hsmmc2; -extern struct platform_device s3c_device_hsmmc3; -extern struct platform_device s3c_device_cfcon; - extern struct platform_device s3c_device_spi0; extern struct platform_device s3c_device_spi1; - -extern struct platform_device s5pc100_device_spi0; -extern struct platform_device s5pc100_device_spi1; -extern struct platform_device s5pc100_device_spi2; -extern struct platform_device s5pv210_device_spi0; -extern struct platform_device s5pv210_device_spi1; -extern struct platform_device s5p6440_device_spi0; -extern struct platform_device s5p6440_device_spi1; -extern struct platform_device s5p6450_device_spi0; -extern struct platform_device s5p6450_device_spi1; - -extern struct platform_device s3c_device_hwmon; - -extern struct platform_device s3c_device_nand; -extern struct platform_device s3c_device_onenand; -extern struct platform_device s3c64xx_device_onenand1; -extern struct platform_device s5p_device_onenand; - +extern struct platform_device s3c_device_ts; +extern struct platform_device s3c_device_timer[]; extern struct platform_device s3c_device_usbgadget; extern struct platform_device s3c_device_usb_hsotg; +extern struct platform_device s3c_device_usb_hsudc; +extern struct platform_device s3c_device_wdt; -extern struct platform_device s5pv210_device_ac97; -extern struct platform_device s5pv210_device_pcm0; -extern struct platform_device s5pv210_device_pcm1; -extern struct platform_device s5pv210_device_pcm2; -extern struct platform_device s5pv210_device_iis0; -extern struct platform_device s5pv210_device_iis1; -extern struct platform_device s5pv210_device_iis2; -extern struct platform_device s5pv210_device_spdif; - -extern struct platform_device exynos4_device_ac97; -extern struct platform_device exynos4_device_pcm0; -extern struct platform_device exynos4_device_pcm1; -extern struct platform_device exynos4_device_pcm2; -extern struct platform_device exynos4_device_i2s0; -extern struct platform_device exynos4_device_i2s1; -extern struct platform_device exynos4_device_i2s2; -extern struct platform_device exynos4_device_spdif; -extern struct platform_device exynos4_device_pd[]; -extern struct platform_device exynos4_device_ahci; - -extern struct platform_device s5p6442_device_pcm0; -extern struct platform_device s5p6442_device_pcm1; -extern struct platform_device s5p6442_device_iis0; -extern struct platform_device s5p6442_device_iis1; -extern struct platform_device s5p6442_device_spi; +extern struct platform_device s5p_device_fimc0; +extern struct platform_device s5p_device_fimc1; +extern struct platform_device s5p_device_fimc2; +extern struct platform_device s5p_device_fimc3; +extern struct platform_device s5p_device_fimc_md; +extern struct platform_device s5p_device_jpeg; +extern struct platform_device s5p_device_g2d; +extern struct platform_device s5p_device_fimd0; +extern struct platform_device s5p_device_hdmi; +extern struct platform_device s5p_device_i2c_hdmiphy; +extern struct platform_device s5p_device_mfc; +extern struct platform_device s5p_device_mfc_l; +extern struct platform_device s5p_device_mfc_r; +extern struct platform_device s5p_device_mipi_csis0; +extern struct platform_device s5p_device_mipi_csis1; +extern struct platform_device s5p_device_mixer; +extern struct platform_device s5p_device_onenand; +extern struct platform_device s5p_device_sdo; -extern struct platform_device s5p6440_device_pcm; extern struct platform_device s5p6440_device_iis; +extern struct platform_device s5p6440_device_pcm; extern struct platform_device s5p6450_device_iis0; extern struct platform_device s5p6450_device_iis1; extern struct platform_device s5p6450_device_iis2; extern struct platform_device s5p6450_device_pcm0; + extern struct platform_device s5pc100_device_ac97; -extern struct platform_device s5pc100_device_pcm0; -extern struct platform_device s5pc100_device_pcm1; extern struct platform_device s5pc100_device_iis0; extern struct platform_device s5pc100_device_iis1; extern struct platform_device s5pc100_device_iis2; +extern struct platform_device s5pc100_device_pcm0; +extern struct platform_device s5pc100_device_pcm1; extern struct platform_device s5pc100_device_spdif; -extern struct platform_device samsung_device_keypad; - -extern struct platform_device s5p_device_fimc0; -extern struct platform_device s5p_device_fimc1; -extern struct platform_device s5p_device_fimc2; -extern struct platform_device s5p_device_fimc3; +extern struct platform_device s5pv210_device_ac97; +extern struct platform_device s5pv210_device_iis0; +extern struct platform_device s5pv210_device_iis1; +extern struct platform_device s5pv210_device_iis2; +extern struct platform_device s5pv210_device_pcm0; +extern struct platform_device s5pv210_device_pcm1; +extern struct platform_device s5pv210_device_pcm2; +extern struct platform_device s5pv210_device_spdif; -extern struct platform_device s5p_device_mipi_csis0; -extern struct platform_device s5p_device_mipi_csis1; +extern struct platform_device exynos4_device_ac97; +extern struct platform_device exynos4_device_ahci; +extern struct platform_device exynos4_device_i2s0; +extern struct platform_device exynos4_device_i2s1; +extern struct platform_device exynos4_device_i2s2; +extern struct platform_device exynos4_device_ohci; +extern struct platform_device exynos4_device_pcm0; +extern struct platform_device exynos4_device_pcm1; +extern struct platform_device exynos4_device_pcm2; +extern struct platform_device exynos4_device_spdif; -extern struct platform_device exynos4_device_sysmmu; +extern struct platform_device samsung_asoc_idma; +extern struct platform_device samsung_device_keypad; +extern struct platform_device samsung_device_pwm; /* s3c2440 specific devices */ @@ -164,3 +155,5 @@ extern struct platform_device s3c_device_ac97; */ extern void *s3c_set_platdata(void *pd, size_t pdsize, struct platform_device *pdev); + +#endif /* __PLAT_DEVS_H */ diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h new file mode 100644 index 00000000000..ce6d7634b6c --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/dma-ops.h @@ -0,0 +1,69 @@ +/* arch/arm/plat-samsung/include/plat/dma-ops.h + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Samsung DMA 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. + */ + +#ifndef __SAMSUNG_DMA_OPS_H_ +#define __SAMSUNG_DMA_OPS_H_ __FILE__ + +#include <linux/dmaengine.h> +#include <mach/dma.h> + +struct samsung_dma_req { + enum dma_transaction_type cap; + struct s3c2410_dma_client *client; +}; + +struct samsung_dma_prep { + enum dma_transaction_type cap; + enum dma_transfer_direction direction; + dma_addr_t buf; + unsigned long period; + unsigned long len; + void (*fp)(void *data); + void *fp_param; +}; + +struct samsung_dma_config { + enum dma_transfer_direction direction; + enum dma_slave_buswidth width; + dma_addr_t fifo; +}; + +struct samsung_dma_ops { + unsigned (*request)(enum dma_ch ch, struct samsung_dma_req *param, + struct device *dev, char *ch_name); + int (*release)(unsigned ch, void *param); + int (*config)(unsigned ch, struct samsung_dma_config *param); + int (*prepare)(unsigned ch, struct samsung_dma_prep *param); + int (*trigger)(unsigned ch); + int (*started)(unsigned ch); + int (*flush)(unsigned ch); + int (*stop)(unsigned ch); +}; + +extern void *samsung_dmadev_get_ops(void); +extern void *s3c_dma_get_ops(void); + +static inline void *__samsung_dma_get_ops(void) +{ + if (samsung_dma_is_dmadev()) + return samsung_dmadev_get_ops(); + else + return s3c_dma_get_ops(); +} + +/* + * samsung_dma_get_ops + * get the set of samsung dma operations + */ +#define samsung_dma_get_ops() __samsung_dma_get_ops() + +#endif /* __SAMSUNG_DMA_OPS_H_ */ diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h index 81074421312..abe07fae71d 100644 --- a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h +++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h @@ -8,11 +8,8 @@ * (at your option) any later version. */ -#ifndef __S3C_DMA_PL330_H_ -#define __S3C_DMA_PL330_H_ - -#define S3C2410_DMAF_AUTOSTART (1 << 0) -#define S3C2410_DMAF_CIRCULAR (1 << 1) +#ifndef __DMA_PL330_H_ +#define __DMA_PL330_H_ __FILE__ /* * PL330 can assign any channel to communicate with @@ -20,11 +17,11 @@ * For the sake of consistency across client drivers, * We keep the channel names unchanged and only add * missing peripherals are added. - * Order is not important since S3C PL330 API driver + * Order is not important since DMA PL330 API driver * use these just as IDs. */ enum dma_ch { - DMACH_UART0_RX, + DMACH_UART0_RX = 0, DMACH_UART0_TX, DMACH_UART1_RX, DMACH_UART1_TX, @@ -84,15 +81,41 @@ enum dma_ch { DMACH_SLIMBUS4_TX, DMACH_SLIMBUS5_RX, DMACH_SLIMBUS5_TX, + DMACH_MIPI_HSI0, + DMACH_MIPI_HSI1, + DMACH_MIPI_HSI2, + DMACH_MIPI_HSI3, + DMACH_MIPI_HSI4, + DMACH_MIPI_HSI5, + DMACH_MIPI_HSI6, + DMACH_MIPI_HSI7, + DMACH_DISP1, + DMACH_MTOM_0, + DMACH_MTOM_1, + DMACH_MTOM_2, + DMACH_MTOM_3, + DMACH_MTOM_4, + DMACH_MTOM_5, + DMACH_MTOM_6, + DMACH_MTOM_7, /* END Marker, also used to denote a reserved channel */ DMACH_MAX, }; -static inline bool s3c_dma_has_circular(void) +struct s3c2410_dma_client { + char *name; +}; + +static inline bool samsung_dma_has_circular(void) +{ + return true; +} + +static inline bool samsung_dma_is_dmadev(void) { return true; } -#include <plat/dma.h> +#include <plat/dma-ops.h> -#endif /* __S3C_DMA_PL330_H_ */ +#endif /* __DMA_PL330_H_ */ diff --git a/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h b/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h index 336d5ac0203..bd3a6db14cb 100644 --- a/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h +++ b/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h @@ -12,17 +12,12 @@ #include <plat/dma-core.h> -extern struct sysdev_class dma_sysclass; +extern struct bus_type dma_subsys; extern struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS]; #define DMA_CH_VALID (1<<31) #define DMA_CH_NEVER (1<<30) -struct s3c24xx_dma_addr { - unsigned long from; - unsigned long to; -}; - /* struct s3c24xx_dma_map * * this holds the mapping information for the channel selected @@ -31,10 +26,8 @@ struct s3c24xx_dma_addr { struct s3c24xx_dma_map { const char *name; - struct s3c24xx_dma_addr hw_addr; unsigned long channels[S3C_DMA_CHANNELS]; - unsigned long channels_rx[S3C_DMA_CHANNELS]; }; struct s3c24xx_dma_selection { @@ -44,10 +37,6 @@ struct s3c24xx_dma_selection { void (*select)(struct s3c2410_dma_chan *chan, struct s3c24xx_dma_map *map); - - void (*direction)(struct s3c2410_dma_chan *chan, - struct s3c24xx_dma_map *map, - enum s3c2410_dmasrc dir); }; extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel); diff --git a/arch/arm/plat-samsung/include/plat/dma.h b/arch/arm/plat-samsung/include/plat/dma.h index 2e8f8c6560d..7b02143ccd9 100644 --- a/arch/arm/plat-samsung/include/plat/dma.h +++ b/arch/arm/plat-samsung/include/plat/dma.h @@ -10,17 +10,17 @@ * published by the Free Software Foundation. */ +#ifndef __PLAT_DMA_H +#define __PLAT_DMA_H + +#include <linux/dma-mapping.h> + enum s3c2410_dma_buffresult { S3C2410_RES_OK, S3C2410_RES_ERR, S3C2410_RES_ABORT }; -enum s3c2410_dmasrc { - S3C2410_DMASRC_HW, /* source is memory */ - S3C2410_DMASRC_MEM /* source is hardware */ -}; - /* enum s3c2410_chan_op * * operation codes passed to the DMA code by the user, and also used @@ -42,6 +42,7 @@ struct s3c2410_dma_client { }; struct s3c2410_dma_chan; +enum dma_ch; /* s3c2410_dma_cbfn_t * @@ -62,7 +63,7 @@ typedef int (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *, * request a dma channel exclusivley */ -extern int s3c2410_dma_request(unsigned int channel, +extern int s3c2410_dma_request(enum dma_ch channel, struct s3c2410_dma_client *, void *dev); @@ -71,14 +72,14 @@ extern int s3c2410_dma_request(unsigned int channel, * change the state of the dma channel */ -extern int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op); +extern int s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op); /* s3c2410_dma_setflags * * set the channel's flags to a given state */ -extern int s3c2410_dma_setflags(unsigned int channel, +extern int s3c2410_dma_setflags(enum dma_ch channel, unsigned int flags); /* s3c2410_dma_free @@ -86,7 +87,7 @@ extern int s3c2410_dma_setflags(unsigned int channel, * free the dma channel (will also abort any outstanding operations) */ -extern int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *); +extern int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *); /* s3c2410_dma_enqueue * @@ -95,7 +96,7 @@ extern int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *); * drained before the buffer is given to the DMA system. */ -extern int s3c2410_dma_enqueue(unsigned int channel, void *id, +extern int s3c2410_dma_enqueue(enum dma_ch channel, void *id, dma_addr_t data, int size); /* s3c2410_dma_config @@ -103,25 +104,27 @@ extern int s3c2410_dma_enqueue(unsigned int channel, void *id, * configure the dma channel */ -extern int s3c2410_dma_config(unsigned int channel, int xferunit); +extern int s3c2410_dma_config(enum dma_ch channel, int xferunit); /* s3c2410_dma_devconfig * * configure the device we're talking to */ -extern int s3c2410_dma_devconfig(unsigned int channel, - enum s3c2410_dmasrc source, unsigned long devaddr); +extern int s3c2410_dma_devconfig(enum dma_ch channel, + enum dma_data_direction source, unsigned long devaddr); /* s3c2410_dma_getposition * * get the position that the dma transfer is currently at */ -extern int s3c2410_dma_getposition(unsigned int channel, +extern int s3c2410_dma_getposition(enum dma_ch channel, dma_addr_t *src, dma_addr_t *dest); -extern int s3c2410_dma_set_opfn(unsigned int, s3c2410_dma_opfn_t rtn); -extern int s3c2410_dma_set_buffdone_fn(unsigned int, s3c2410_dma_cbfn_t rtn); +extern int s3c2410_dma_set_opfn(enum dma_ch, s3c2410_dma_opfn_t rtn); +extern int s3c2410_dma_set_buffdone_fn(enum dma_ch, s3c2410_dma_cbfn_t rtn); +#include <plat/dma-ops.h> +#endif diff --git a/arch/arm/plat-samsung/include/plat/fb-core.h b/arch/arm/plat-samsung/include/plat/fb-core.h index bca383efcf6..6abcbf139ce 100644 --- a/arch/arm/plat-samsung/include/plat/fb-core.h +++ b/arch/arm/plat-samsung/include/plat/fb-core.h @@ -26,4 +26,19 @@ static inline void s3c_fb_setname(char *name) #endif } +/* Re-define device name depending on support. */ +static inline void s5p_fb_setname(int id, char *name) +{ + switch (id) { +#ifdef CONFIG_S5P_DEV_FIMD0 + case 0: + s5p_device_fimd0.name = name; + break; +#endif + default: + printk(KERN_ERR "%s: invalid device id(%d)\n", __func__, id); + break; + } +} + #endif /* __ASM_PLAT_FB_CORE_H */ diff --git a/arch/arm/plat-samsung/include/plat/fb-s3c2410.h b/arch/arm/plat-samsung/include/plat/fb-s3c2410.h new file mode 100644 index 00000000000..4e5d9588b5b --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/fb-s3c2410.h @@ -0,0 +1,72 @@ +/* arch/arm/plat-samsung/include/plat/fb-s3c2410.h + * + * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org> + * + * Inspired by pxafb.h + * + * 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_PLAT_FB_S3C2410_H +#define __ASM_PLAT_FB_S3C2410_H __FILE__ + +struct s3c2410fb_hw { + unsigned long lcdcon1; + unsigned long lcdcon2; + unsigned long lcdcon3; + unsigned long lcdcon4; + unsigned long lcdcon5; +}; + +/* LCD description */ +struct s3c2410fb_display { + /* LCD type */ + unsigned type; + + /* Screen size */ + unsigned short width; + unsigned short height; + + /* Screen info */ + unsigned short xres; + unsigned short yres; + unsigned short bpp; + + unsigned pixclock; /* pixclock in picoseconds */ + unsigned short left_margin; /* value in pixels (TFT) or HCLKs (STN) */ + unsigned short right_margin; /* value in pixels (TFT) or HCLKs (STN) */ + unsigned short hsync_len; /* value in pixels (TFT) or HCLKs (STN) */ + unsigned short upper_margin; /* value in lines (TFT) or 0 (STN) */ + unsigned short lower_margin; /* value in lines (TFT) or 0 (STN) */ + unsigned short vsync_len; /* value in lines (TFT) or 0 (STN) */ + + /* lcd configuration registers */ + unsigned long lcdcon5; +}; + +struct s3c2410fb_mach_info { + + struct s3c2410fb_display *displays; /* attached diplays info */ + unsigned num_displays; /* number of defined displays */ + unsigned default_display; + + /* GPIOs */ + + unsigned long gpcup; + unsigned long gpcup_mask; + unsigned long gpccon; + unsigned long gpccon_mask; + unsigned long gpdup; + unsigned long gpdup_mask; + unsigned long gpdcon; + unsigned long gpdcon_mask; + + /* lpc3600 control register */ + unsigned long lpcsel; +}; + +extern void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *); + +#endif /* __ASM_PLAT_FB_S3C2410_H */ diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h index cb3ca3adc68..9ae50727078 100644 --- a/arch/arm/plat-samsung/include/plat/fb.h +++ b/arch/arm/plat-samsung/include/plat/fb.h @@ -15,63 +15,23 @@ #ifndef __PLAT_S3C_FB_H #define __PLAT_S3C_FB_H __FILE__ -/* S3C_FB_MAX_WIN - * Set to the maximum number of windows that any of the supported hardware - * can use. Since the platform data uses this for an array size, having it - * set to the maximum of any version of the hardware can do is safe. - */ -#define S3C_FB_MAX_WIN (5) +#include <linux/platform_data/video_s3c.h> /** - * struct s3c_fb_pd_win - per window setup data - * @win_mode: The display parameters to initialise (not for window 0) - * @virtual_x: The virtual X size. - * @virtual_y: The virtual Y size. - */ -struct s3c_fb_pd_win { - struct fb_videomode win_mode; - - unsigned short default_bpp; - unsigned short max_bpp; - unsigned short virtual_x; - unsigned short virtual_y; -}; - -/** - * struct s3c_fb_platdata - S3C driver platform specific information - * @setup_gpio: Setup the external GPIO pins to the right state to transfer - * the data from the display system to the connected display - * device. - * @default_win: default window layer number to be used for UI layer. - * @vidcon0: The base vidcon0 values to control the panel data format. - * @vidcon1: The base vidcon1 values to control the panel data output. - * @win: The setup data for each hardware window, or NULL for unused. - * @display_mode: The LCD output display mode. - * - * The platform data supplies the video driver with all the information - * it requires to work with the display(s) attached to the machine. It - * controls the initial mode, the number of display windows (0 is always - * the base framebuffer) that are initialised etc. - * + * s3c_fb_set_platdata() - Setup the FB device with platform data. + * @pd: The platform data to set. The data is copied from the passed structure + * so the machine data can mark the data __initdata so that any unused + * machines will end up dumping their data at runtime. */ -struct s3c_fb_platdata { - void (*setup_gpio)(void); - - struct s3c_fb_pd_win *win[S3C_FB_MAX_WIN]; - - u32 default_win; - - u32 vidcon0; - u32 vidcon1; -}; +extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd); /** - * s3c_fb_set_platdata() - Setup the FB device with platform data. + * s5p_fimd0_set_platdata() - Setup the FB device with platform data. * @pd: The platform data to set. The data is copied from the passed structure * so the machine data can mark the data __initdata so that any unused * machines will end up dumping their data at runtime. */ -extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd); +extern void s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd); /** * s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD @@ -94,4 +54,18 @@ extern void s5pc100_fb_gpio_setup_24bpp(void); */ extern void s5pv210_fb_gpio_setup_24bpp(void); +/** + * exynos4_fimd0_gpio_setup_24bpp() - Exynos4 setup function for 24bpp LCD0 + * + * Initialise the GPIO for an 24bpp LCD display on the RGB interface 0. + */ +extern void exynos4_fimd0_gpio_setup_24bpp(void); + +/** + * s5p64x0_fb_gpio_setup_24bpp() - S5P6440/S5P6450 setup function for 24bpp LCD + * + * Initialise the GPIO for an 24bpp LCD display on the RGB interface. + */ +extern void s5p64x0_fb_gpio_setup_24bpp(void); + #endif /* __PLAT_S3C_FB_H */ diff --git a/arch/arm/plat-samsung/include/plat/fimc-core.h b/arch/arm/plat-samsung/include/plat/fimc-core.h index 945a99d5956..1d6cb2b8b09 100644 --- a/arch/arm/plat-samsung/include/plat/fimc-core.h +++ b/arch/arm/plat-samsung/include/plat/fimc-core.h @@ -43,6 +43,8 @@ static inline void s3c_fimc_setname(int id, char *name) s5p_device_fimc3.name = name; break; #endif + default: + break; } } diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h index 5603db0b79b..a181d7ce81c 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h @@ -1,11 +1,11 @@ -/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg-helper.h +/* linux/arch/arm/plat-samsung/include/plat/gpio-cfg-helper.h * * Copyright 2008 Openmoko, Inc. * Copyright 2008 Simtec Electronics * http://armlinux.simtec.co.uk/ * Ben Dooks <ben@simtec.co.uk> * - * S3C Platform - GPIO pin configuration helper definitions + * Samsung Platform - GPIO pin configuration helper 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 @@ -24,130 +24,40 @@ * by disabling interrupts. */ -static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip, - unsigned int off, unsigned int config) +static inline int samsung_gpio_do_setcfg(struct samsung_gpio_chip *chip, + unsigned int off, unsigned int config) { return (chip->config->set_config)(chip, off, config); } -static inline unsigned s3c_gpio_do_getcfg(struct s3c_gpio_chip *chip, - unsigned int off) +static inline unsigned samsung_gpio_do_getcfg(struct samsung_gpio_chip *chip, + unsigned int off) { return (chip->config->get_config)(chip, off); } -static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip, - unsigned int off, s3c_gpio_pull_t pull) +static inline int samsung_gpio_do_setpull(struct samsung_gpio_chip *chip, + unsigned int off, samsung_gpio_pull_t pull) { return (chip->config->set_pull)(chip, off, pull); } -static inline s3c_gpio_pull_t s3c_gpio_do_getpull(struct s3c_gpio_chip *chip, - unsigned int off) +static inline samsung_gpio_pull_t samsung_gpio_do_getpull(struct samsung_gpio_chip *chip, + unsigned int off) { return chip->config->get_pull(chip, off); } -/** - * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration. - * @chip: The gpio chip that is being configured. - * @off: The offset for the GPIO being configured. - * @cfg: The configuration value to set. - * - * This helper deal with the GPIO cases where the control register - * has two bits of configuration per gpio, which have the following - * functions: - * 00 = input - * 01 = output - * 1x = special function -*/ -extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, - unsigned int off, unsigned int cfg); - -/** - * s3c_gpio_getcfg_s3c24xx - S3C24XX style GPIO configuration read. - * @chip: The gpio chip that is being configured. - * @off: The offset for the GPIO being configured. - * - * The reverse of s3c_gpio_setcfg_s3c24xx(). Will return a value whicg - * could be directly passed back to s3c_gpio_setcfg_s3c24xx(), from the - * S3C_GPIO_SPECIAL() macro. - */ -unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip, - unsigned int off); - -/** - * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A) - * @chip: The gpio chip that is being configured. - * @off: The offset for the GPIO being configured. - * @cfg: The configuration value to set. - * - * This helper deal with the GPIO cases where the control register - * has one bit of configuration for the gpio, where setting the bit - * means the pin is in special function mode and unset means output. -*/ -extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, - unsigned int off, unsigned int cfg); - - -/** - * s3c_gpio_getcfg_s3c24xx_a - S3C24XX style GPIO configuration read (Bank A) - * @chip: The gpio chip that is being configured. - * @off: The offset for the GPIO being configured. - * - * The reverse of s3c_gpio_setcfg_s3c24xx_a() turning an GPIO into a usable - * GPIO configuration value. - * - * @sa s3c_gpio_getcfg_s3c24xx - * @sa s3c_gpio_getcfg_s3c64xx_4bit - */ -extern unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip, - unsigned int off); - -/** - * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config. - * @chip: The gpio chip that is being configured. - * @off: The offset for the GPIO being configured. - * @cfg: The configuration value to set. - * - * This helper deal with the GPIO cases where the control register has 4 bits - * of control per GPIO, generally in the form of: - * 0000 = Input - * 0001 = Output - * others = Special functions (dependant on bank) - * - * Note, since the code to deal with the case where there are two control - * registers instead of one, we do not have a separate set of functions for - * each case. -*/ -extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, - unsigned int off, unsigned int cfg); - - -/** - * s3c_gpio_getcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config read. - * @chip: The gpio chip that is being configured. - * @off: The offset for the GPIO being configured. - * - * The reverse of s3c_gpio_setcfg_s3c64xx_4bit(), turning a gpio configuration - * register setting into a value the software can use, such as could be passed - * to s3c_gpio_setcfg_s3c64xx_4bit(). - * - * @sa s3c_gpio_getcfg_s3c24xx - */ -extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, - unsigned int off); - /* Pull-{up,down} resistor controls. * - * S3C2410,S3C2440,S3C24A0 = Pull-UP, + * S3C2410,S3C2440 = Pull-UP, * S3C2412,S3C2413 = Pull-Down * S3C6400,S3C6410 = Pull-Both [None,Down,Up,Undef] * S3C2443 = Pull-Both [not same as S3C6400] */ /** - * s3c_gpio_setpull_1up() - Pull configuration for choice of up or none. + * s3c24xx_gpio_setpull_1up() - Pull configuration for choice of up or none. * @chip: The gpio chip that is being configured. * @off: The offset for the GPIO being configured. * @param: pull: The pull mode being requested. @@ -155,11 +65,11 @@ extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, * This is a helper function for the case where we have GPIOs with one * bit configuring the presence of a pull-up resistor. */ -extern int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, - unsigned int off, s3c_gpio_pull_t pull); +extern int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip, + unsigned int off, samsung_gpio_pull_t pull); /** - * s3c_gpio_setpull_1down() - Pull configuration for choice of down or none + * s3c24xx_gpio_setpull_1down() - Pull configuration for choice of down or none * @chip: The gpio chip that is being configured * @off: The offset for the GPIO being configured * @param: pull: The pull mode being requested @@ -167,11 +77,13 @@ extern int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, * This is a helper function for the case where we have GPIOs with one * bit configuring the presence of a pull-down resistor. */ -extern int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip, - unsigned int off, s3c_gpio_pull_t pull); +extern int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip, + unsigned int off, samsung_gpio_pull_t pull); /** - * s3c_gpio_setpull_upown() - Pull configuration for choice of up, down or none + * samsung_gpio_setpull_upown() - Pull configuration for choice of up, + * down or none + * * @chip: The gpio chip that is being configured. * @off: The offset for the GPIO being configured. * @param: pull: The pull mode being requested. @@ -183,45 +95,46 @@ extern int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip, * 01 = Pull-up resistor connected * 10 = Pull-down resistor connected */ -extern int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip, - unsigned int off, s3c_gpio_pull_t pull); - +extern int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip, + unsigned int off, samsung_gpio_pull_t pull); /** - * s3c_gpio_getpull_updown() - Get configuration for choice of up, down or none + * samsung_gpio_getpull_updown() - Get configuration for choice of up, + * down or none + * * @chip: The gpio chip that the GPIO pin belongs to * @off: The offset to the pin to get the configuration of. * - * This helper function reads the state of the pull-{up,down} resistor for the - * given GPIO in the same case as s3c_gpio_setpull_upown. + * This helper function reads the state of the pull-{up,down} resistor + * for the given GPIO in the same case as samsung_gpio_setpull_upown. */ -extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip, - unsigned int off); +extern samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip, + unsigned int off); /** - * s3c_gpio_getpull_1up() - Get configuration for choice of up or none + * s3c24xx_gpio_getpull_1up() - Get configuration for choice of up or none * @chip: The gpio chip that the GPIO pin belongs to * @off: The offset to the pin to get the configuration of. * * This helper function reads the state of the pull-up resistor for the - * given GPIO in the same case as s3c_gpio_setpull_1up. + * given GPIO in the same case as s3c24xx_gpio_setpull_1up. */ -extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, - unsigned int off); +extern samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip, + unsigned int off); /** - * s3c_gpio_getpull_1down() - Get configuration for choice of down or none + * s3c24xx_gpio_getpull_1down() - Get configuration for choice of down or none * @chip: The gpio chip that the GPIO pin belongs to * @off: The offset to the pin to get the configuration of. * * This helper function reads the state of the pull-down resistor for the - * given GPIO in the same case as s3c_gpio_setpull_1down. + * given GPIO in the same case as s3c24xx_gpio_setpull_1down. */ -extern s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip, - unsigned int off); +extern samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip, + unsigned int off); /** - * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443. + * s3c2443_gpio_setpull() - Pull configuration for s3c2443. * @chip: The gpio chip that is being configured. * @off: The offset for the GPIO being configured. * @param: pull: The pull mode being requested. @@ -233,19 +146,18 @@ extern s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip, * 10 = Pull-down resistor connected * x1 = No pull up resistor */ -extern int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip, - unsigned int off, s3c_gpio_pull_t pull); +extern int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip, + unsigned int off, samsung_gpio_pull_t pull); /** - * s3c_gpio_getpull_s3c2443() - Get configuration for s3c2443 pull resistors + * s3c2443_gpio_getpull() - Get configuration for s3c2443 pull resistors * @chip: The gpio chip that the GPIO pin belongs to. * @off: The offset to the pin to get the configuration of. * * This helper function reads the state of the pull-{up,down} resistor for the - * given GPIO in the same case as s3c_gpio_setpull_upown. + * given GPIO in the same case as samsung_gpio_setpull_upown. */ -extern s3c_gpio_pull_t s3c_gpio_getpull_s3c2443(struct s3c_gpio_chip *chip, +extern samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip, unsigned int off); #endif /* __PLAT_GPIO_CFG_HELPERS_H */ - diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h index 5e04fa6eda7..08740eed050 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h @@ -24,14 +24,16 @@ #ifndef __PLAT_GPIO_CFG_H #define __PLAT_GPIO_CFG_H __FILE__ -typedef unsigned int __bitwise__ s3c_gpio_pull_t; +#include <linux/types.h> + +typedef unsigned int __bitwise__ samsung_gpio_pull_t; typedef unsigned int __bitwise__ s5p_gpio_drvstr_t; /* forward declaration if gpio-core.h hasn't been included */ -struct s3c_gpio_chip; +struct samsung_gpio_chip; /** - * struct s3c_gpio_cfg GPIO configuration + * struct samsung_gpio_cfg GPIO configuration * @cfg_eint: Configuration setting when used for external interrupt source * @get_pull: Read the current pull configuration for the GPIO * @set_pull: Set the current pull configuraiton for the GPIO @@ -44,20 +46,20 @@ struct s3c_gpio_chip; * per-bank configuration information that other systems such as the * external interrupt code will need. * - * @sa s3c_gpio_cfgpin + * @sa samsung_gpio_cfgpin * @sa s3c_gpio_getcfg * @sa s3c_gpio_setpull * @sa s3c_gpio_getpull */ -struct s3c_gpio_cfg { +struct samsung_gpio_cfg { unsigned int cfg_eint; - s3c_gpio_pull_t (*get_pull)(struct s3c_gpio_chip *chip, unsigned offs); - int (*set_pull)(struct s3c_gpio_chip *chip, unsigned offs, - s3c_gpio_pull_t pull); + samsung_gpio_pull_t (*get_pull)(struct samsung_gpio_chip *chip, unsigned offs); + int (*set_pull)(struct samsung_gpio_chip *chip, unsigned offs, + samsung_gpio_pull_t pull); - unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs); - int (*set_config)(struct s3c_gpio_chip *chip, unsigned offs, + unsigned (*get_config)(struct samsung_gpio_chip *chip, unsigned offs); + int (*set_config)(struct samsung_gpio_chip *chip, unsigned offs, unsigned config); }; @@ -69,7 +71,7 @@ struct s3c_gpio_cfg { #define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1)) #define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x)) -#define s3c_gpio_is_cfg_special(_cfg) \ +#define samsung_gpio_is_cfg_special(_cfg) \ (((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK) /** @@ -125,12 +127,12 @@ extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr, * * These values control the state of the weak pull-{up,down} resistors * available on most pins on the S3C series. Not all chips support both - * up or down settings, and it may be dependant on the chip that is being + * up or down settings, and it may be dependent on the chip that is being * used to whether the particular mode is available. */ -#define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00) -#define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01) -#define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x02) +#define S3C_GPIO_PULL_NONE ((__force samsung_gpio_pull_t)0x00) +#define S3C_GPIO_PULL_DOWN ((__force samsung_gpio_pull_t)0x01) +#define S3C_GPIO_PULL_UP ((__force samsung_gpio_pull_t)0x02) /** * s3c_gpio_setpull() - set the state of a gpio pin pull resistor @@ -138,12 +140,12 @@ extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr, * @pull: The configuration for the pull resistor. * * This function sets the state of the pull-{up,down} resistor for the - * specified pin. It will return 0 if successfull, or a negative error + * specified pin. It will return 0 if successful, or a negative error * code if the pin cannot support the requested pull setting. * * @pull is one of S3C_GPIO_PULL_NONE, S3C_GPIO_PULL_DOWN or S3C_GPIO_PULL_UP. */ -extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull); +extern int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull); /** * s3c_gpio_getpull() - get the pull resistor state of a gpio pin @@ -151,7 +153,7 @@ extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull); * * Read the pull resistor value for the specified pin. */ -extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin); +extern samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin); /* configure `all` aspects of an gpio */ @@ -170,7 +172,7 @@ extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin); * @sa s3c_gpio_cfgpin_range */ extern int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr, - unsigned int cfg, s3c_gpio_pull_t pull); + unsigned int cfg, samsung_gpio_pull_t pull); static inline int s3c_gpio_cfgrange_nopull(unsigned int pin, unsigned int size, unsigned int cfg) @@ -202,7 +204,7 @@ extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin); * @drvstr: The new value of the driver strength * * This function sets the driver strength value for the specified pin. - * It will return 0 if successfull, or a negative error code if the pin + * It will return 0 if successful, or a negative error code if the pin * cannot support the requested setting. */ extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr); diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h index dac35d0a711..cf5aae5b097 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-core.h +++ b/arch/arm/plat-samsung/include/plat/gpio-core.h @@ -11,6 +11,9 @@ * published by the Free Software Foundation. */ +#ifndef __PLAT_SAMSUNG_GPIO_CORE_H +#define __PLAT_SAMSUNG_GPIO_CORE_H + #define GPIOCON_OFF (0x00) #define GPIODAT_OFF (0x04) @@ -25,22 +28,22 @@ * specific code. */ -struct s3c_gpio_chip; +struct samsung_gpio_chip; /** - * struct s3c_gpio_pm - power management (suspend/resume) information + * struct samsung_gpio_pm - power management (suspend/resume) information * @save: Routine to save the state of the GPIO block * @resume: Routine to resume the GPIO block. */ -struct s3c_gpio_pm { - void (*save)(struct s3c_gpio_chip *chip); - void (*resume)(struct s3c_gpio_chip *chip); +struct samsung_gpio_pm { + void (*save)(struct samsung_gpio_chip *chip); + void (*resume)(struct samsung_gpio_chip *chip); }; -struct s3c_gpio_cfg; +struct samsung_gpio_cfg; /** - * struct s3c_gpio_chip - wrapper for specific implementation of gpio + * struct samsung_gpio_chip - wrapper for specific implementation of gpio * @chip: The chip structure to be exported via gpiolib. * @base: The base pointer to the gpio configuration registers. * @group: The group register number for gpio interrupt support. @@ -48,6 +51,7 @@ struct s3c_gpio_cfg; * @config: special function and pull-resistor control information. * @lock: Lock for exclusive access to this gpio bank. * @pm_save: Save information for suspend/resume support. + * @bitmap_gpio_int: Bitmap for representing GPIO interrupt or not. * * This wrapper provides the necessary information for the Samsung * specific gpios being registered with gpiolib. @@ -60,10 +64,10 @@ struct s3c_gpio_cfg; * CPU cores trying to get one lock for different GPIO banks, where each * bank of GPIO has its own register space and configuration registers. */ -struct s3c_gpio_chip { +struct samsung_gpio_chip { struct gpio_chip chip; - struct s3c_gpio_cfg *config; - struct s3c_gpio_pm *pm; + struct samsung_gpio_cfg *config; + struct samsung_gpio_pm *pm; void __iomem *base; int irq_base; int group; @@ -71,60 +75,14 @@ struct s3c_gpio_chip { #ifdef CONFIG_PM u32 pm_save[4]; #endif + u32 bitmap_gpio_int; }; -static inline struct s3c_gpio_chip *to_s3c_gpio(struct gpio_chip *gpc) +static inline struct samsung_gpio_chip *to_samsung_gpio(struct gpio_chip *gpc) { - return container_of(gpc, struct s3c_gpio_chip, chip); + return container_of(gpc, struct samsung_gpio_chip, chip); } -/** s3c_gpiolib_add() - add the s3c specific version of a gpio_chip. - * @chip: The chip to register - * - * This is a wrapper to gpiochip_add() that takes our specific gpio chip - * information and makes the necessary alterations for the platform and - * notes the information for use with the configuration systems and any - * other parts of the system. - */ -extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip); - -/* CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios - * for use with the configuration calls, and other parts of the s3c gpiolib - * support code. - * - * Not all s3c support code will need this, as some configurations of cpu - * may only support one or two different configuration options and have an - * easy gpio to s3c_gpio_chip mapping function. If this is the case, then - * the machine support file should provide its own s3c_gpiolib_getchip() - * and any other necessary functions. - */ - -/** - * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config. - * @chip: The gpio chip that is being configured. - * @nr_chips: The no of chips (gpio ports) for the GPIO being configured. - * - * This helper deal with the GPIO cases where the control register has 4 bits - * of control per GPIO, generally in the form of: - * 0000 = Input - * 0001 = Output - * others = Special functions (dependant on bank) - * - * Note, since the code to deal with the case where there are two control - * registers instead of one, we do not have a separate set of function - * (samsung_gpiolib_add_4bit2_chips)for each case. - */ -extern void samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip, - int nr_chips); -extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip, - int nr_chips); -extern void samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip, - int nr_chips); - -extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip); -extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip); - - /** * samsung_gpiolib_to_irq - convert gpio pin to irq number * @chip: The gpio chip that the pin belongs to. @@ -136,36 +94,49 @@ extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip); extern int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset); /* exported for core SoC support to change */ -extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default; +extern struct samsung_gpio_cfg s3c24xx_gpiocfg_default; #ifdef CONFIG_S3C_GPIO_TRACK -extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END]; +extern struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END]; -static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip) +static inline struct samsung_gpio_chip *samsung_gpiolib_getchip(unsigned int chip) { return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL; } #else -/* machine specific code should provide s3c_gpiolib_getchip */ +/* machine specific code should provide samsung_gpiolib_getchip */ + +extern struct samsung_gpio_chip s3c24xx_gpios[]; -#include <mach/gpio-track.h> +static inline struct samsung_gpio_chip *samsung_gpiolib_getchip(unsigned int pin) +{ + struct samsung_gpio_chip *chip; + + if (pin > S3C_GPIO_END) + return NULL; -static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { } + chip = &s3c24xx_gpios[pin/32]; + return ((pin - chip->chip.base) < chip->chip.ngpio) ? chip : NULL; +} + +static inline void s3c_gpiolib_track(struct samsung_gpio_chip *chip) { } #endif #ifdef CONFIG_PM -extern struct s3c_gpio_pm s3c_gpio_pm_1bit; -extern struct s3c_gpio_pm s3c_gpio_pm_2bit; -extern struct s3c_gpio_pm s3c_gpio_pm_4bit; +extern struct samsung_gpio_pm samsung_gpio_pm_1bit; +extern struct samsung_gpio_pm samsung_gpio_pm_2bit; +extern struct samsung_gpio_pm samsung_gpio_pm_4bit; #define __gpio_pm(x) x #else -#define s3c_gpio_pm_1bit NULL -#define s3c_gpio_pm_2bit NULL -#define s3c_gpio_pm_4bit NULL +#define samsung_gpio_pm_1bit NULL +#define samsung_gpio_pm_2bit NULL +#define samsung_gpio_pm_4bit NULL #define __gpio_pm(x) NULL #endif /* CONFIG_PM */ /* locking wrappers to deal with multiple access to the same gpio bank */ -#define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl) -#define s3c_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl) +#define samsung_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl) +#define samsung_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl) + +#endif /* __PLAT_SAMSUNG_GPIO_CORE_H */ diff --git a/arch/arm/plat-samsung/include/plat/hdmi.h b/arch/arm/plat-samsung/include/plat/hdmi.h new file mode 100644 index 00000000000..331d046ac2c --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/hdmi.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co.Ltd + * + * 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. + */ + +#ifndef __PLAT_SAMSUNG_HDMI_H +#define __PLAT_SAMSUNG_HDMI_H __FILE__ + +extern void s5p_hdmi_set_platdata(struct i2c_board_info *hdmiphy_info, + struct i2c_board_info *mhl_info, int mhl_bus); + +#endif /* __PLAT_SAMSUNG_HDMI_H */ diff --git a/arch/arm/plat-samsung/include/plat/hwmon.h b/arch/arm/plat-samsung/include/plat/hwmon.h deleted file mode 100644 index c167e4429bc..00000000000 --- a/arch/arm/plat-samsung/include/plat/hwmon.h +++ /dev/null @@ -1,51 +0,0 @@ -/* linux/arch/arm/plat-s3c/include/plat/hwmon.h - * - * Copyright 2005 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C - HWMon interface for ADC - * - * 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_ADC_HWMON_H -#define __ASM_ARCH_ADC_HWMON_H __FILE__ - -/** - * s3c_hwmon_chcfg - channel configuration - * @name: The name to give this channel. - * @mult: Multiply the ADC value read by this. - * @div: Divide the value from the ADC by this. - * - * The value read from the ADC is converted to a value that - * hwmon expects (mV) by result = (value_read * @mult) / @div. - */ -struct s3c_hwmon_chcfg { - const char *name; - unsigned int mult; - unsigned int div; -}; - -/** - * s3c_hwmon_pdata - HWMON platform data - * @in: One configuration for each possible channel used. - */ -struct s3c_hwmon_pdata { - struct s3c_hwmon_chcfg *in[8]; -}; - -/** - * s3c_hwmon_set_platdata - Set platform data for S3C HWMON device - * @pd: Platform data to register to device. - * - * Register the given platform data for use with the S3C HWMON device. - * The call will copy the platform data, so the board definitions can - * make the structure itself __initdata. - */ -extern void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd); - -#endif /* __ASM_ARCH_ADC_HWMON_H */ - diff --git a/arch/arm/plat-samsung/include/plat/iic.h b/arch/arm/plat-samsung/include/plat/iic.h deleted file mode 100644 index 1543da8f85c..00000000000 --- a/arch/arm/plat-samsung/include/plat/iic.h +++ /dev/null @@ -1,74 +0,0 @@ -/* arch/arm/plat-s3c/include/plat/iic.h - * - * Copyright 2004-2009 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * S3C - I2C Controller platform_device info - * - * 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_IIC_H -#define __ASM_ARCH_IIC_H __FILE__ - -#define S3C_IICFLG_FILTER (1<<0) /* enable s3c2440 filter */ - -/** - * struct s3c2410_platform_i2c - Platform data for s3c I2C. - * @bus_num: The bus number to use (if possible). - * @flags: Any flags for the I2C bus (E.g. S3C_IICFLK_FILTER). - * @slave_addr: The I2C address for the slave device (if enabled). - * @frequency: The desired frequency in Hz of the bus. This is - * guaranteed to not be exceeded. If the caller does - * not care, use zero and the driver will select a - * useful default. - * @sda_delay: The delay (in ns) applied to SDA edges. - * @cfg_gpio: A callback to configure the pins for I2C operation. - */ -struct s3c2410_platform_i2c { - int bus_num; - unsigned int flags; - unsigned int slave_addr; - unsigned long frequency; - unsigned int sda_delay; - - void (*cfg_gpio)(struct platform_device *dev); -}; - -/** - * s3c_i2c0_set_platdata - set platform data for i2c0 device - * @i2c: The platform data to set, or NULL for default data. - * - * Register the given platform data for use with the i2c0 device. This - * call copies the platform data, so the caller can use __initdata for - * their copy. - * - * This call will set cfg_gpio if is null to the default platform - * implementation. - * - * Any user of s3c_device_i2c0 should call this, even if it is with - * NULL to ensure that the device is given the default platform data - * as the driver will no longer carry defaults. - */ -extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c); -extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c); -extern void s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *i2c); -extern void s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *i2c); -extern void s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *i2c); -extern void s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *i2c); -extern void s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *i2c); -extern void s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *i2c); - -/* defined by architecture to configure gpio */ -extern void s3c_i2c0_cfg_gpio(struct platform_device *dev); -extern void s3c_i2c1_cfg_gpio(struct platform_device *dev); -extern void s3c_i2c2_cfg_gpio(struct platform_device *dev); -extern void s3c_i2c3_cfg_gpio(struct platform_device *dev); -extern void s3c_i2c4_cfg_gpio(struct platform_device *dev); -extern void s3c_i2c5_cfg_gpio(struct platform_device *dev); -extern void s3c_i2c6_cfg_gpio(struct platform_device *dev); -extern void s3c_i2c7_cfg_gpio(struct platform_device *dev); - -#endif /* __ASM_ARCH_IIC_H */ diff --git a/arch/arm/plat-samsung/include/plat/irq-vic-timer.h b/arch/arm/plat-samsung/include/plat/irq-vic-timer.h deleted file mode 100644 index a90b53431b5..00000000000 --- a/arch/arm/plat-samsung/include/plat/irq-vic-timer.h +++ /dev/null @@ -1,13 +0,0 @@ -/* arch/arm/plat-samsung/include/plat/irq-vic-timer.h - * - * Copyright (c) 2010 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * Header file for Samsung SoC IRQ VIC timer - * - * 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. -*/ - -extern void s3c_init_vic_timer_irq(unsigned int vic, unsigned int timer); diff --git a/arch/arm/plat-samsung/include/plat/irqs.h b/arch/arm/plat-samsung/include/plat/irqs.h new file mode 100644 index 00000000000..039001c0ef0 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/irqs.h @@ -0,0 +1,72 @@ +/* linux/arch/arm/plat-samsung/include/plat/irqs.h + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P Common IRQ 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. +*/ + +#ifndef __PLAT_SAMSUNG_IRQS_H +#define __PLAT_SAMSUNG_IRQS_H __FILE__ + +/* we keep the first set of CPU IRQs out of the range of + * the ISA space, so that the PC104 has them to itself + * and we don't end up having to do horrible things to the + * standard ISA drivers.... + * + * note, since we're using the VICs, our start must be a + * mulitple of 32 to allow the common code to work + */ + +#define S5P_IRQ_OFFSET (32) + +#define S5P_IRQ(x) ((x) + S5P_IRQ_OFFSET) + +#define S5P_VIC0_BASE S5P_IRQ(0) +#define S5P_VIC1_BASE S5P_IRQ(32) +#define S5P_VIC2_BASE S5P_IRQ(64) +#define S5P_VIC3_BASE S5P_IRQ(96) + +#define VIC_BASE(x) (S5P_VIC0_BASE + ((x)*32)) + +#define IRQ_VIC0_BASE S5P_VIC0_BASE +#define IRQ_VIC1_BASE S5P_VIC1_BASE +#define IRQ_VIC2_BASE S5P_VIC2_BASE + +/* VIC based IRQs */ + +#define S5P_IRQ_VIC0(x) (S5P_VIC0_BASE + (x)) +#define S5P_IRQ_VIC1(x) (S5P_VIC1_BASE + (x)) +#define S5P_IRQ_VIC2(x) (S5P_VIC2_BASE + (x)) +#define S5P_IRQ_VIC3(x) (S5P_VIC3_BASE + (x)) + +#define IRQ_EINT(x) ((x) < 16 ? ((x) + S5P_EINT_BASE1) \ + : ((x) - 16 + S5P_EINT_BASE2)) + +#define EINT_OFFSET(irq) ((irq) < S5P_EINT_BASE2 ? \ + ((irq) - S5P_EINT_BASE1) : \ + ((irq) + 16 - S5P_EINT_BASE2)) + +#define IRQ_EINT_BIT(x) EINT_OFFSET(x) + +/* Typically only a few gpio chips require gpio interrupt support. + To avoid memory waste irq descriptors are allocated only for + S5P_GPIOINT_GROUP_COUNT chips, each with total number of + S5P_GPIOINT_GROUP_SIZE pins/irqs. Each GPIOINT group can be assiged + to any gpio chip with the s5p_register_gpio_interrupt() function */ +#define S5P_GPIOINT_GROUP_COUNT 4 +#define S5P_GPIOINT_GROUP_SIZE 8 +#define S5P_GPIOINT_COUNT (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE) + +/* IRQ types common for all s5p platforms */ +#define S5P_IRQ_TYPE_LEVEL_LOW (0x00) +#define S5P_IRQ_TYPE_LEVEL_HIGH (0x01) +#define S5P_IRQ_TYPE_EDGE_FALLING (0x02) +#define S5P_IRQ_TYPE_EDGE_RISING (0x03) +#define S5P_IRQ_TYPE_EDGE_BOTH (0x04) + +#endif /* __PLAT_SAMSUNG_IRQS_H */ diff --git a/arch/arm/plat-samsung/include/plat/keypad.h b/arch/arm/plat-samsung/include/plat/keypad.h index b59a6483cd8..c81ace332a1 100644 --- a/arch/arm/plat-samsung/include/plat/keypad.h +++ b/arch/arm/plat-samsung/include/plat/keypad.h @@ -13,32 +13,7 @@ #ifndef __PLAT_SAMSUNG_KEYPAD_H #define __PLAT_SAMSUNG_KEYPAD_H -#include <linux/input/matrix_keypad.h> - -#define SAMSUNG_MAX_ROWS 8 -#define SAMSUNG_MAX_COLS 8 - -/** - * struct samsung_keypad_platdata - Platform device data for Samsung Keypad. - * @keymap_data: pointer to &matrix_keymap_data. - * @rows: number of keypad row supported. - * @cols: number of keypad col supported. - * @no_autorepeat: disable key autorepeat. - * @wakeup: controls whether the device should be set up as wakeup source. - * @cfg_gpio: configure the GPIO. - * - * Initialisation data specific to either the machine or the platform - * for the device driver to use or call-back when configuring gpio. - */ -struct samsung_keypad_platdata { - const struct matrix_keymap_data *keymap_data; - unsigned int rows; - unsigned int cols; - bool no_autorepeat; - bool wakeup; - - void (*cfg_gpio)(unsigned int rows, unsigned int cols); -}; +#include <linux/input/samsung-keypad.h> /** * samsung_keypad_set_platdata - Set platform data for Samsung Keypad device. diff --git a/arch/arm/plat-samsung/include/plat/map-s3c.h b/arch/arm/plat-samsung/include/plat/map-s3c.h new file mode 100644 index 00000000000..c0c70a895ca --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/map-s3c.h @@ -0,0 +1,84 @@ +/* linux/arch/arm/plat-samsung/include/plat/map-s3c.h + * + * Copyright (c) 2008 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * S3C24XX - Memory map 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_PLAT_MAP_S3C_H +#define __ASM_PLAT_MAP_S3C_H __FILE__ + +#define S3C24XX_VA_IRQ S3C_VA_IRQ +#define S3C24XX_VA_MEMCTRL S3C_VA_MEM +#define S3C24XX_VA_UART S3C_VA_UART + +#define S3C24XX_VA_TIMER S3C_VA_TIMER +#define S3C24XX_VA_CLKPWR S3C_VA_SYS +#define S3C24XX_VA_WATCHDOG S3C_VA_WATCHDOG + +#define S3C2412_VA_SSMC S3C_ADDR_CPU(0x00000000) +#define S3C2412_VA_EBI S3C_ADDR_CPU(0x00100000) + +#define S3C2410_PA_UART (0x50000000) +#define S3C24XX_PA_UART S3C2410_PA_UART + +#ifndef S3C_UART_OFFSET +#define S3C_UART_OFFSET (0x400) +#endif + +/* + * GPIO ports + * + * the calculation for the VA of this must ensure that + * it is the same distance apart from the UART in the + * phsyical address space, as the initial mapping for the IO + * is done as a 1:1 mapping. This puts it (currently) at + * 0xFA800000, which is not in the way of any current mapping + * by the base system. +*/ + +#define S3C2410_PA_GPIO (0x56000000) +#define S3C24XX_PA_GPIO S3C2410_PA_GPIO + +#define S3C24XX_VA_GPIO ((S3C24XX_PA_GPIO - S3C24XX_PA_UART) + S3C24XX_VA_UART) +#define S3C64XX_VA_GPIO S3C_ADDR_CPU(0x00000000) + +#define S3C64XX_VA_MODEM S3C_ADDR_CPU(0x00100000) +#define S3C64XX_VA_USB_HSPHY S3C_ADDR_CPU(0x00200000) + +#define S3C_VA_USB_HSPHY S3C64XX_VA_USB_HSPHY + +/* + * ISA style IO, for each machine to sort out mappings for, + * if it implements it. We reserve two 16M regions for ISA. + */ + +#define S3C2410_ADDR(x) S3C_ADDR(x) + +#define S3C24XX_VA_ISA_WORD S3C2410_ADDR(0x02000000) +#define S3C24XX_VA_ISA_BYTE S3C2410_ADDR(0x03000000) + +/* deal with the registers that move under the 2412/2413 */ + +#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) +#ifndef __ASSEMBLY__ +extern void __iomem *s3c24xx_va_gpio2; +#endif +#ifdef CONFIG_CPU_S3C2412_ONLY +#define S3C24XX_VA_GPIO2 (S3C24XX_VA_GPIO + 0x10) +#else +#define S3C24XX_VA_GPIO2 s3c24xx_va_gpio2 +#endif +#else +#define s3c24xx_va_gpio2 S3C24XX_VA_GPIO +#define S3C24XX_VA_GPIO2 S3C24XX_VA_GPIO +#endif + +#include <plat/map-s5p.h> + +#endif /* __ASM_PLAT_MAP_S3C_H */ diff --git a/arch/arm/plat-samsung/include/plat/map-s5p.h b/arch/arm/plat-samsung/include/plat/map-s5p.h new file mode 100644 index 00000000000..c18678610bc --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/map-s5p.h @@ -0,0 +1,62 @@ +/* linux/arch/arm/plat-samsung/include/plat/map-s5p.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P - Memory map 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_PLAT_MAP_S5P_H +#define __ASM_PLAT_MAP_S5P_H __FILE__ + +#define S5P_VA_CHIPID S3C_ADDR(0x02000000) +#define S5P_VA_CMU S3C_ADDR(0x02100000) +#define S5P_VA_PMU S3C_ADDR(0x02180000) +#define S5P_VA_GPIO S3C_ADDR(0x02200000) +#define S5P_VA_GPIO1 S5P_VA_GPIO +#define S5P_VA_GPIO2 S3C_ADDR(0x02240000) +#define S5P_VA_GPIO3 S3C_ADDR(0x02280000) + +#define S5P_VA_SYSRAM S3C_ADDR(0x02400000) +#define S5P_VA_SYSRAM_NS S3C_ADDR(0x02410000) +#define S5P_VA_DMC0 S3C_ADDR(0x02440000) +#define S5P_VA_DMC1 S3C_ADDR(0x02480000) +#define S5P_VA_SROMC S3C_ADDR(0x024C0000) + +#define S5P_VA_SYSTIMER S3C_ADDR(0x02500000) +#define S5P_VA_L2CC S3C_ADDR(0x02600000) + +#define S5P_VA_COMBINER_BASE S3C_ADDR(0x02700000) +#define S5P_VA_COMBINER(x) (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10) + +#define S5P_VA_COREPERI_BASE S3C_ADDR(0x02800000) +#define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x)) +#define S5P_VA_SCU S5P_VA_COREPERI(0x0) +#define S5P_VA_TWD S5P_VA_COREPERI(0x600) + +#define S5P_VA_GIC_CPU S3C_ADDR(0x02810000) +#define S5P_VA_GIC_DIST S3C_ADDR(0x02820000) + +#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000)) +#define VA_VIC0 VA_VIC(0) +#define VA_VIC1 VA_VIC(1) +#define VA_VIC2 VA_VIC(2) +#define VA_VIC3 VA_VIC(3) + +#define S5P_VA_UART(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET)) +#define S5P_VA_UART0 S5P_VA_UART(0) +#define S5P_VA_UART1 S5P_VA_UART(1) +#define S5P_VA_UART2 S5P_VA_UART(2) +#define S5P_VA_UART3 S5P_VA_UART(3) + +#ifndef S3C_UART_OFFSET +#define S3C_UART_OFFSET (0x400) +#endif + +#include <plat/map-s3c.h> + +#endif /* __ASM_PLAT_MAP_S5P_H */ diff --git a/arch/arm/plat-samsung/include/plat/mfc.h b/arch/arm/plat-samsung/include/plat/mfc.h new file mode 100644 index 00000000000..033654e91e2 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/mfc.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2011 Samsung Electronics Co.Ltd + * + * 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. + */ + +#ifndef __PLAT_SAMSUNG_MFC_H +#define __PLAT_SAMSUNG_MFC_H __FILE__ + +struct s5p_mfc_dt_meminfo { + unsigned long loff; + unsigned long lsize; + unsigned long roff; + unsigned long rsize; + char *compatible; +}; + +/** + * s5p_mfc_reserve_mem - function to early reserve memory for MFC driver + * @rbase: base address for MFC 'right' memory interface + * @rsize: size of the memory reserved for MFC 'right' interface + * @lbase: base address for MFC 'left' memory interface + * @lsize: size of the memory reserved for MFC 'left' interface + * + * This function reserves system memory for both MFC device memory + * interfaces and registers it to respective struct device entries as + * coherent memory. + */ +void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize, + phys_addr_t lbase, unsigned int lsize); + +#endif /* __PLAT_SAMSUNG_MFC_H */ diff --git a/arch/arm/plat-samsung/include/plat/nand.h b/arch/arm/plat-samsung/include/plat/nand.h deleted file mode 100644 index b64115fa93a..00000000000 --- a/arch/arm/plat-samsung/include/plat/nand.h +++ /dev/null @@ -1,67 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/nand.h - * - * Copyright (c) 2004 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * S3C2410 - NAND device controller platform_device info - * - * 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. -*/ - -/** - * struct s3c2410_nand_set - define a set of one or more nand chips - * @disable_ecc: Entirely disable ECC - Dangerous - * @flash_bbt: Openmoko u-boot can create a Bad Block Table - * Setting this flag will allow the kernel to - * look for it at boot time and also skip the NAND - * scan. - * @options: Default value to set into 'struct nand_chip' options. - * @nr_chips: Number of chips in this set - * @nr_partitions: Number of partitions pointed to by @partitions - * @name: Name of set (optional) - * @nr_map: Map for low-layer logical to physical chip numbers (option) - * @partitions: The mtd partition list - * - * define a set of one or more nand chips registered with an unique mtd. Also - * allows to pass flag to the underlying NAND layer. 'disable_ecc' will trigger - * a warning at boot time. - */ -struct s3c2410_nand_set { - unsigned int disable_ecc:1; - unsigned int flash_bbt:1; - - unsigned int options; - int nr_chips; - int nr_partitions; - char *name; - int *nr_map; - struct mtd_partition *partitions; - struct nand_ecclayout *ecc_layout; -}; - -struct s3c2410_platform_nand { - /* timing information for controller, all times in nanoseconds */ - - int tacls; /* time for active CLE/ALE to nWE/nOE */ - int twrph0; /* active time for nWE/nOE */ - int twrph1; /* time for release CLE/ALE from nWE/nOE inactive */ - - unsigned int ignore_unset_ecc:1; - - int nr_sets; - struct s3c2410_nand_set *sets; - - void (*select_chip)(struct s3c2410_nand_set *, - int chip); -}; - -/** - * s3c_nand_set_platdata() - register NAND platform data. - * @nand: The NAND platform data to register with s3c_device_nand. - * - * This function copies the given NAND platform data, @nand and registers - * it with the s3c_device_nand. This allows @nand to be __initdata. -*/ -extern void s3c_nand_set_platdata(struct s3c2410_platform_nand *nand); diff --git a/arch/arm/plat-samsung/include/plat/pd.h b/arch/arm/plat-samsung/include/plat/pd.h deleted file mode 100644 index abb4bc32716..00000000000 --- a/arch/arm/plat-samsung/include/plat/pd.h +++ /dev/null @@ -1,30 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/pd.h - * - * Copyright (c) 2010-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. -*/ - -#ifndef __ASM_PLAT_SAMSUNG_PD_H -#define __ASM_PLAT_SAMSUNG_PD_H __FILE__ - -struct samsung_pd_info { - int (*enable)(struct device *dev); - int (*disable)(struct device *dev); - void __iomem *base; -}; - -enum exynos4_pd_block { - PD_MFC, - PD_G3D, - PD_LCD0, - PD_LCD1, - PD_TV, - PD_CAM, - PD_GPS -}; - -#endif /* __ASM_PLAT_SAMSUNG_PD_H */ diff --git a/arch/arm/plat-samsung/include/plat/pll.h b/arch/arm/plat-samsung/include/plat/pll.h new file mode 100644 index 00000000000..357af7c1c66 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/pll.h @@ -0,0 +1,323 @@ +/* linux/arch/arm/plat-samsung/include/plat/pll.h + * + * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * http://armlinux.simtec.co.uk/ + * + * Samsung PLL codes + * + * 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 <asm/div64.h> + +#define S3C24XX_PLL_MDIV_MASK (0xFF) +#define S3C24XX_PLL_PDIV_MASK (0x1F) +#define S3C24XX_PLL_SDIV_MASK (0x3) +#define S3C24XX_PLL_MDIV_SHIFT (12) +#define S3C24XX_PLL_PDIV_SHIFT (4) +#define S3C24XX_PLL_SDIV_SHIFT (0) + +static inline unsigned int s3c24xx_get_pll(unsigned int pllval, + unsigned int baseclk) +{ + unsigned int mdiv, pdiv, sdiv; + uint64_t fvco; + + mdiv = (pllval >> S3C24XX_PLL_MDIV_SHIFT) & S3C24XX_PLL_MDIV_MASK; + pdiv = (pllval >> S3C24XX_PLL_PDIV_SHIFT) & S3C24XX_PLL_PDIV_MASK; + sdiv = (pllval >> S3C24XX_PLL_SDIV_SHIFT) & S3C24XX_PLL_SDIV_MASK; + + fvco = (uint64_t)baseclk * (mdiv + 8); + do_div(fvco, (pdiv + 2) << sdiv); + + return (unsigned int)fvco; +} + +#define S3C2416_PLL_MDIV_MASK (0x3FF) +#define S3C2416_PLL_PDIV_MASK (0x3F) +#define S3C2416_PLL_SDIV_MASK (0x7) +#define S3C2416_PLL_MDIV_SHIFT (14) +#define S3C2416_PLL_PDIV_SHIFT (5) +#define S3C2416_PLL_SDIV_SHIFT (0) + +static inline unsigned int s3c2416_get_pll(unsigned int pllval, + unsigned int baseclk) +{ + unsigned int mdiv, pdiv, sdiv; + uint64_t fvco; + + mdiv = (pllval >> S3C2416_PLL_MDIV_SHIFT) & S3C2416_PLL_MDIV_MASK; + pdiv = (pllval >> S3C2416_PLL_PDIV_SHIFT) & S3C2416_PLL_PDIV_MASK; + sdiv = (pllval >> S3C2416_PLL_SDIV_SHIFT) & S3C2416_PLL_SDIV_MASK; + + fvco = (uint64_t)baseclk * mdiv; + do_div(fvco, (pdiv << sdiv)); + + return (unsigned int)fvco; +} + +#define S3C6400_PLL_MDIV_MASK (0x3FF) +#define S3C6400_PLL_PDIV_MASK (0x3F) +#define S3C6400_PLL_SDIV_MASK (0x7) +#define S3C6400_PLL_MDIV_SHIFT (16) +#define S3C6400_PLL_PDIV_SHIFT (8) +#define S3C6400_PLL_SDIV_SHIFT (0) + +static inline unsigned long s3c6400_get_pll(unsigned long baseclk, + u32 pllcon) +{ + u32 mdiv, pdiv, sdiv; + u64 fvco = baseclk; + + mdiv = (pllcon >> S3C6400_PLL_MDIV_SHIFT) & S3C6400_PLL_MDIV_MASK; + pdiv = (pllcon >> S3C6400_PLL_PDIV_SHIFT) & S3C6400_PLL_PDIV_MASK; + sdiv = (pllcon >> S3C6400_PLL_SDIV_SHIFT) & S3C6400_PLL_SDIV_MASK; + + fvco *= mdiv; + do_div(fvco, (pdiv << sdiv)); + + return (unsigned long)fvco; +} + +#define PLL6553X_MDIV_MASK (0x7F) +#define PLL6553X_PDIV_MASK (0x1F) +#define PLL6553X_SDIV_MASK (0x3) +#define PLL6553X_KDIV_MASK (0xFFFF) +#define PLL6553X_MDIV_SHIFT (16) +#define PLL6553X_PDIV_SHIFT (8) +#define PLL6553X_SDIV_SHIFT (0) + +static inline unsigned long s3c_get_pll6553x(unsigned long baseclk, + u32 pll_con0, u32 pll_con1) +{ + unsigned long result; + u32 mdiv, pdiv, sdiv, kdiv; + u64 tmp; + + mdiv = (pll_con0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK; + pdiv = (pll_con0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK; + sdiv = (pll_con0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK; + kdiv = pll_con1 & PLL6553X_KDIV_MASK; + + /* + * We need to multiple baseclk by mdiv (the integer part) and kdiv + * which is in 2^16ths, so shift mdiv up (does not overflow) and + * add kdiv before multiplying. The use of tmp is to avoid any + * overflows before shifting bac down into result when multipling + * by the mdiv and kdiv pair. + */ + + tmp = baseclk; + tmp *= (mdiv << 16) + kdiv; + do_div(tmp, (pdiv << sdiv)); + result = tmp >> 16; + + return result; +} + +#define PLL35XX_MDIV_MASK (0x3FF) +#define PLL35XX_PDIV_MASK (0x3F) +#define PLL35XX_SDIV_MASK (0x7) +#define PLL35XX_MDIV_SHIFT (16) +#define PLL35XX_PDIV_SHIFT (8) +#define PLL35XX_SDIV_SHIFT (0) + +static inline unsigned long s5p_get_pll35xx(unsigned long baseclk, u32 pll_con) +{ + u32 mdiv, pdiv, sdiv; + u64 fvco = baseclk; + + mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK; + pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK; + sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK; + + fvco *= mdiv; + do_div(fvco, (pdiv << sdiv)); + + return (unsigned long)fvco; +} + +#define PLL36XX_KDIV_MASK (0xFFFF) +#define PLL36XX_MDIV_MASK (0x1FF) +#define PLL36XX_PDIV_MASK (0x3F) +#define PLL36XX_SDIV_MASK (0x7) +#define PLL36XX_MDIV_SHIFT (16) +#define PLL36XX_PDIV_SHIFT (8) +#define PLL36XX_SDIV_SHIFT (0) + +static inline unsigned long s5p_get_pll36xx(unsigned long baseclk, + u32 pll_con0, u32 pll_con1) +{ + unsigned long result; + u32 mdiv, pdiv, sdiv, kdiv; + u64 tmp; + + mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK; + pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK; + sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK; + kdiv = pll_con1 & PLL36XX_KDIV_MASK; + + tmp = baseclk; + + tmp *= (mdiv << 16) + kdiv; + do_div(tmp, (pdiv << sdiv)); + result = tmp >> 16; + + return result; +} + +#define PLL45XX_MDIV_MASK (0x3FF) +#define PLL45XX_PDIV_MASK (0x3F) +#define PLL45XX_SDIV_MASK (0x7) +#define PLL45XX_MDIV_SHIFT (16) +#define PLL45XX_PDIV_SHIFT (8) +#define PLL45XX_SDIV_SHIFT (0) + +enum pll45xx_type_t { + pll_4500, + pll_4502, + pll_4508 +}; + +static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con, + enum pll45xx_type_t pll_type) +{ + u32 mdiv, pdiv, sdiv; + u64 fvco = baseclk; + + mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK; + pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK; + sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK; + + if (pll_type == pll_4508) + sdiv = sdiv - 1; + + fvco *= mdiv; + do_div(fvco, (pdiv << sdiv)); + + return (unsigned long)fvco; +} + +/* CON0 bit-fields */ +#define PLL46XX_MDIV_MASK (0x1FF) +#define PLL46XX_PDIV_MASK (0x3F) +#define PLL46XX_SDIV_MASK (0x7) +#define PLL46XX_LOCKED_SHIFT (29) +#define PLL46XX_MDIV_SHIFT (16) +#define PLL46XX_PDIV_SHIFT (8) +#define PLL46XX_SDIV_SHIFT (0) + +/* CON1 bit-fields */ +#define PLL46XX_MRR_MASK (0x1F) +#define PLL46XX_MFR_MASK (0x3F) +#define PLL46XX_KDIV_MASK (0xFFFF) +#define PLL4650C_KDIV_MASK (0xFFF) +#define PLL46XX_MRR_SHIFT (24) +#define PLL46XX_MFR_SHIFT (16) +#define PLL46XX_KDIV_SHIFT (0) + +enum pll46xx_type_t { + pll_4600, + pll_4650, + pll_4650c, +}; + +static inline unsigned long s5p_get_pll46xx(unsigned long baseclk, + u32 pll_con0, u32 pll_con1, + enum pll46xx_type_t pll_type) +{ + unsigned long result; + u32 mdiv, pdiv, sdiv, kdiv; + u64 tmp; + + mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK; + pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK; + sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK; + kdiv = pll_con1 & PLL46XX_KDIV_MASK; + + if (pll_type == pll_4650c) + kdiv = pll_con1 & PLL4650C_KDIV_MASK; + else + kdiv = pll_con1 & PLL46XX_KDIV_MASK; + + tmp = baseclk; + + if (pll_type == pll_4600) { + tmp *= (mdiv << 16) + kdiv; + do_div(tmp, (pdiv << sdiv)); + result = tmp >> 16; + } else { + tmp *= (mdiv << 10) + kdiv; + do_div(tmp, (pdiv << sdiv)); + result = tmp >> 10; + } + + return result; +} + +#define PLL90XX_MDIV_MASK (0xFF) +#define PLL90XX_PDIV_MASK (0x3F) +#define PLL90XX_SDIV_MASK (0x7) +#define PLL90XX_KDIV_MASK (0xffff) +#define PLL90XX_LOCKED_SHIFT (29) +#define PLL90XX_MDIV_SHIFT (16) +#define PLL90XX_PDIV_SHIFT (8) +#define PLL90XX_SDIV_SHIFT (0) +#define PLL90XX_KDIV_SHIFT (0) + +static inline unsigned long s5p_get_pll90xx(unsigned long baseclk, + u32 pll_con, u32 pll_conk) +{ + unsigned long result; + u32 mdiv, pdiv, sdiv, kdiv; + u64 tmp; + + mdiv = (pll_con >> PLL90XX_MDIV_SHIFT) & PLL90XX_MDIV_MASK; + pdiv = (pll_con >> PLL90XX_PDIV_SHIFT) & PLL90XX_PDIV_MASK; + sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK; + kdiv = pll_conk & PLL90XX_KDIV_MASK; + + /* + * We need to multiple baseclk by mdiv (the integer part) and kdiv + * which is in 2^16ths, so shift mdiv up (does not overflow) and + * add kdiv before multiplying. The use of tmp is to avoid any + * overflows before shifting bac down into result when multipling + * by the mdiv and kdiv pair. + */ + + tmp = baseclk; + tmp *= (mdiv << 16) + kdiv; + do_div(tmp, (pdiv << sdiv)); + result = tmp >> 16; + + return result; +} + +#define PLL65XX_MDIV_MASK (0x3FF) +#define PLL65XX_PDIV_MASK (0x3F) +#define PLL65XX_SDIV_MASK (0x7) +#define PLL65XX_MDIV_SHIFT (16) +#define PLL65XX_PDIV_SHIFT (8) +#define PLL65XX_SDIV_SHIFT (0) + +static inline unsigned long s5p_get_pll65xx(unsigned long baseclk, u32 pll_con) +{ + u32 mdiv, pdiv, sdiv; + u64 fvco = baseclk; + + mdiv = (pll_con >> PLL65XX_MDIV_SHIFT) & PLL65XX_MDIV_MASK; + pdiv = (pll_con >> PLL65XX_PDIV_SHIFT) & PLL65XX_PDIV_MASK; + sdiv = (pll_con >> PLL65XX_SDIV_SHIFT) & PLL65XX_SDIV_MASK; + + fvco *= mdiv; + do_div(fvco, (pdiv << sdiv)); + + return (unsigned long)fvco; +} diff --git a/arch/arm/plat-samsung/include/plat/pll6553x.h b/arch/arm/plat-samsung/include/plat/pll6553x.h deleted file mode 100644 index b8b7e1d884f..00000000000 --- a/arch/arm/plat-samsung/include/plat/pll6553x.h +++ /dev/null @@ -1,51 +0,0 @@ -/* arch/arm/plat-samsung/include/plat/pll6553x.h - * partially from arch/arm/mach-s3c64xx/include/mach/pll.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * Samsung PLL6553x PLL 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. -*/ - -/* S3C6400 and compatible (S3C2416, etc.) EPLL code */ - -#define PLL6553X_MDIV_MASK ((1 << (23-16)) - 1) -#define PLL6553X_PDIV_MASK ((1 << (13-8)) - 1) -#define PLL6553X_SDIV_MASK ((1 << (2-0)) - 1) -#define PLL6553X_MDIV_SHIFT (16) -#define PLL6553X_PDIV_SHIFT (8) -#define PLL6553X_SDIV_SHIFT (0) -#define PLL6553X_KDIV_MASK (0xffff) - -static inline unsigned long s3c_get_pll6553x(unsigned long baseclk, - u32 pll0, u32 pll1) -{ - unsigned long result; - u32 mdiv, pdiv, sdiv, kdiv; - u64 tmp; - - mdiv = (pll0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK; - pdiv = (pll0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK; - sdiv = (pll0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK; - kdiv = pll1 & PLL6553X_KDIV_MASK; - - /* We need to multiple baseclk by mdiv (the integer part) and kdiv - * which is in 2^16ths, so shift mdiv up (does not overflow) and - * add kdiv before multiplying. The use of tmp is to avoid any - * overflows before shifting bac down into result when multipling - * by the mdiv and kdiv pair. - */ - - tmp = baseclk; - tmp *= (mdiv << 16) + kdiv; - do_div(tmp, (pdiv << sdiv)); - result = tmp >> 16; - - return result; -} diff --git a/arch/arm/plat-samsung/include/plat/pm-common.h b/arch/arm/plat-samsung/include/plat/pm-common.h new file mode 100644 index 00000000000..8705f9e0e28 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/pm-common.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Tomasz Figa <t.figa@samsung.com> + * Copyright (c) 2004 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Written by Ben Dooks, <ben@simtec.co.uk> + * + * 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_SAMSUNG_PM_COMMON_H +#define __PLAT_SAMSUNG_PM_COMMON_H __FILE__ + +#include <linux/irq.h> + +/* sleep save info */ + +/** + * struct sleep_save - save information for shared peripherals. + * @reg: Pointer to the register to save. + * @val: Holder for the value saved from reg. + * + * This describes a list of registers which is used by the pm core and + * other subsystem to save and restore register values over suspend. + */ +struct sleep_save { + void __iomem *reg; + unsigned long val; +}; + +#define SAVE_ITEM(x) \ + { .reg = (x) } + +/* helper functions to save/restore lists of registers. */ + +extern void s3c_pm_do_save(struct sleep_save *ptr, int count); +extern void s3c_pm_do_restore(const struct sleep_save *ptr, int count); +extern void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count); + +/* PM debug functions */ + +/** + * struct pm_uart_save - save block for core UART + * @ulcon: Save value for S3C2410_ULCON + * @ucon: Save value for S3C2410_UCON + * @ufcon: Save value for S3C2410_UFCON + * @umcon: Save value for S3C2410_UMCON + * @ubrdiv: Save value for S3C2410_UBRDIV + * + * Save block for UART registers to be held over sleep and restored if they + * are needed (say by debug). +*/ +struct pm_uart_save { + u32 ulcon; + u32 ucon; + u32 ufcon; + u32 umcon; + u32 ubrdiv; + u32 udivslot; +}; + +#ifdef CONFIG_SAMSUNG_PM_DEBUG +/** + * s3c_pm_dbg() - low level debug function for use in suspend/resume. + * @msg: The message to print. + * + * This function is used mainly to debug the resume process before the system + * can rely on printk/console output. It uses the low-level debugging output + * routine printascii() to do its work. + */ +extern void s3c_pm_dbg(const char *msg, ...); + +/** + * s3c_pm_debug_init() - suspend/resume low level debug initialization. + * @base: Virtual base of UART to use for suspend/resume debugging. + * + * This function needs to be called before S3C_PMDBG() can be used, to set up + * UART port base address and configuration. + */ +extern void s3c_pm_debug_init(void); + +#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt) + +extern void s3c_pm_save_uarts(void); +extern void s3c_pm_restore_uarts(void); +#else +#define S3C_PMDBG(fmt...) pr_debug(fmt) +#define s3c_pm_debug_init() do { } while (0) + +static inline void s3c_pm_save_uarts(void) { } +static inline void s3c_pm_restore_uarts(void) { } +#endif + +/* suspend memory checking */ + +#ifdef CONFIG_SAMSUNG_PM_CHECK +extern void s3c_pm_check_prepare(void); +extern void s3c_pm_check_restore(void); +extern void s3c_pm_check_cleanup(void); +extern void s3c_pm_check_store(void); +#else +#define s3c_pm_check_prepare() do { } while (0) +#define s3c_pm_check_restore() do { } while (0) +#define s3c_pm_check_cleanup() do { } while (0) +#define s3c_pm_check_store() do { } while (0) +#endif + +#endif diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h index 937cc2ace51..e17d871b934 100644 --- a/arch/arm/plat-samsung/include/plat/pm.h +++ b/arch/arm/plat-samsung/include/plat/pm.h @@ -15,13 +15,14 @@ * management */ -#include <linux/irq.h> +#include <plat/pm-common.h> -struct sys_device; +struct device; -#ifdef CONFIG_PM +#ifdef CONFIG_SAMSUNG_PM extern __init int s3c_pm_init(void); +extern __init int s3c64xx_pm_init(void); #else @@ -29,6 +30,11 @@ static inline int s3c_pm_init(void) { return 0; } + +static inline int s3c64xx_pm_init(void) +{ + return 0; +} #endif /* configuration for the IRQ mask over sleep */ @@ -42,91 +48,24 @@ extern unsigned long s3c_irqwake_eintallow; /* per-cpu sleep functions */ extern void (*pm_cpu_prep)(void); -extern void (*pm_cpu_sleep)(void); +extern int (*pm_cpu_sleep)(unsigned long); /* Flags for PM Control */ extern unsigned long s3c_pm_flags; -extern unsigned char pm_uart_udivslot; /* true to save UART UDIVSLOT */ - /* from sleep.S */ -extern int s3c_cpu_save(unsigned long *saveblk, long); -extern void s3c_cpu_resume(void); - -extern void s3c2410_cpu_suspend(void); - -/* sleep save info */ +extern int s3c2410_cpu_suspend(unsigned long); -/** - * struct sleep_save - save information for shared peripherals. - * @reg: Pointer to the register to save. - * @val: Holder for the value saved from reg. - * - * This describes a list of registers which is used by the pm core and - * other subsystem to save and restore register values over suspend. - */ -struct sleep_save { - void __iomem *reg; - unsigned long val; -}; - -#define SAVE_ITEM(x) \ - { .reg = (x) } - -/** - * struct pm_uart_save - save block for core UART - * @ulcon: Save value for S3C2410_ULCON - * @ucon: Save value for S3C2410_UCON - * @ufcon: Save value for S3C2410_UFCON - * @umcon: Save value for S3C2410_UMCON - * @ubrdiv: Save value for S3C2410_UBRDIV - * - * Save block for UART registers to be held over sleep and restored if they - * are needed (say by debug). -*/ -struct pm_uart_save { - u32 ulcon; - u32 ucon; - u32 ufcon; - u32 umcon; - u32 ubrdiv; - u32 udivslot; -}; - -/* helper functions to save/restore lists of registers. */ - -extern void s3c_pm_do_save(struct sleep_save *ptr, int count); -extern void s3c_pm_do_restore(struct sleep_save *ptr, int count); -extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count); - -#ifdef CONFIG_PM +#ifdef CONFIG_SAMSUNG_PM +extern int s3c_irq_wake(struct irq_data *data, unsigned int state); extern int s3c_irqext_wake(struct irq_data *data, unsigned int state); -extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state); -extern int s3c24xx_irq_resume(struct sys_device *dev); +extern void s3c_cpu_resume(void); #else +#define s3c_irq_wake NULL #define s3c_irqext_wake NULL -#define s3c24xx_irq_suspend NULL -#define s3c24xx_irq_resume NULL -#endif - -/* PM debug functions */ - -#ifdef CONFIG_SAMSUNG_PM_DEBUG -/** - * s3c_pm_dbg() - low level debug function for use in suspend/resume. - * @msg: The message to print. - * - * This function is used mainly to debug the resume process before the system - * can rely on printk/console output. It uses the low-level debugging output - * routine printascii() to do its work. - */ -extern void s3c_pm_dbg(const char *msg, ...); - -#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt) -#else -#define S3C_PMDBG(fmt...) printk(KERN_DEBUG fmt) +#define s3c_cpu_resume NULL #endif #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK @@ -141,20 +80,6 @@ extern void s3c_pm_debug_smdkled(u32 set, u32 clear); static inline void s3c_pm_debug_smdkled(u32 set, u32 clear) { } #endif /* CONFIG_S3C_PM_DEBUG_LED_SMDK */ -/* suspend memory checking */ - -#ifdef CONFIG_SAMSUNG_PM_CHECK -extern void s3c_pm_check_prepare(void); -extern void s3c_pm_check_restore(void); -extern void s3c_pm_check_cleanup(void); -extern void s3c_pm_check_store(void); -#else -#define s3c_pm_check_prepare() do { } while(0) -#define s3c_pm_check_restore() do { } while(0) -#define s3c_pm_check_cleanup() do { } while(0) -#define s3c_pm_check_store() do { } while(0) -#endif - /** * s3c_pm_configure_extint() - ensure pins are correctly set for IRQ * @@ -163,21 +88,26 @@ extern void s3c_pm_check_store(void); */ extern void s3c_pm_configure_extint(void); +#ifdef CONFIG_GPIO_SAMSUNG /** - * s3c_pm_restore_gpios() - restore the state of the gpios after sleep. + * samsung_pm_restore_gpios() - restore the state of the gpios after sleep. * * Restore the state of the GPIO pins after sleep, which may involve ensuring * that we do not glitch the state of the pins from that the bootloader's * resume code has done. */ -extern void s3c_pm_restore_gpios(void); +extern void samsung_pm_restore_gpios(void); /** - * s3c_pm_save_gpios() - save the state of the GPIOs for restoring after sleep. + * samsung_pm_save_gpios() - save the state of the GPIOs for restoring after sleep. * - * Save the GPIO states for resotration on resume. See s3c_pm_restore_gpios(). + * Save the GPIO states for resotration on resume. See samsung_pm_restore_gpios(). */ -extern void s3c_pm_save_gpios(void); +extern void samsung_pm_save_gpios(void); +#else +static inline void samsung_pm_restore_gpios(void) {} +static inline void samsung_pm_save_gpios(void) {} +#endif extern void s3c_pm_save_core(void); extern void s3c_pm_restore_core(void); diff --git a/arch/arm/plat-samsung/include/plat/pwm-core.h b/arch/arm/plat-samsung/include/plat/pwm-core.h new file mode 100644 index 00000000000..5bff1facb67 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/pwm-core.h @@ -0,0 +1,22 @@ +/* + * Copyright 2013 Tomasz Figa <tomasz.figa@gmail.com> + * + * Samsung PWM controller platform data helpers. + * + * 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_PWM_CORE_H +#define __ASM_ARCH_PWM_CORE_H __FILE__ + +#include <clocksource/samsung_pwm.h> + +#ifdef CONFIG_SAMSUNG_DEV_PWM +extern void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd); +#else +static inline void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd) { } +#endif + +#endif /* __ASM_ARCH_PWM_CORE_H */ diff --git a/arch/arm/plat-samsung/include/plat/regs-ac97.h b/arch/arm/plat-samsung/include/plat/regs-ac97.h deleted file mode 100644 index c3878f7acb8..00000000000 --- a/arch/arm/plat-samsung/include/plat/regs-ac97.h +++ /dev/null @@ -1,67 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-ac97.h - * - * Copyright (c) 2006 Simtec Electronics <linux@simtec.co.uk> - * http://www.simtec.co.uk/products/SWLINUX/ - * - * 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. - * - * S3C2440 AC97 Controller -*/ - -#ifndef __ASM_ARCH_REGS_AC97_H -#define __ASM_ARCH_REGS_AC97_H __FILE__ - -#define S3C_AC97_GLBCTRL (0x00) - -#define S3C_AC97_GLBCTRL_CODECREADYIE (1<<22) -#define S3C_AC97_GLBCTRL_PCMOUTURIE (1<<21) -#define S3C_AC97_GLBCTRL_PCMINORIE (1<<20) -#define S3C_AC97_GLBCTRL_MICINORIE (1<<19) -#define S3C_AC97_GLBCTRL_PCMOUTTIE (1<<18) -#define S3C_AC97_GLBCTRL_PCMINTIE (1<<17) -#define S3C_AC97_GLBCTRL_MICINTIE (1<<16) -#define S3C_AC97_GLBCTRL_PCMOUTTM_OFF (0<<12) -#define S3C_AC97_GLBCTRL_PCMOUTTM_PIO (1<<12) -#define S3C_AC97_GLBCTRL_PCMOUTTM_DMA (2<<12) -#define S3C_AC97_GLBCTRL_PCMOUTTM_MASK (3<<12) -#define S3C_AC97_GLBCTRL_PCMINTM_OFF (0<<10) -#define S3C_AC97_GLBCTRL_PCMINTM_PIO (1<<10) -#define S3C_AC97_GLBCTRL_PCMINTM_DMA (2<<10) -#define S3C_AC97_GLBCTRL_PCMINTM_MASK (3<<10) -#define S3C_AC97_GLBCTRL_MICINTM_OFF (0<<8) -#define S3C_AC97_GLBCTRL_MICINTM_PIO (1<<8) -#define S3C_AC97_GLBCTRL_MICINTM_DMA (2<<8) -#define S3C_AC97_GLBCTRL_MICINTM_MASK (3<<8) -#define S3C_AC97_GLBCTRL_TRANSFERDATAENABLE (1<<3) -#define S3C_AC97_GLBCTRL_ACLINKON (1<<2) -#define S3C_AC97_GLBCTRL_WARMRESET (1<<1) -#define S3C_AC97_GLBCTRL_COLDRESET (1<<0) - -#define S3C_AC97_GLBSTAT (0x04) - -#define S3C_AC97_GLBSTAT_CODECREADY (1<<22) -#define S3C_AC97_GLBSTAT_PCMOUTUR (1<<21) -#define S3C_AC97_GLBSTAT_PCMINORI (1<<20) -#define S3C_AC97_GLBSTAT_MICINORI (1<<19) -#define S3C_AC97_GLBSTAT_PCMOUTTI (1<<18) -#define S3C_AC97_GLBSTAT_PCMINTI (1<<17) -#define S3C_AC97_GLBSTAT_MICINTI (1<<16) -#define S3C_AC97_GLBSTAT_MAINSTATE_IDLE (0<<0) -#define S3C_AC97_GLBSTAT_MAINSTATE_INIT (1<<0) -#define S3C_AC97_GLBSTAT_MAINSTATE_READY (2<<0) -#define S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE (3<<0) -#define S3C_AC97_GLBSTAT_MAINSTATE_LP (4<<0) -#define S3C_AC97_GLBSTAT_MAINSTATE_WARM (5<<0) - -#define S3C_AC97_CODEC_CMD (0x08) - -#define S3C_AC97_CODEC_CMD_READ (1<<23) - -#define S3C_AC97_STAT (0x0c) -#define S3C_AC97_PCM_ADDR (0x10) -#define S3C_AC97_PCM_DATA (0x18) -#define S3C_AC97_MIC_DATA (0x1C) - -#endif /* __ASM_ARCH_REGS_AC97_H */ diff --git a/arch/arm/plat-samsung/include/plat/regs-adc.h b/arch/arm/plat-samsung/include/plat/regs-adc.h index 7554c4fcddb..70612100120 100644 --- a/arch/arm/plat-samsung/include/plat/regs-adc.h +++ b/arch/arm/plat-samsung/include/plat/regs-adc.h @@ -20,7 +20,9 @@ #define S3C2410_ADCDAT0 S3C2410_ADCREG(0x0C) #define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10) #define S3C64XX_ADCUPDN S3C2410_ADCREG(0x14) +#define S3C2443_ADCMUX S3C2410_ADCREG(0x18) #define S3C64XX_ADCCLRINT S3C2410_ADCREG(0x18) +#define S5P_ADCMUX S3C2410_ADCREG(0x1C) #define S3C64XX_ADCCLRINTPNDNUP S3C2410_ADCREG(0x20) @@ -32,6 +34,7 @@ #define S3C2410_ADCCON_PRSCVLMASK (0xFF<<6) #define S3C2410_ADCCON_SELMUX(x) (((x)&0x7)<<3) #define S3C2410_ADCCON_MUXMASK (0x7<<3) +#define S3C2416_ADCCON_RESSEL (1 << 3) #define S3C2410_ADCCON_STDBM (1<<2) #define S3C2410_ADCCON_READ_START (1<<1) #define S3C2410_ADCCON_ENABLE_START (1<<0) @@ -39,6 +42,7 @@ /* ADCTSC Register Bits */ +#define S3C2443_ADCTSC_UD_SEN (1 << 8) #define S3C2410_ADCTSC_YM_SEN (1<<7) #define S3C2410_ADCTSC_YP_SEN (1<<6) #define S3C2410_ADCTSC_XM_SEN (1<<5) diff --git a/arch/arm/plat-samsung/include/plat/regs-ata.h b/arch/arm/plat-samsung/include/plat/regs-ata.h deleted file mode 100644 index f5df92fdae2..00000000000 --- a/arch/arm/plat-samsung/include/plat/regs-ata.h +++ /dev/null @@ -1,56 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/regs-ata.h - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Samsung CF-ATA 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 __ASM_PLAT_REGS_ATA_H -#define __ASM_PLAT_REGS_ATA_H __FILE__ - -#define S3C_CFATA_REG(x) (x) - -#define S3C_CFATA_MUX S3C_CFATA_REG(0x0) - -#define S3C_ATA_CTRL S3C_CFATA_REG(0x0) -#define S3C_ATA_STATUS S3C_CFATA_REG(0x4) -#define S3C_ATA_CMD S3C_CFATA_REG(0x8) -#define S3C_ATA_SWRST S3C_CFATA_REG(0xc) -#define S3C_ATA_IRQ S3C_CFATA_REG(0x10) -#define S3C_ATA_IRQ_MSK S3C_CFATA_REG(0x14) -#define S3C_ATA_CFG S3C_CFATA_REG(0x18) - -#define S3C_ATA_MDMA_TIME S3C_CFATA_REG(0x28) -#define S3C_ATA_PIO_TIME S3C_CFATA_REG(0x2c) -#define S3C_ATA_UDMA_TIME S3C_CFATA_REG(0x30) -#define S3C_ATA_XFR_NUM S3C_CFATA_REG(0x34) -#define S3C_ATA_XFR_CNT S3C_CFATA_REG(0x38) -#define S3C_ATA_TBUF_START S3C_CFATA_REG(0x3c) -#define S3C_ATA_TBUF_SIZE S3C_CFATA_REG(0x40) -#define S3C_ATA_SBUF_START S3C_CFATA_REG(0x44) -#define S3C_ATA_SBUF_SIZE S3C_CFATA_REG(0x48) -#define S3C_ATA_CADR_TBUF S3C_CFATA_REG(0x4c) -#define S3C_ATA_CADR_SBUF S3C_CFATA_REG(0x50) -#define S3C_ATA_PIO_DTR S3C_CFATA_REG(0x54) -#define S3C_ATA_PIO_FED S3C_CFATA_REG(0x58) -#define S3C_ATA_PIO_SCR S3C_CFATA_REG(0x5c) -#define S3C_ATA_PIO_LLR S3C_CFATA_REG(0x60) -#define S3C_ATA_PIO_LMR S3C_CFATA_REG(0x64) -#define S3C_ATA_PIO_LHR S3C_CFATA_REG(0x68) -#define S3C_ATA_PIO_DVR S3C_CFATA_REG(0x6c) -#define S3C_ATA_PIO_CSD S3C_CFATA_REG(0x70) -#define S3C_ATA_PIO_DAD S3C_CFATA_REG(0x74) -#define S3C_ATA_PIO_READY S3C_CFATA_REG(0x78) -#define S3C_ATA_PIO_RDATA S3C_CFATA_REG(0x7c) - -#define S3C_CFATA_MUX_TRUEIDE 0x01 - -#define S3C_ATA_CFG_SWAP 0x40 -#define S3C_ATA_CFG_IORDYEN 0x02 - -#endif /* __ASM_PLAT_REGS_ATA_H */ diff --git a/arch/arm/plat-samsung/include/plat/regs-dma.h b/arch/arm/plat-samsung/include/plat/regs-dma.h new file mode 100644 index 00000000000..a7d622ef16a --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/regs-dma.h @@ -0,0 +1,151 @@ +/* arch/arm/plat-samsung/include/plat/regs-dma.h + * + * Copyright (C) 2003-2006 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * Samsung S3C24XX DMA 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. +*/ + +#ifndef __ASM_PLAT_REGS_DMA_H +#define __ASM_PLAT_REGS_DMA_H __FILE__ + +#define S3C2410_DMA_DISRC (0x00) +#define S3C2410_DMA_DISRCC (0x04) +#define S3C2410_DMA_DIDST (0x08) +#define S3C2410_DMA_DIDSTC (0x0C) +#define S3C2410_DMA_DCON (0x10) +#define S3C2410_DMA_DSTAT (0x14) +#define S3C2410_DMA_DCSRC (0x18) +#define S3C2410_DMA_DCDST (0x1C) +#define S3C2410_DMA_DMASKTRIG (0x20) +#define S3C2412_DMA_DMAREQSEL (0x24) +#define S3C2443_DMA_DMAREQSEL (0x24) + +#define S3C2410_DISRCC_INC (1 << 0) +#define S3C2410_DISRCC_APB (1 << 1) + +#define S3C2410_DMASKTRIG_STOP (1 << 2) +#define S3C2410_DMASKTRIG_ON (1 << 1) +#define S3C2410_DMASKTRIG_SWTRIG (1 << 0) + +#define S3C2410_DCON_DEMAND (0 << 31) +#define S3C2410_DCON_HANDSHAKE (1 << 31) +#define S3C2410_DCON_SYNC_PCLK (0 << 30) +#define S3C2410_DCON_SYNC_HCLK (1 << 30) + +#define S3C2410_DCON_INTREQ (1 << 29) + +#define S3C2410_DCON_CH0_XDREQ0 (0 << 24) +#define S3C2410_DCON_CH0_UART0 (1 << 24) +#define S3C2410_DCON_CH0_SDI (2 << 24) +#define S3C2410_DCON_CH0_TIMER (3 << 24) +#define S3C2410_DCON_CH0_USBEP1 (4 << 24) + +#define S3C2410_DCON_CH1_XDREQ1 (0 << 24) +#define S3C2410_DCON_CH1_UART1 (1 << 24) +#define S3C2410_DCON_CH1_I2SSDI (2 << 24) +#define S3C2410_DCON_CH1_SPI (3 << 24) +#define S3C2410_DCON_CH1_USBEP2 (4 << 24) + +#define S3C2410_DCON_CH2_I2SSDO (0 << 24) +#define S3C2410_DCON_CH2_I2SSDI (1 << 24) +#define S3C2410_DCON_CH2_SDI (2 << 24) +#define S3C2410_DCON_CH2_TIMER (3 << 24) +#define S3C2410_DCON_CH2_USBEP3 (4 << 24) + +#define S3C2410_DCON_CH3_UART2 (0 << 24) +#define S3C2410_DCON_CH3_SDI (1 << 24) +#define S3C2410_DCON_CH3_SPI (2 << 24) +#define S3C2410_DCON_CH3_TIMER (3 << 24) +#define S3C2410_DCON_CH3_USBEP4 (4 << 24) + +#define S3C2410_DCON_SRCSHIFT (24) +#define S3C2410_DCON_SRCMASK (7 << 24) + +#define S3C2410_DCON_BYTE (0 << 20) +#define S3C2410_DCON_HALFWORD (1 << 20) +#define S3C2410_DCON_WORD (2 << 20) + +#define S3C2410_DCON_AUTORELOAD (0 << 22) +#define S3C2410_DCON_NORELOAD (1 << 22) +#define S3C2410_DCON_HWTRIG (1 << 23) + +#ifdef CONFIG_CPU_S3C2440 + +#define S3C2440_DIDSTC_CHKINT (1 << 2) + +#define S3C2440_DCON_CH0_I2SSDO (5 << 24) +#define S3C2440_DCON_CH0_PCMIN (6 << 24) + +#define S3C2440_DCON_CH1_PCMOUT (5 << 24) +#define S3C2440_DCON_CH1_SDI (6 << 24) + +#define S3C2440_DCON_CH2_PCMIN (5 << 24) +#define S3C2440_DCON_CH2_MICIN (6 << 24) + +#define S3C2440_DCON_CH3_MICIN (5 << 24) +#define S3C2440_DCON_CH3_PCMOUT (6 << 24) +#endif /* CONFIG_CPU_S3C2440 */ + +#ifdef CONFIG_CPU_S3C2412 + +#define S3C2412_DMAREQSEL_SRC(x) ((x) << 1) + +#define S3C2412_DMAREQSEL_HW (1) + +#define S3C2412_DMAREQSEL_SPI0TX S3C2412_DMAREQSEL_SRC(0) +#define S3C2412_DMAREQSEL_SPI0RX S3C2412_DMAREQSEL_SRC(1) +#define S3C2412_DMAREQSEL_SPI1TX S3C2412_DMAREQSEL_SRC(2) +#define S3C2412_DMAREQSEL_SPI1RX S3C2412_DMAREQSEL_SRC(3) +#define S3C2412_DMAREQSEL_I2STX S3C2412_DMAREQSEL_SRC(4) +#define S3C2412_DMAREQSEL_I2SRX S3C2412_DMAREQSEL_SRC(5) +#define S3C2412_DMAREQSEL_TIMER S3C2412_DMAREQSEL_SRC(9) +#define S3C2412_DMAREQSEL_SDI S3C2412_DMAREQSEL_SRC(10) +#define S3C2412_DMAREQSEL_USBEP1 S3C2412_DMAREQSEL_SRC(13) +#define S3C2412_DMAREQSEL_USBEP2 S3C2412_DMAREQSEL_SRC(14) +#define S3C2412_DMAREQSEL_USBEP3 S3C2412_DMAREQSEL_SRC(15) +#define S3C2412_DMAREQSEL_USBEP4 S3C2412_DMAREQSEL_SRC(16) +#define S3C2412_DMAREQSEL_XDREQ0 S3C2412_DMAREQSEL_SRC(17) +#define S3C2412_DMAREQSEL_XDREQ1 S3C2412_DMAREQSEL_SRC(18) +#define S3C2412_DMAREQSEL_UART0_0 S3C2412_DMAREQSEL_SRC(19) +#define S3C2412_DMAREQSEL_UART0_1 S3C2412_DMAREQSEL_SRC(20) +#define S3C2412_DMAREQSEL_UART1_0 S3C2412_DMAREQSEL_SRC(21) +#define S3C2412_DMAREQSEL_UART1_1 S3C2412_DMAREQSEL_SRC(22) +#define S3C2412_DMAREQSEL_UART2_0 S3C2412_DMAREQSEL_SRC(23) +#define S3C2412_DMAREQSEL_UART2_1 S3C2412_DMAREQSEL_SRC(24) +#endif /* CONFIG_CPU_S3C2412 */ + +#if defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2443) + +#define S3C2443_DMAREQSEL_SRC(x) ((x) << 1) + +#define S3C2443_DMAREQSEL_HW (1) + +#define S3C2443_DMAREQSEL_SPI0TX S3C2443_DMAREQSEL_SRC(0) +#define S3C2443_DMAREQSEL_SPI0RX S3C2443_DMAREQSEL_SRC(1) +#define S3C2443_DMAREQSEL_SPI1TX S3C2443_DMAREQSEL_SRC(2) +#define S3C2443_DMAREQSEL_SPI1RX S3C2443_DMAREQSEL_SRC(3) +#define S3C2443_DMAREQSEL_I2STX S3C2443_DMAREQSEL_SRC(4) +#define S3C2443_DMAREQSEL_I2SRX S3C2443_DMAREQSEL_SRC(5) +#define S3C2443_DMAREQSEL_TIMER S3C2443_DMAREQSEL_SRC(9) +#define S3C2443_DMAREQSEL_SDI S3C2443_DMAREQSEL_SRC(10) +#define S3C2443_DMAREQSEL_XDREQ0 S3C2443_DMAREQSEL_SRC(17) +#define S3C2443_DMAREQSEL_XDREQ1 S3C2443_DMAREQSEL_SRC(18) +#define S3C2443_DMAREQSEL_UART0_0 S3C2443_DMAREQSEL_SRC(19) +#define S3C2443_DMAREQSEL_UART0_1 S3C2443_DMAREQSEL_SRC(20) +#define S3C2443_DMAREQSEL_UART1_0 S3C2443_DMAREQSEL_SRC(21) +#define S3C2443_DMAREQSEL_UART1_1 S3C2443_DMAREQSEL_SRC(22) +#define S3C2443_DMAREQSEL_UART2_0 S3C2443_DMAREQSEL_SRC(23) +#define S3C2443_DMAREQSEL_UART2_1 S3C2443_DMAREQSEL_SRC(24) +#define S3C2443_DMAREQSEL_UART3_0 S3C2443_DMAREQSEL_SRC(25) +#define S3C2443_DMAREQSEL_UART3_1 S3C2443_DMAREQSEL_SRC(26) +#define S3C2443_DMAREQSEL_PCMOUT S3C2443_DMAREQSEL_SRC(27) +#define S3C2443_DMAREQSEL_PCMIN S3C2443_DMAREQSEL_SRC(28) +#define S3C2443_DMAREQSEL_MICIN S3C2443_DMAREQSEL_SRC(29) +#endif /* CONFIG_CPU_S3C2443 */ + +#endif /* __ASM_PLAT_REGS_DMA_H */ diff --git a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h deleted file mode 100644 index 4c3647f8005..00000000000 --- a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h +++ /dev/null @@ -1,159 +0,0 @@ -/* arch/arm/plat-samsung/include/plat/regs-fb-v4.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * S3C64XX - new-style framebuffer register definitions - * - * This is the register set for the new style framebuffer interface - * found from the S3C2443 onwards and specifically the S3C64XX series - * S3C6400 and S3C6410. - * - * The file contains the cpu specific items which change between whichever - * architecture is selected. See <plat/regs-fb.h> for the core definitions - * that are the same. - * - * 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 the core definitions here, in case we really do need to - * override them at a later date. -*/ - -#include <plat/regs-fb.h> - -#define S3C_FB_MAX_WIN (5) /* number of hardware windows available. */ -#define VIDCON1_FSTATUS_EVEN (1 << 15) - -/* Video timing controls */ -#define VIDTCON0 (0x10) -#define VIDTCON1 (0x14) -#define VIDTCON2 (0x18) - -/* Window position controls */ - -#define WINCON(_win) (0x20 + ((_win) * 4)) - -/* OSD1 and OSD4 do not have register D */ - -#define VIDOSD_BASE (0x40) - -#define VIDINTCON0 (0x130) - -/* WINCONx */ - -#define WINCONx_CSCWIDTH_MASK (0x3 << 26) -#define WINCONx_CSCWIDTH_SHIFT (26) -#define WINCONx_CSCWIDTH_WIDE (0x0 << 26) -#define WINCONx_CSCWIDTH_NARROW (0x3 << 26) - -#define WINCONx_ENLOCAL (1 << 22) -#define WINCONx_BUFSTATUS (1 << 21) -#define WINCONx_BUFSEL (1 << 20) -#define WINCONx_BUFAUTOEN (1 << 19) -#define WINCONx_YCbCr (1 << 13) - -#define WINCON1_LOCALSEL_CAMIF (1 << 23) - -#define WINCON2_LOCALSEL_CAMIF (1 << 23) -#define WINCON2_BLD_PIX (1 << 6) - -#define WINCON2_ALPHA_SEL (1 << 1) -#define WINCON2_BPPMODE_MASK (0xf << 2) -#define WINCON2_BPPMODE_SHIFT (2) -#define WINCON2_BPPMODE_1BPP (0x0 << 2) -#define WINCON2_BPPMODE_2BPP (0x1 << 2) -#define WINCON2_BPPMODE_4BPP (0x2 << 2) -#define WINCON2_BPPMODE_8BPP_1232 (0x4 << 2) -#define WINCON2_BPPMODE_16BPP_565 (0x5 << 2) -#define WINCON2_BPPMODE_16BPP_A1555 (0x6 << 2) -#define WINCON2_BPPMODE_16BPP_I1555 (0x7 << 2) -#define WINCON2_BPPMODE_18BPP_666 (0x8 << 2) -#define WINCON2_BPPMODE_18BPP_A1665 (0x9 << 2) -#define WINCON2_BPPMODE_19BPP_A1666 (0xa << 2) -#define WINCON2_BPPMODE_24BPP_888 (0xb << 2) -#define WINCON2_BPPMODE_24BPP_A1887 (0xc << 2) -#define WINCON2_BPPMODE_25BPP_A1888 (0xd << 2) -#define WINCON2_BPPMODE_28BPP_A4888 (0xd << 2) - -#define WINCON3_BLD_PIX (1 << 6) - -#define WINCON3_ALPHA_SEL (1 << 1) -#define WINCON3_BPPMODE_MASK (0xf << 2) -#define WINCON3_BPPMODE_SHIFT (2) -#define WINCON3_BPPMODE_1BPP (0x0 << 2) -#define WINCON3_BPPMODE_2BPP (0x1 << 2) -#define WINCON3_BPPMODE_4BPP (0x2 << 2) -#define WINCON3_BPPMODE_16BPP_565 (0x5 << 2) -#define WINCON3_BPPMODE_16BPP_A1555 (0x6 << 2) -#define WINCON3_BPPMODE_16BPP_I1555 (0x7 << 2) -#define WINCON3_BPPMODE_18BPP_666 (0x8 << 2) -#define WINCON3_BPPMODE_18BPP_A1665 (0x9 << 2) -#define WINCON3_BPPMODE_19BPP_A1666 (0xa << 2) -#define WINCON3_BPPMODE_24BPP_888 (0xb << 2) -#define WINCON3_BPPMODE_24BPP_A1887 (0xc << 2) -#define WINCON3_BPPMODE_25BPP_A1888 (0xd << 2) -#define WINCON3_BPPMODE_28BPP_A4888 (0xd << 2) - -#define VIDINTCON0_FIFIOSEL_WINDOW2 (0x10 << 5) -#define VIDINTCON0_FIFIOSEL_WINDOW3 (0x20 << 5) -#define VIDINTCON0_FIFIOSEL_WINDOW4 (0x40 << 5) - -#define DITHMODE (0x170) -#define WINxMAP(_win) (0x180 + ((_win) * 4)) - - -#define DITHMODE_R_POS_MASK (0x3 << 5) -#define DITHMODE_R_POS_SHIFT (5) -#define DITHMODE_R_POS_8BIT (0x0 << 5) -#define DITHMODE_R_POS_6BIT (0x1 << 5) -#define DITHMODE_R_POS_5BIT (0x2 << 5) - -#define DITHMODE_G_POS_MASK (0x3 << 3) -#define DITHMODE_G_POS_SHIFT (3) -#define DITHMODE_G_POS_8BIT (0x0 << 3) -#define DITHMODE_G_POS_6BIT (0x1 << 3) -#define DITHMODE_G_POS_5BIT (0x2 << 3) - -#define DITHMODE_B_POS_MASK (0x3 << 1) -#define DITHMODE_B_POS_SHIFT (1) -#define DITHMODE_B_POS_8BIT (0x0 << 1) -#define DITHMODE_B_POS_6BIT (0x1 << 1) -#define DITHMODE_B_POS_5BIT (0x2 << 1) - -#define DITHMODE_DITH_EN (1 << 0) - -#define WPALCON (0x1A0) - -/* Palette control */ -/* Note for S5PC100: you can still use those macros on WPALCON (aka WPALCON_L), - * but make sure that WPALCON_H W2PAL-W4PAL entries are zeroed out */ -#define WPALCON_W4PAL_16BPP_A555 (1 << 8) -#define WPALCON_W3PAL_16BPP_A555 (1 << 7) -#define WPALCON_W2PAL_16BPP_A555 (1 << 6) - - -/* Notes on per-window bpp settings - * - * Value Win0 Win1 Win2 Win3 Win 4 - * 0000 1(P) 1(P) 1(P) 1(P) 1(P) - * 0001 2(P) 2(P) 2(P) 2(P) 2(P) - * 0010 4(P) 4(P) 4(P) 4(P) -none- - * 0011 8(P) 8(P) -none- -none- -none- - * 0100 -none- 8(A232) 8(A232) -none- -none- - * 0101 16(565) 16(565) 16(565) 16(565) 16(565) - * 0110 -none- 16(A555) 16(A555) 16(A555) 16(A555) - * 0111 16(I555) 16(I565) 16(I555) 16(I555) 16(I555) - * 1000 18(666) 18(666) 18(666) 18(666) 18(666) - * 1001 -none- 18(A665) 18(A665) 18(A665) 16(A665) - * 1010 -none- 19(A666) 19(A666) 19(A666) 19(A666) - * 1011 24(888) 24(888) 24(888) 24(888) 24(888) - * 1100 -none- 24(A887) 24(A887) 24(A887) 24(A887) - * 1101 -none- 25(A888) 25(A888) 25(A888) 25(A888) - * 1110 -none- -none- -none- -none- -none- - * 1111 -none- -none- -none- -none- -none- -*/ diff --git a/arch/arm/plat-samsung/include/plat/regs-fb.h b/arch/arm/plat-samsung/include/plat/regs-fb.h deleted file mode 100644 index 8f39aa5b26e..00000000000 --- a/arch/arm/plat-samsung/include/plat/regs-fb.h +++ /dev/null @@ -1,386 +0,0 @@ -/* arch/arm/plat-samsung/include/plat/regs-fb.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * S3C Platform - new-style framebuffer register definitions - * - * This is the register set for the new style framebuffer interface - * found from the S3C2443 onwards into the S3C2416, S3C2450 and the - * S3C64XX series such as the S3C6400 and S3C6410. - * - * The file does not contain the cpu specific items which are based on - * whichever architecture is selected, it only contains the core of the - * register set. See <mach/regs-fb.h> to get the specifics. - * - * Note, we changed to using regs-fb.h as it avoids any clashes with - * the original regs-lcd.h so out of the way of regs-lcd.h as well as - * indicating the newer block is much more than just an LCD interface. - * - * 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. -*/ - -/* Please do not include this file directly, use <mach/regs-fb.h> to - * ensure all the localised SoC support is included as necessary. -*/ - -/* VIDCON0 */ - -#define VIDCON0 (0x00) -#define VIDCON0_INTERLACE (1 << 29) -#define VIDCON0_VIDOUT_MASK (0x3 << 26) -#define VIDCON0_VIDOUT_SHIFT (26) -#define VIDCON0_VIDOUT_RGB (0x0 << 26) -#define VIDCON0_VIDOUT_TV (0x1 << 26) -#define VIDCON0_VIDOUT_I80_LDI0 (0x2 << 26) -#define VIDCON0_VIDOUT_I80_LDI1 (0x3 << 26) - -#define VIDCON0_L1_DATA_MASK (0x7 << 23) -#define VIDCON0_L1_DATA_SHIFT (23) -#define VIDCON0_L1_DATA_16BPP (0x0 << 23) -#define VIDCON0_L1_DATA_18BPP16 (0x1 << 23) -#define VIDCON0_L1_DATA_18BPP9 (0x2 << 23) -#define VIDCON0_L1_DATA_24BPP (0x3 << 23) -#define VIDCON0_L1_DATA_18BPP (0x4 << 23) -#define VIDCON0_L1_DATA_16BPP8 (0x5 << 23) - -#define VIDCON0_L0_DATA_MASK (0x7 << 20) -#define VIDCON0_L0_DATA_SHIFT (20) -#define VIDCON0_L0_DATA_16BPP (0x0 << 20) -#define VIDCON0_L0_DATA_18BPP16 (0x1 << 20) -#define VIDCON0_L0_DATA_18BPP9 (0x2 << 20) -#define VIDCON0_L0_DATA_24BPP (0x3 << 20) -#define VIDCON0_L0_DATA_18BPP (0x4 << 20) -#define VIDCON0_L0_DATA_16BPP8 (0x5 << 20) - -#define VIDCON0_PNRMODE_MASK (0x3 << 17) -#define VIDCON0_PNRMODE_SHIFT (17) -#define VIDCON0_PNRMODE_RGB (0x0 << 17) -#define VIDCON0_PNRMODE_BGR (0x1 << 17) -#define VIDCON0_PNRMODE_SERIAL_RGB (0x2 << 17) -#define VIDCON0_PNRMODE_SERIAL_BGR (0x3 << 17) - -#define VIDCON0_CLKVALUP (1 << 16) -#define VIDCON0_CLKVAL_F_MASK (0xff << 6) -#define VIDCON0_CLKVAL_F_SHIFT (6) -#define VIDCON0_CLKVAL_F_LIMIT (0xff) -#define VIDCON0_CLKVAL_F(_x) ((_x) << 6) -#define VIDCON0_VLCKFREE (1 << 5) -#define VIDCON0_CLKDIR (1 << 4) - -#define VIDCON0_CLKSEL_MASK (0x3 << 2) -#define VIDCON0_CLKSEL_SHIFT (2) -#define VIDCON0_CLKSEL_HCLK (0x0 << 2) -#define VIDCON0_CLKSEL_LCD (0x1 << 2) -#define VIDCON0_CLKSEL_27M (0x3 << 2) - -#define VIDCON0_ENVID (1 << 1) -#define VIDCON0_ENVID_F (1 << 0) - -#define VIDCON1 (0x04) -#define VIDCON1_LINECNT_MASK (0x7ff << 16) -#define VIDCON1_LINECNT_SHIFT (16) -#define VIDCON1_LINECNT_GET(_v) (((_v) >> 16) & 0x7ff) -#define VIDCON1_VSTATUS_MASK (0x3 << 13) -#define VIDCON1_VSTATUS_SHIFT (13) -#define VIDCON1_VSTATUS_VSYNC (0x0 << 13) -#define VIDCON1_VSTATUS_BACKPORCH (0x1 << 13) -#define VIDCON1_VSTATUS_ACTIVE (0x2 << 13) -#define VIDCON1_VSTATUS_FRONTPORCH (0x0 << 13) - -#define VIDCON1_INV_VCLK (1 << 7) -#define VIDCON1_INV_HSYNC (1 << 6) -#define VIDCON1_INV_VSYNC (1 << 5) -#define VIDCON1_INV_VDEN (1 << 4) - -/* VIDCON2 */ - -#define VIDCON2 (0x08) -#define VIDCON2_EN601 (1 << 23) -#define VIDCON2_TVFMTSEL_SW (1 << 14) - -#define VIDCON2_TVFMTSEL1_MASK (0x3 << 12) -#define VIDCON2_TVFMTSEL1_SHIFT (12) -#define VIDCON2_TVFMTSEL1_RGB (0x0 << 12) -#define VIDCON2_TVFMTSEL1_YUV422 (0x1 << 12) -#define VIDCON2_TVFMTSEL1_YUV444 (0x2 << 12) - -#define VIDCON2_ORGYCbCr (1 << 8) -#define VIDCON2_YUVORDCrCb (1 << 7) - -/* PRTCON (S3C6410, S5PC100) - * Might not be present in the S3C6410 documentation, - * but tests prove it's there almost for sure; shouldn't hurt in any case. - */ -#define PRTCON (0x0c) -#define PRTCON_PROTECT (1 << 11) - -/* VIDTCON0 */ - -#define VIDTCON0_VBPDE_MASK (0xff << 24) -#define VIDTCON0_VBPDE_SHIFT (24) -#define VIDTCON0_VBPDE_LIMIT (0xff) -#define VIDTCON0_VBPDE(_x) ((_x) << 24) - -#define VIDTCON0_VBPD_MASK (0xff << 16) -#define VIDTCON0_VBPD_SHIFT (16) -#define VIDTCON0_VBPD_LIMIT (0xff) -#define VIDTCON0_VBPD(_x) ((_x) << 16) - -#define VIDTCON0_VFPD_MASK (0xff << 8) -#define VIDTCON0_VFPD_SHIFT (8) -#define VIDTCON0_VFPD_LIMIT (0xff) -#define VIDTCON0_VFPD(_x) ((_x) << 8) - -#define VIDTCON0_VSPW_MASK (0xff << 0) -#define VIDTCON0_VSPW_SHIFT (0) -#define VIDTCON0_VSPW_LIMIT (0xff) -#define VIDTCON0_VSPW(_x) ((_x) << 0) - -/* VIDTCON1 */ - -#define VIDTCON1_VFPDE_MASK (0xff << 24) -#define VIDTCON1_VFPDE_SHIFT (24) -#define VIDTCON1_VFPDE_LIMIT (0xff) -#define VIDTCON1_VFPDE(_x) ((_x) << 24) - -#define VIDTCON1_HBPD_MASK (0xff << 16) -#define VIDTCON1_HBPD_SHIFT (16) -#define VIDTCON1_HBPD_LIMIT (0xff) -#define VIDTCON1_HBPD(_x) ((_x) << 16) - -#define VIDTCON1_HFPD_MASK (0xff << 8) -#define VIDTCON1_HFPD_SHIFT (8) -#define VIDTCON1_HFPD_LIMIT (0xff) -#define VIDTCON1_HFPD(_x) ((_x) << 8) - -#define VIDTCON1_HSPW_MASK (0xff << 0) -#define VIDTCON1_HSPW_SHIFT (0) -#define VIDTCON1_HSPW_LIMIT (0xff) -#define VIDTCON1_HSPW(_x) ((_x) << 0) - -#define VIDTCON2 (0x18) -#define VIDTCON2_LINEVAL_MASK (0x7ff << 11) -#define VIDTCON2_LINEVAL_SHIFT (11) -#define VIDTCON2_LINEVAL_LIMIT (0x7ff) -#define VIDTCON2_LINEVAL(_x) ((_x) << 11) - -#define VIDTCON2_HOZVAL_MASK (0x7ff << 0) -#define VIDTCON2_HOZVAL_SHIFT (0) -#define VIDTCON2_HOZVAL_LIMIT (0x7ff) -#define VIDTCON2_HOZVAL(_x) ((_x) << 0) - -/* WINCONx */ - - -#define WINCONx_BITSWP (1 << 18) -#define WINCONx_BYTSWP (1 << 17) -#define WINCONx_HAWSWP (1 << 16) -#define WINCONx_WSWP (1 << 15) -#define WINCONx_BURSTLEN_MASK (0x3 << 9) -#define WINCONx_BURSTLEN_SHIFT (9) -#define WINCONx_BURSTLEN_16WORD (0x0 << 9) -#define WINCONx_BURSTLEN_8WORD (0x1 << 9) -#define WINCONx_BURSTLEN_4WORD (0x2 << 9) - -#define WINCONx_ENWIN (1 << 0) -#define WINCON0_BPPMODE_MASK (0xf << 2) -#define WINCON0_BPPMODE_SHIFT (2) -#define WINCON0_BPPMODE_1BPP (0x0 << 2) -#define WINCON0_BPPMODE_2BPP (0x1 << 2) -#define WINCON0_BPPMODE_4BPP (0x2 << 2) -#define WINCON0_BPPMODE_8BPP_PALETTE (0x3 << 2) -#define WINCON0_BPPMODE_16BPP_565 (0x5 << 2) -#define WINCON0_BPPMODE_16BPP_1555 (0x7 << 2) -#define WINCON0_BPPMODE_18BPP_666 (0x8 << 2) -#define WINCON0_BPPMODE_24BPP_888 (0xb << 2) - -#define WINCON1_BLD_PIX (1 << 6) - -#define WINCON1_ALPHA_SEL (1 << 1) -#define WINCON1_BPPMODE_MASK (0xf << 2) -#define WINCON1_BPPMODE_SHIFT (2) -#define WINCON1_BPPMODE_1BPP (0x0 << 2) -#define WINCON1_BPPMODE_2BPP (0x1 << 2) -#define WINCON1_BPPMODE_4BPP (0x2 << 2) -#define WINCON1_BPPMODE_8BPP_PALETTE (0x3 << 2) -#define WINCON1_BPPMODE_8BPP_1232 (0x4 << 2) -#define WINCON1_BPPMODE_16BPP_565 (0x5 << 2) -#define WINCON1_BPPMODE_16BPP_A1555 (0x6 << 2) -#define WINCON1_BPPMODE_16BPP_I1555 (0x7 << 2) -#define WINCON1_BPPMODE_18BPP_666 (0x8 << 2) -#define WINCON1_BPPMODE_18BPP_A1665 (0x9 << 2) -#define WINCON1_BPPMODE_19BPP_A1666 (0xa << 2) -#define WINCON1_BPPMODE_24BPP_888 (0xb << 2) -#define WINCON1_BPPMODE_24BPP_A1887 (0xc << 2) -#define WINCON1_BPPMODE_25BPP_A1888 (0xd << 2) -#define WINCON1_BPPMODE_28BPP_A4888 (0xd << 2) - -/* S5PV210 */ -#define SHADOWCON (0x34) -#define SHADOWCON_WINx_PROTECT(_win) (1 << (10 + (_win))) -/* DMA channels (all windows) */ -#define SHADOWCON_CHx_ENABLE(_win) (1 << (_win)) -/* Local input channels (windows 0-2) */ -#define SHADOWCON_CHx_LOCAL_ENABLE(_win) (1 << (5 + (_win))) - -#define VIDOSDxA_TOPLEFT_X_MASK (0x7ff << 11) -#define VIDOSDxA_TOPLEFT_X_SHIFT (11) -#define VIDOSDxA_TOPLEFT_X_LIMIT (0x7ff) -#define VIDOSDxA_TOPLEFT_X(_x) ((_x) << 11) - -#define VIDOSDxA_TOPLEFT_Y_MASK (0x7ff << 0) -#define VIDOSDxA_TOPLEFT_Y_SHIFT (0) -#define VIDOSDxA_TOPLEFT_Y_LIMIT (0x7ff) -#define VIDOSDxA_TOPLEFT_Y(_x) ((_x) << 0) - -#define VIDOSDxB_BOTRIGHT_X_MASK (0x7ff << 11) -#define VIDOSDxB_BOTRIGHT_X_SHIFT (11) -#define VIDOSDxB_BOTRIGHT_X_LIMIT (0x7ff) -#define VIDOSDxB_BOTRIGHT_X(_x) ((_x) << 11) - -#define VIDOSDxB_BOTRIGHT_Y_MASK (0x7ff << 0) -#define VIDOSDxB_BOTRIGHT_Y_SHIFT (0) -#define VIDOSDxB_BOTRIGHT_Y_LIMIT (0x7ff) -#define VIDOSDxB_BOTRIGHT_Y(_x) ((_x) << 0) - -/* For VIDOSD[1..4]C */ -#define VIDISD14C_ALPHA0_R(_x) ((_x) << 20) -#define VIDISD14C_ALPHA0_G_MASK (0xf << 16) -#define VIDISD14C_ALPHA0_G_SHIFT (16) -#define VIDISD14C_ALPHA0_G_LIMIT (0xf) -#define VIDISD14C_ALPHA0_G(_x) ((_x) << 16) -#define VIDISD14C_ALPHA0_B_MASK (0xf << 12) -#define VIDISD14C_ALPHA0_B_SHIFT (12) -#define VIDISD14C_ALPHA0_B_LIMIT (0xf) -#define VIDISD14C_ALPHA0_B(_x) ((_x) << 12) -#define VIDISD14C_ALPHA1_R_MASK (0xf << 8) -#define VIDISD14C_ALPHA1_R_SHIFT (8) -#define VIDISD14C_ALPHA1_R_LIMIT (0xf) -#define VIDISD14C_ALPHA1_R(_x) ((_x) << 8) -#define VIDISD14C_ALPHA1_G_MASK (0xf << 4) -#define VIDISD14C_ALPHA1_G_SHIFT (4) -#define VIDISD14C_ALPHA1_G_LIMIT (0xf) -#define VIDISD14C_ALPHA1_G(_x) ((_x) << 4) -#define VIDISD14C_ALPHA1_B_MASK (0xf << 0) -#define VIDISD14C_ALPHA1_B_SHIFT (0) -#define VIDISD14C_ALPHA1_B_LIMIT (0xf) -#define VIDISD14C_ALPHA1_B(_x) ((_x) << 0) - -/* Video buffer addresses */ -#define VIDW_BUF_START(_buff) (0xA0 + ((_buff) * 8)) -#define VIDW_BUF_START1(_buff) (0xA4 + ((_buff) * 8)) -#define VIDW_BUF_END(_buff) (0xD0 + ((_buff) * 8)) -#define VIDW_BUF_END1(_buff) (0xD4 + ((_buff) * 8)) -#define VIDW_BUF_SIZE(_buff) (0x100 + ((_buff) * 4)) - -#define VIDW_BUF_SIZE_OFFSET_MASK (0x1fff << 13) -#define VIDW_BUF_SIZE_OFFSET_SHIFT (13) -#define VIDW_BUF_SIZE_OFFSET_LIMIT (0x1fff) -#define VIDW_BUF_SIZE_OFFSET(_x) ((_x) << 13) - -#define VIDW_BUF_SIZE_PAGEWIDTH_MASK (0x1fff << 0) -#define VIDW_BUF_SIZE_PAGEWIDTH_SHIFT (0) -#define VIDW_BUF_SIZE_PAGEWIDTH_LIMIT (0x1fff) -#define VIDW_BUF_SIZE_PAGEWIDTH(_x) ((_x) << 0) - -/* Interrupt controls and status */ - -#define VIDINTCON0_FIFOINTERVAL_MASK (0x3f << 20) -#define VIDINTCON0_FIFOINTERVAL_SHIFT (20) -#define VIDINTCON0_FIFOINTERVAL_LIMIT (0x3f) -#define VIDINTCON0_FIFOINTERVAL(_x) ((_x) << 20) - -#define VIDINTCON0_INT_SYSMAINCON (1 << 19) -#define VIDINTCON0_INT_SYSSUBCON (1 << 18) -#define VIDINTCON0_INT_I80IFDONE (1 << 17) - -#define VIDINTCON0_FRAMESEL0_MASK (0x3 << 15) -#define VIDINTCON0_FRAMESEL0_SHIFT (15) -#define VIDINTCON0_FRAMESEL0_BACKPORCH (0x0 << 15) -#define VIDINTCON0_FRAMESEL0_VSYNC (0x1 << 15) -#define VIDINTCON0_FRAMESEL0_ACTIVE (0x2 << 15) -#define VIDINTCON0_FRAMESEL0_FRONTPORCH (0x3 << 15) - -#define VIDINTCON0_FRAMESEL1 (1 << 13) -#define VIDINTCON0_FRAMESEL1_MASK (0x3 << 13) -#define VIDINTCON0_FRAMESEL1_NONE (0x0 << 13) -#define VIDINTCON0_FRAMESEL1_BACKPORCH (0x1 << 13) -#define VIDINTCON0_FRAMESEL1_VSYNC (0x2 << 13) -#define VIDINTCON0_FRAMESEL1_FRONTPORCH (0x3 << 13) - -#define VIDINTCON0_INT_FRAME (1 << 12) -#define VIDINTCON0_FIFIOSEL_MASK (0x7f << 5) -#define VIDINTCON0_FIFIOSEL_SHIFT (5) -#define VIDINTCON0_FIFIOSEL_WINDOW0 (0x1 << 5) -#define VIDINTCON0_FIFIOSEL_WINDOW1 (0x2 << 5) - -#define VIDINTCON0_FIFOLEVEL_MASK (0x7 << 2) -#define VIDINTCON0_FIFOLEVEL_SHIFT (2) -#define VIDINTCON0_FIFOLEVEL_TO25PC (0x0 << 2) -#define VIDINTCON0_FIFOLEVEL_TO50PC (0x1 << 2) -#define VIDINTCON0_FIFOLEVEL_TO75PC (0x2 << 2) -#define VIDINTCON0_FIFOLEVEL_EMPTY (0x3 << 2) -#define VIDINTCON0_FIFOLEVEL_FULL (0x4 << 2) - -#define VIDINTCON0_INT_FIFO_MASK (0x3 << 0) -#define VIDINTCON0_INT_FIFO_SHIFT (0) -#define VIDINTCON0_INT_ENABLE (1 << 0) - -#define VIDINTCON1 (0x134) -#define VIDINTCON1_INT_I180 (1 << 2) -#define VIDINTCON1_INT_FRAME (1 << 1) -#define VIDINTCON1_INT_FIFO (1 << 0) - -/* Window colour-key control registers */ -#define WKEYCON (0x140) /* 6410,V210 */ - -#define WKEYCON0 (0x00) -#define WKEYCON1 (0x04) - -#define WxKEYCON0_KEYBL_EN (1 << 26) -#define WxKEYCON0_KEYEN_F (1 << 25) -#define WxKEYCON0_DIRCON (1 << 24) -#define WxKEYCON0_COMPKEY_MASK (0xffffff << 0) -#define WxKEYCON0_COMPKEY_SHIFT (0) -#define WxKEYCON0_COMPKEY_LIMIT (0xffffff) -#define WxKEYCON0_COMPKEY(_x) ((_x) << 0) -#define WxKEYCON1_COLVAL_MASK (0xffffff << 0) -#define WxKEYCON1_COLVAL_SHIFT (0) -#define WxKEYCON1_COLVAL_LIMIT (0xffffff) -#define WxKEYCON1_COLVAL(_x) ((_x) << 0) - - -/* Window blanking (MAP) */ - -#define WINxMAP_MAP (1 << 24) -#define WINxMAP_MAP_COLOUR_MASK (0xffffff << 0) -#define WINxMAP_MAP_COLOUR_SHIFT (0) -#define WINxMAP_MAP_COLOUR_LIMIT (0xffffff) -#define WINxMAP_MAP_COLOUR(_x) ((_x) << 0) - -#define WPALCON_PAL_UPDATE (1 << 9) -#define WPALCON_W1PAL_MASK (0x7 << 3) -#define WPALCON_W1PAL_SHIFT (3) -#define WPALCON_W1PAL_25BPP_A888 (0x0 << 3) -#define WPALCON_W1PAL_24BPP (0x1 << 3) -#define WPALCON_W1PAL_19BPP_A666 (0x2 << 3) -#define WPALCON_W1PAL_18BPP_A665 (0x3 << 3) -#define WPALCON_W1PAL_18BPP (0x4 << 3) -#define WPALCON_W1PAL_16BPP_A555 (0x5 << 3) -#define WPALCON_W1PAL_16BPP_565 (0x6 << 3) - -#define WPALCON_W0PAL_MASK (0x7 << 0) -#define WPALCON_W0PAL_SHIFT (0) -#define WPALCON_W0PAL_25BPP_A888 (0x0 << 0) -#define WPALCON_W0PAL_24BPP (0x1 << 0) -#define WPALCON_W0PAL_19BPP_A666 (0x2 << 0) -#define WPALCON_W0PAL_18BPP_A665 (0x3 << 0) -#define WPALCON_W0PAL_18BPP (0x4 << 0) -#define WPALCON_W0PAL_16BPP_A555 (0x5 << 0) -#define WPALCON_W0PAL_16BPP_565 (0x6 << 0) - diff --git a/arch/arm/plat-samsung/include/plat/regs-iic.h b/arch/arm/plat-samsung/include/plat/regs-iic.h deleted file mode 100644 index 2f7c17de8ac..00000000000 --- a/arch/arm/plat-samsung/include/plat/regs-iic.h +++ /dev/null @@ -1,56 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-iic.h - * - * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk> - * http://www.simtec.co.uk/products/SWLINUX/ - * - * 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. - * - * S3C2410 I2C Controller -*/ - -#ifndef __ASM_ARCH_REGS_IIC_H -#define __ASM_ARCH_REGS_IIC_H __FILE__ - -/* see s3c2410x user guide, v1.1, section 9 (p447) for more info */ - -#define S3C2410_IICREG(x) (x) - -#define S3C2410_IICCON S3C2410_IICREG(0x00) -#define S3C2410_IICSTAT S3C2410_IICREG(0x04) -#define S3C2410_IICADD S3C2410_IICREG(0x08) -#define S3C2410_IICDS S3C2410_IICREG(0x0C) -#define S3C2440_IICLC S3C2410_IICREG(0x10) - -#define S3C2410_IICCON_ACKEN (1<<7) -#define S3C2410_IICCON_TXDIV_16 (0<<6) -#define S3C2410_IICCON_TXDIV_512 (1<<6) -#define S3C2410_IICCON_IRQEN (1<<5) -#define S3C2410_IICCON_IRQPEND (1<<4) -#define S3C2410_IICCON_SCALE(x) ((x)&15) -#define S3C2410_IICCON_SCALEMASK (0xf) - -#define S3C2410_IICSTAT_MASTER_RX (2<<6) -#define S3C2410_IICSTAT_MASTER_TX (3<<6) -#define S3C2410_IICSTAT_SLAVE_RX (0<<6) -#define S3C2410_IICSTAT_SLAVE_TX (1<<6) -#define S3C2410_IICSTAT_MODEMASK (3<<6) - -#define S3C2410_IICSTAT_START (1<<5) -#define S3C2410_IICSTAT_BUSBUSY (1<<5) -#define S3C2410_IICSTAT_TXRXEN (1<<4) -#define S3C2410_IICSTAT_ARBITR (1<<3) -#define S3C2410_IICSTAT_ASSLAVE (1<<2) -#define S3C2410_IICSTAT_ADDR0 (1<<1) -#define S3C2410_IICSTAT_LASTBIT (1<<0) - -#define S3C2410_IICLC_SDA_DELAY0 (0 << 0) -#define S3C2410_IICLC_SDA_DELAY5 (1 << 0) -#define S3C2410_IICLC_SDA_DELAY10 (2 << 0) -#define S3C2410_IICLC_SDA_DELAY15 (3 << 0) -#define S3C2410_IICLC_SDA_DELAY_MASK (3 << 0) - -#define S3C2410_IICLC_FILTER_ON (1<<2) - -#endif /* __ASM_ARCH_REGS_IIC_H */ diff --git a/arch/arm/plat-samsung/include/plat/regs-nand.h b/arch/arm/plat-samsung/include/plat/regs-nand.h deleted file mode 100644 index 238efea7b9e..00000000000 --- a/arch/arm/plat-samsung/include/plat/regs-nand.h +++ /dev/null @@ -1,123 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-nand.h - * - * Copyright (c) 2004-2005 Simtec Electronics <linux@simtec.co.uk> - * http://www.simtec.co.uk/products/SWLINUX/ - * - * 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. - * - * S3C2410 NAND register definitions -*/ - -#ifndef __ASM_ARM_REGS_NAND -#define __ASM_ARM_REGS_NAND - - -#define S3C2410_NFREG(x) (x) - -#define S3C2410_NFCONF S3C2410_NFREG(0x00) -#define S3C2410_NFCMD S3C2410_NFREG(0x04) -#define S3C2410_NFADDR S3C2410_NFREG(0x08) -#define S3C2410_NFDATA S3C2410_NFREG(0x0C) -#define S3C2410_NFSTAT S3C2410_NFREG(0x10) -#define S3C2410_NFECC S3C2410_NFREG(0x14) - -#define S3C2440_NFCONT S3C2410_NFREG(0x04) -#define S3C2440_NFCMD S3C2410_NFREG(0x08) -#define S3C2440_NFADDR S3C2410_NFREG(0x0C) -#define S3C2440_NFDATA S3C2410_NFREG(0x10) -#define S3C2440_NFECCD0 S3C2410_NFREG(0x14) -#define S3C2440_NFECCD1 S3C2410_NFREG(0x18) -#define S3C2440_NFECCD S3C2410_NFREG(0x1C) -#define S3C2440_NFSTAT S3C2410_NFREG(0x20) -#define S3C2440_NFESTAT0 S3C2410_NFREG(0x24) -#define S3C2440_NFESTAT1 S3C2410_NFREG(0x28) -#define S3C2440_NFMECC0 S3C2410_NFREG(0x2C) -#define S3C2440_NFMECC1 S3C2410_NFREG(0x30) -#define S3C2440_NFSECC S3C2410_NFREG(0x34) -#define S3C2440_NFSBLK S3C2410_NFREG(0x38) -#define S3C2440_NFEBLK S3C2410_NFREG(0x3C) - -#define S3C2412_NFSBLK S3C2410_NFREG(0x20) -#define S3C2412_NFEBLK S3C2410_NFREG(0x24) -#define S3C2412_NFSTAT S3C2410_NFREG(0x28) -#define S3C2412_NFMECC_ERR0 S3C2410_NFREG(0x2C) -#define S3C2412_NFMECC_ERR1 S3C2410_NFREG(0x30) -#define S3C2412_NFMECC0 S3C2410_NFREG(0x34) -#define S3C2412_NFMECC1 S3C2410_NFREG(0x38) -#define S3C2412_NFSECC S3C2410_NFREG(0x3C) - -#define S3C2410_NFCONF_EN (1<<15) -#define S3C2410_NFCONF_512BYTE (1<<14) -#define S3C2410_NFCONF_4STEP (1<<13) -#define S3C2410_NFCONF_INITECC (1<<12) -#define S3C2410_NFCONF_nFCE (1<<11) -#define S3C2410_NFCONF_TACLS(x) ((x)<<8) -#define S3C2410_NFCONF_TWRPH0(x) ((x)<<4) -#define S3C2410_NFCONF_TWRPH1(x) ((x)<<0) - -#define S3C2410_NFSTAT_BUSY (1<<0) - -#define S3C2440_NFCONF_BUSWIDTH_8 (0<<0) -#define S3C2440_NFCONF_BUSWIDTH_16 (1<<0) -#define S3C2440_NFCONF_ADVFLASH (1<<3) -#define S3C2440_NFCONF_TACLS(x) ((x)<<12) -#define S3C2440_NFCONF_TWRPH0(x) ((x)<<8) -#define S3C2440_NFCONF_TWRPH1(x) ((x)<<4) - -#define S3C2440_NFCONT_LOCKTIGHT (1<<13) -#define S3C2440_NFCONT_SOFTLOCK (1<<12) -#define S3C2440_NFCONT_ILLEGALACC_EN (1<<10) -#define S3C2440_NFCONT_RNBINT_EN (1<<9) -#define S3C2440_NFCONT_RN_FALLING (1<<8) -#define S3C2440_NFCONT_SPARE_ECCLOCK (1<<6) -#define S3C2440_NFCONT_MAIN_ECCLOCK (1<<5) -#define S3C2440_NFCONT_INITECC (1<<4) -#define S3C2440_NFCONT_nFCE (1<<1) -#define S3C2440_NFCONT_ENABLE (1<<0) - -#define S3C2440_NFSTAT_READY (1<<0) -#define S3C2440_NFSTAT_nCE (1<<1) -#define S3C2440_NFSTAT_RnB_CHANGE (1<<2) -#define S3C2440_NFSTAT_ILLEGAL_ACCESS (1<<3) - -#define S3C2412_NFCONF_NANDBOOT (1<<31) -#define S3C2412_NFCONF_ECCCLKCON (1<<30) -#define S3C2412_NFCONF_ECC_MLC (1<<24) -#define S3C2412_NFCONF_TACLS_MASK (7<<12) /* 1 extra bit of Tacls */ - -#define S3C2412_NFCONT_ECC4_DIRWR (1<<18) -#define S3C2412_NFCONT_LOCKTIGHT (1<<17) -#define S3C2412_NFCONT_SOFTLOCK (1<<16) -#define S3C2412_NFCONT_ECC4_ENCINT (1<<13) -#define S3C2412_NFCONT_ECC4_DECINT (1<<12) -#define S3C2412_NFCONT_MAIN_ECC_LOCK (1<<7) -#define S3C2412_NFCONT_INIT_MAIN_ECC (1<<5) -#define S3C2412_NFCONT_nFCE1 (1<<2) -#define S3C2412_NFCONT_nFCE0 (1<<1) - -#define S3C2412_NFSTAT_ECC_ENCDONE (1<<7) -#define S3C2412_NFSTAT_ECC_DECDONE (1<<6) -#define S3C2412_NFSTAT_ILLEGAL_ACCESS (1<<5) -#define S3C2412_NFSTAT_RnB_CHANGE (1<<4) -#define S3C2412_NFSTAT_nFCE1 (1<<3) -#define S3C2412_NFSTAT_nFCE0 (1<<2) -#define S3C2412_NFSTAT_Res1 (1<<1) -#define S3C2412_NFSTAT_READY (1<<0) - -#define S3C2412_NFECCERR_SERRDATA(x) (((x) >> 21) & 0xf) -#define S3C2412_NFECCERR_SERRBIT(x) (((x) >> 18) & 0x7) -#define S3C2412_NFECCERR_MERRDATA(x) (((x) >> 7) & 0x3ff) -#define S3C2412_NFECCERR_MERRBIT(x) (((x) >> 4) & 0x7) -#define S3C2412_NFECCERR_SPARE_ERR(x) (((x) >> 2) & 0x3) -#define S3C2412_NFECCERR_MAIN_ERR(x) (((x) >> 2) & 0x3) -#define S3C2412_NFECCERR_NONE (0) -#define S3C2412_NFECCERR_1BIT (1) -#define S3C2412_NFECCERR_MULTIBIT (2) -#define S3C2412_NFECCERR_ECCAREA (3) - - - -#endif /* __ASM_ARM_REGS_NAND */ - diff --git a/arch/arm/plat-samsung/include/plat/regs-onenand.h b/arch/arm/plat-samsung/include/plat/regs-onenand.h deleted file mode 100644 index 930ea8b88ed..00000000000 --- a/arch/arm/plat-samsung/include/plat/regs-onenand.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * linux/arch/arm/plat-s3c/include/plat/regs-onenand.h - * - * Copyright (C) 2008-2010 Samsung Electronics - * Kyungmin Park <kyungmin.park@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 __SAMSUNG_ONENAND_H__ -#define __SAMSUNG_ONENAND_H__ - -#include <mach/hardware.h> - -/* - * OneNAND Controller - */ -#define MEM_CFG_OFFSET 0x0000 -#define BURST_LEN_OFFSET 0x0010 -#define MEM_RESET_OFFSET 0x0020 -#define INT_ERR_STAT_OFFSET 0x0030 -#define INT_ERR_MASK_OFFSET 0x0040 -#define INT_ERR_ACK_OFFSET 0x0050 -#define ECC_ERR_STAT_OFFSET 0x0060 -#define MANUFACT_ID_OFFSET 0x0070 -#define DEVICE_ID_OFFSET 0x0080 -#define DATA_BUF_SIZE_OFFSET 0x0090 -#define BOOT_BUF_SIZE_OFFSET 0x00A0 -#define BUF_AMOUNT_OFFSET 0x00B0 -#define TECH_OFFSET 0x00C0 -#define FBA_WIDTH_OFFSET 0x00D0 -#define FPA_WIDTH_OFFSET 0x00E0 -#define FSA_WIDTH_OFFSET 0x00F0 -#define TRANS_SPARE_OFFSET 0x0140 -#define DBS_DFS_WIDTH_OFFSET 0x0160 -#define INT_PIN_ENABLE_OFFSET 0x01A0 -#define ACC_CLOCK_OFFSET 0x01C0 -#define FLASH_VER_ID_OFFSET 0x01F0 -#define FLASH_AUX_CNTRL_OFFSET 0x0300 /* s3c64xx only */ - -#define ONENAND_MEM_RESET_HOT 0x3 -#define ONENAND_MEM_RESET_COLD 0x2 -#define ONENAND_MEM_RESET_WARM 0x1 - -#define CACHE_OP_ERR (1 << 13) -#define RST_CMP (1 << 12) -#define RDY_ACT (1 << 11) -#define INT_ACT (1 << 10) -#define UNSUP_CMD (1 << 9) -#define LOCKED_BLK (1 << 8) -#define BLK_RW_CMP (1 << 7) -#define ERS_CMP (1 << 6) -#define PGM_CMP (1 << 5) -#define LOAD_CMP (1 << 4) -#define ERS_FAIL (1 << 3) -#define PGM_FAIL (1 << 2) -#define INT_TO (1 << 1) -#define LD_FAIL_ECC_ERR (1 << 0) - -#define TSRF (1 << 0) - -#endif diff --git a/arch/arm/plat-samsung/include/plat/regs-rtc.h b/arch/arm/plat-samsung/include/plat/regs-rtc.h deleted file mode 100644 index 30b7cc14cef..00000000000 --- a/arch/arm/plat-samsung/include/plat/regs-rtc.h +++ /dev/null @@ -1,68 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-rtc.h - * - * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk> - * http://www.simtec.co.uk/products/SWLINUX/ - * - * 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. - * - * S3C2410 Internal RTC register definition -*/ - -#ifndef __ASM_ARCH_REGS_RTC_H -#define __ASM_ARCH_REGS_RTC_H __FILE__ - -#define S3C2410_RTCREG(x) (x) -#define S3C2410_INTP S3C2410_RTCREG(0x30) -#define S3C2410_INTP_ALM (1 << 1) -#define S3C2410_INTP_TIC (1 << 0) - -#define S3C2410_RTCCON S3C2410_RTCREG(0x40) -#define S3C2410_RTCCON_RTCEN (1<<0) -#define S3C2410_RTCCON_CLKSEL (1<<1) -#define S3C2410_RTCCON_CNTSEL (1<<2) -#define S3C2410_RTCCON_CLKRST (1<<3) -#define S3C64XX_RTCCON_TICEN (1<<8) - -#define S3C64XX_RTCCON_TICMSK (0xF<<7) -#define S3C64XX_RTCCON_TICSHT (7) - -#define S3C2410_TICNT S3C2410_RTCREG(0x44) -#define S3C2410_TICNT_ENABLE (1<<7) - -#define S3C2410_RTCALM S3C2410_RTCREG(0x50) -#define S3C2410_RTCALM_ALMEN (1<<6) -#define S3C2410_RTCALM_YEAREN (1<<5) -#define S3C2410_RTCALM_MONEN (1<<4) -#define S3C2410_RTCALM_DAYEN (1<<3) -#define S3C2410_RTCALM_HOUREN (1<<2) -#define S3C2410_RTCALM_MINEN (1<<1) -#define S3C2410_RTCALM_SECEN (1<<0) - -#define S3C2410_RTCALM_ALL \ - S3C2410_RTCALM_ALMEN | S3C2410_RTCALM_YEAREN | S3C2410_RTCALM_MONEN |\ - S3C2410_RTCALM_DAYEN | S3C2410_RTCALM_HOUREN | S3C2410_RTCALM_MINEN |\ - S3C2410_RTCALM_SECEN - - -#define S3C2410_ALMSEC S3C2410_RTCREG(0x54) -#define S3C2410_ALMMIN S3C2410_RTCREG(0x58) -#define S3C2410_ALMHOUR S3C2410_RTCREG(0x5c) - -#define S3C2410_ALMDATE S3C2410_RTCREG(0x60) -#define S3C2410_ALMMON S3C2410_RTCREG(0x64) -#define S3C2410_ALMYEAR S3C2410_RTCREG(0x68) - -#define S3C2410_RTCRST S3C2410_RTCREG(0x6c) - -#define S3C2410_RTCSEC S3C2410_RTCREG(0x70) -#define S3C2410_RTCMIN S3C2410_RTCREG(0x74) -#define S3C2410_RTCHOUR S3C2410_RTCREG(0x78) -#define S3C2410_RTCDATE S3C2410_RTCREG(0x7c) -#define S3C2410_RTCDAY S3C2410_RTCREG(0x80) -#define S3C2410_RTCMON S3C2410_RTCREG(0x84) -#define S3C2410_RTCYEAR S3C2410_RTCREG(0x88) - - -#endif /* __ASM_ARCH_REGS_RTC_H */ diff --git a/arch/arm/plat-samsung/include/plat/regs-sdhci.h b/arch/arm/plat-samsung/include/plat/regs-sdhci.h deleted file mode 100644 index e34049ad44c..00000000000 --- a/arch/arm/plat-samsung/include/plat/regs-sdhci.h +++ /dev/null @@ -1,87 +0,0 @@ -/* linux/arch/arm/plat-s3c/include/plat/regs-sdhci.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * S3C Platform - SDHCI (HSMMC) 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_S3C_SDHCI_REGS_H -#define __PLAT_S3C_SDHCI_REGS_H __FILE__ - -#define S3C_SDHCI_CONTROL2 (0x80) -#define S3C_SDHCI_CONTROL3 (0x84) -#define S3C64XX_SDHCI_CONTROL4 (0x8C) - -#define S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR (1 << 31) -#define S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK (1 << 30) -#define S3C_SDHCI_CTRL2_CDINVRXD3 (1 << 29) -#define S3C_SDHCI_CTRL2_SLCARDOUT (1 << 28) - -#define S3C_SDHCI_CTRL2_FLTCLKSEL_MASK (0xf << 24) -#define S3C_SDHCI_CTRL2_FLTCLKSEL_SHIFT (24) -#define S3C_SDHCI_CTRL2_FLTCLKSEL(_x) ((_x) << 24) - -#define S3C_SDHCI_CTRL2_LVLDAT_MASK (0xff << 16) -#define S3C_SDHCI_CTRL2_LVLDAT_SHIFT (16) -#define S3C_SDHCI_CTRL2_LVLDAT(_x) ((_x) << 16) - -#define S3C_SDHCI_CTRL2_ENFBCLKTX (1 << 15) -#define S3C_SDHCI_CTRL2_ENFBCLKRX (1 << 14) -#define S3C_SDHCI_CTRL2_SDCDSEL (1 << 13) -#define S3C_SDHCI_CTRL2_SDSIGPC (1 << 12) -#define S3C_SDHCI_CTRL2_ENBUSYCHKTXSTART (1 << 11) - -#define S3C_SDHCI_CTRL2_DFCNT_MASK (0x3 << 9) -#define S3C_SDHCI_CTRL2_DFCNT_SHIFT (9) -#define S3C_SDHCI_CTRL2_DFCNT_NONE (0x0 << 9) -#define S3C_SDHCI_CTRL2_DFCNT_4SDCLK (0x1 << 9) -#define S3C_SDHCI_CTRL2_DFCNT_16SDCLK (0x2 << 9) -#define S3C_SDHCI_CTRL2_DFCNT_64SDCLK (0x3 << 9) - -#define S3C_SDHCI_CTRL2_ENCLKOUTHOLD (1 << 8) -#define S3C_SDHCI_CTRL2_RWAITMODE (1 << 7) -#define S3C_SDHCI_CTRL2_DISBUFRD (1 << 6) -#define S3C_SDHCI_CTRL2_SELBASECLK_MASK (0x3 << 4) -#define S3C_SDHCI_CTRL2_SELBASECLK_SHIFT (4) -#define S3C_SDHCI_CTRL2_PWRSYNC (1 << 3) -#define S3C_SDHCI_CTRL2_ENCLKOUTMSKCON (1 << 1) -#define S3C_SDHCI_CTRL2_HWINITFIN (1 << 0) - -#define S3C_SDHCI_CTRL3_FCSEL3 (1 << 31) -#define S3C_SDHCI_CTRL3_FCSEL2 (1 << 23) -#define S3C_SDHCI_CTRL3_FCSEL1 (1 << 15) -#define S3C_SDHCI_CTRL3_FCSEL0 (1 << 7) - -#define S3C_SDHCI_CTRL3_FIA3_MASK (0x7f << 24) -#define S3C_SDHCI_CTRL3_FIA3_SHIFT (24) -#define S3C_SDHCI_CTRL3_FIA3(_x) ((_x) << 24) - -#define S3C_SDHCI_CTRL3_FIA2_MASK (0x7f << 16) -#define S3C_SDHCI_CTRL3_FIA2_SHIFT (16) -#define S3C_SDHCI_CTRL3_FIA2(_x) ((_x) << 16) - -#define S3C_SDHCI_CTRL3_FIA1_MASK (0x7f << 8) -#define S3C_SDHCI_CTRL3_FIA1_SHIFT (8) -#define S3C_SDHCI_CTRL3_FIA1(_x) ((_x) << 8) - -#define S3C_SDHCI_CTRL3_FIA0_MASK (0x7f << 0) -#define S3C_SDHCI_CTRL3_FIA0_SHIFT (0) -#define S3C_SDHCI_CTRL3_FIA0(_x) ((_x) << 0) - -#define S3C64XX_SDHCI_CONTROL4_DRIVE_MASK (0x3 << 16) -#define S3C64XX_SDHCI_CONTROL4_DRIVE_SHIFT (16) -#define S3C64XX_SDHCI_CONTROL4_DRIVE_2mA (0x0 << 16) -#define S3C64XX_SDHCI_CONTROL4_DRIVE_4mA (0x1 << 16) -#define S3C64XX_SDHCI_CONTROL4_DRIVE_7mA (0x2 << 16) -#define S3C64XX_SDHCI_CONTROL4_DRIVE_9mA (0x3 << 16) - -#define S3C64XX_SDHCI_CONTROL4_BUSY (1) - -#endif /* __PLAT_S3C_SDHCI_REGS_H */ diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h deleted file mode 100644 index 788837e99cb..00000000000 --- a/arch/arm/plat-samsung/include/plat/regs-serial.h +++ /dev/null @@ -1,283 +0,0 @@ -/* arch/arm/plat-samsung/include/plat/regs-serial.h - * - * From linux/include/asm-arm/hardware/serial_s3c2410.h - * - * Internal header file for Samsung S3C2410 serial ports (UART0-2) - * - * Copyright (C) 2002 Shane Nay (shane@minirl.com) - * - * Additional defines, Copyright 2003 Simtec Electronics (linux@simtec.co.uk) - * - * Adapted from: - * - * Internal header file for MX1ADS serial ports (UART1 & 2) - * - * Copyright (C) 2002 Shane Nay (shane@minirl.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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef __ASM_ARM_REGS_SERIAL_H -#define __ASM_ARM_REGS_SERIAL_H - -#define S3C24XX_VA_UART0 (S3C_VA_UART) -#define S3C24XX_VA_UART1 (S3C_VA_UART + 0x4000 ) -#define S3C24XX_VA_UART2 (S3C_VA_UART + 0x8000 ) -#define S3C24XX_VA_UART3 (S3C_VA_UART + 0xC000 ) - -#define S3C2410_PA_UART0 (S3C24XX_PA_UART) -#define S3C2410_PA_UART1 (S3C24XX_PA_UART + 0x4000 ) -#define S3C2410_PA_UART2 (S3C24XX_PA_UART + 0x8000 ) -#define S3C2443_PA_UART3 (S3C24XX_PA_UART + 0xC000 ) - -#define S3C2410_URXH (0x24) -#define S3C2410_UTXH (0x20) -#define S3C2410_ULCON (0x00) -#define S3C2410_UCON (0x04) -#define S3C2410_UFCON (0x08) -#define S3C2410_UMCON (0x0C) -#define S3C2410_UBRDIV (0x28) -#define S3C2410_UTRSTAT (0x10) -#define S3C2410_UERSTAT (0x14) -#define S3C2410_UFSTAT (0x18) -#define S3C2410_UMSTAT (0x1C) - -#define S3C2410_LCON_CFGMASK ((0xF<<3)|(0x3)) - -#define S3C2410_LCON_CS5 (0x0) -#define S3C2410_LCON_CS6 (0x1) -#define S3C2410_LCON_CS7 (0x2) -#define S3C2410_LCON_CS8 (0x3) -#define S3C2410_LCON_CSMASK (0x3) - -#define S3C2410_LCON_PNONE (0x0) -#define S3C2410_LCON_PEVEN (0x5 << 3) -#define S3C2410_LCON_PODD (0x4 << 3) -#define S3C2410_LCON_PMASK (0x7 << 3) - -#define S3C2410_LCON_STOPB (1<<2) -#define S3C2410_LCON_IRM (1<<6) - -#define S3C2440_UCON_CLKMASK (3<<10) -#define S3C2440_UCON_PCLK (0<<10) -#define S3C2440_UCON_UCLK (1<<10) -#define S3C2440_UCON_PCLK2 (2<<10) -#define S3C2440_UCON_FCLK (3<<10) -#define S3C2443_UCON_EPLL (3<<10) - -#define S3C6400_UCON_CLKMASK (3<<10) -#define S3C6400_UCON_PCLK (0<<10) -#define S3C6400_UCON_PCLK2 (2<<10) -#define S3C6400_UCON_UCLK0 (1<<10) -#define S3C6400_UCON_UCLK1 (3<<10) - -#define S3C2440_UCON2_FCLK_EN (1<<15) -#define S3C2440_UCON0_DIVMASK (15 << 12) -#define S3C2440_UCON1_DIVMASK (15 << 12) -#define S3C2440_UCON2_DIVMASK (7 << 12) -#define S3C2440_UCON_DIVSHIFT (12) - -#define S3C2412_UCON_CLKMASK (3<<10) -#define S3C2412_UCON_UCLK (1<<10) -#define S3C2412_UCON_USYSCLK (3<<10) -#define S3C2412_UCON_PCLK (0<<10) -#define S3C2412_UCON_PCLK2 (2<<10) - -#define S3C2410_UCON_UCLK (1<<10) -#define S3C2410_UCON_SBREAK (1<<4) - -#define S3C2410_UCON_TXILEVEL (1<<9) -#define S3C2410_UCON_RXILEVEL (1<<8) -#define S3C2410_UCON_TXIRQMODE (1<<2) -#define S3C2410_UCON_RXIRQMODE (1<<0) -#define S3C2410_UCON_RXFIFO_TOI (1<<7) -#define S3C2443_UCON_RXERR_IRQEN (1<<6) -#define S3C2443_UCON_LOOPBACK (1<<5) - -#define S3C2410_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ - S3C2410_UCON_RXILEVEL | \ - S3C2410_UCON_TXIRQMODE | \ - S3C2410_UCON_RXIRQMODE | \ - S3C2410_UCON_RXFIFO_TOI) - -#define S3C2410_UFCON_FIFOMODE (1<<0) -#define S3C2410_UFCON_TXTRIG0 (0<<6) -#define S3C2410_UFCON_RXTRIG8 (1<<4) -#define S3C2410_UFCON_RXTRIG12 (2<<4) - -/* S3C2440 FIFO trigger levels */ -#define S3C2440_UFCON_RXTRIG1 (0<<4) -#define S3C2440_UFCON_RXTRIG8 (1<<4) -#define S3C2440_UFCON_RXTRIG16 (2<<4) -#define S3C2440_UFCON_RXTRIG32 (3<<4) - -#define S3C2440_UFCON_TXTRIG0 (0<<6) -#define S3C2440_UFCON_TXTRIG16 (1<<6) -#define S3C2440_UFCON_TXTRIG32 (2<<6) -#define S3C2440_UFCON_TXTRIG48 (3<<6) - -#define S3C2410_UFCON_RESETBOTH (3<<1) -#define S3C2410_UFCON_RESETTX (1<<2) -#define S3C2410_UFCON_RESETRX (1<<1) - -#define S3C2410_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ - S3C2410_UFCON_TXTRIG0 | \ - S3C2410_UFCON_RXTRIG8 ) - -#define S3C2410_UMCOM_AFC (1<<4) -#define S3C2410_UMCOM_RTS_LOW (1<<0) - -#define S3C2412_UMCON_AFC_63 (0<<5) /* same as s3c2443 */ -#define S3C2412_UMCON_AFC_56 (1<<5) -#define S3C2412_UMCON_AFC_48 (2<<5) -#define S3C2412_UMCON_AFC_40 (3<<5) -#define S3C2412_UMCON_AFC_32 (4<<5) -#define S3C2412_UMCON_AFC_24 (5<<5) -#define S3C2412_UMCON_AFC_16 (6<<5) -#define S3C2412_UMCON_AFC_8 (7<<5) - -#define S3C2410_UFSTAT_TXFULL (1<<9) -#define S3C2410_UFSTAT_RXFULL (1<<8) -#define S3C2410_UFSTAT_TXMASK (15<<4) -#define S3C2410_UFSTAT_TXSHIFT (4) -#define S3C2410_UFSTAT_RXMASK (15<<0) -#define S3C2410_UFSTAT_RXSHIFT (0) - -/* UFSTAT S3C24A0 */ -#define S3C24A0_UFSTAT_TXFULL (1 << 14) -#define S3C24A0_UFSTAT_RXFULL (1 << 6) -#define S3C24A0_UFSTAT_TXMASK (63 << 8) -#define S3C24A0_UFSTAT_TXSHIFT (8) -#define S3C24A0_UFSTAT_RXMASK (63) -#define S3C24A0_UFSTAT_RXSHIFT (0) - -/* UFSTAT S3C2443 same as S3C2440 */ -#define S3C2440_UFSTAT_TXFULL (1<<14) -#define S3C2440_UFSTAT_RXFULL (1<<6) -#define S3C2440_UFSTAT_TXSHIFT (8) -#define S3C2440_UFSTAT_RXSHIFT (0) -#define S3C2440_UFSTAT_TXMASK (63<<8) -#define S3C2440_UFSTAT_RXMASK (63) - -#define S3C2410_UTRSTAT_TXE (1<<2) -#define S3C2410_UTRSTAT_TXFE (1<<1) -#define S3C2410_UTRSTAT_RXDR (1<<0) - -#define S3C2410_UERSTAT_OVERRUN (1<<0) -#define S3C2410_UERSTAT_FRAME (1<<2) -#define S3C2410_UERSTAT_BREAK (1<<3) -#define S3C2443_UERSTAT_PARITY (1<<1) - -#define S3C2410_UERSTAT_ANY (S3C2410_UERSTAT_OVERRUN | \ - S3C2410_UERSTAT_FRAME | \ - S3C2410_UERSTAT_BREAK) - -#define S3C2410_UMSTAT_CTS (1<<0) -#define S3C2410_UMSTAT_DeltaCTS (1<<2) - -#define S3C2443_DIVSLOT (0x2C) - -/* S3C64XX interrupt registers. */ -#define S3C64XX_UINTP 0x30 -#define S3C64XX_UINTSP 0x34 -#define S3C64XX_UINTM 0x38 - -/* Following are specific to S5PV210 and S5P6442 */ -#define S5PV210_UCON_CLKMASK (1<<10) -#define S5PV210_UCON_PCLK (0<<10) -#define S5PV210_UCON_UCLK (1<<10) - -#define S5PV210_UFCON_TXTRIG0 (0<<8) -#define S5PV210_UFCON_TXTRIG4 (1<<8) -#define S5PV210_UFCON_TXTRIG8 (2<<8) -#define S5PV210_UFCON_TXTRIG16 (3<<8) -#define S5PV210_UFCON_TXTRIG32 (4<<8) -#define S5PV210_UFCON_TXTRIG64 (5<<8) -#define S5PV210_UFCON_TXTRIG128 (6<<8) -#define S5PV210_UFCON_TXTRIG256 (7<<8) - -#define S5PV210_UFCON_RXTRIG1 (0<<4) -#define S5PV210_UFCON_RXTRIG4 (1<<4) -#define S5PV210_UFCON_RXTRIG8 (2<<4) -#define S5PV210_UFCON_RXTRIG16 (3<<4) -#define S5PV210_UFCON_RXTRIG32 (4<<4) -#define S5PV210_UFCON_RXTRIG64 (5<<4) -#define S5PV210_UFCON_RXTRIG128 (6<<4) -#define S5PV210_UFCON_RXTRIG256 (7<<4) - -#define S5PV210_UFSTAT_TXFULL (1<<24) -#define S5PV210_UFSTAT_RXFULL (1<<8) -#define S5PV210_UFSTAT_TXMASK (255<<16) -#define S5PV210_UFSTAT_TXSHIFT (16) -#define S5PV210_UFSTAT_RXMASK (255<<0) -#define S5PV210_UFSTAT_RXSHIFT (0) - -#ifndef __ASSEMBLY__ - -/* struct s3c24xx_uart_clksrc - * - * this structure defines a named clock source that can be used for the - * uart, so that the best clock can be selected for the requested baud - * rate. - * - * min_baud and max_baud define the range of baud-rates this clock is - * acceptable for, if they are both zero, it is assumed any baud rate that - * can be generated from this clock will be used. - * - * divisor gives the divisor from the clock to the one seen by the uart -*/ - -struct s3c24xx_uart_clksrc { - const char *name; - unsigned int divisor; - unsigned int min_baud; - unsigned int max_baud; -}; - -/* configuration structure for per-machine configurations for the - * serial port - * - * the pointer is setup by the machine specific initialisation from the - * arch/arm/mach-s3c2410/ directory. -*/ - -struct s3c2410_uartcfg { - unsigned char hwport; /* hardware port number */ - unsigned char unused; - unsigned short flags; - upf_t uart_flags; /* default uart flags */ - - unsigned int has_fracval; - - unsigned long ucon; /* value of ucon for port */ - unsigned long ulcon; /* value of ulcon for port */ - unsigned long ufcon; /* value of ufcon for port */ - - struct s3c24xx_uart_clksrc *clocks; - unsigned int clocks_size; -}; - -/* s3c24xx_uart_devs - * - * this is exported from the core as we cannot use driver_register(), - * or platform_add_device() before the console_initcall() -*/ - -extern struct platform_device *s3c24xx_uart_devs[4]; - -#endif /* __ASSEMBLY__ */ - -#endif /* __ASM_ARM_REGS_SERIAL_H */ - diff --git a/arch/arm/plat-samsung/include/plat/regs-spi.h b/arch/arm/plat-samsung/include/plat/regs-spi.h new file mode 100644 index 00000000000..552fe7cfe28 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/regs-spi.h @@ -0,0 +1,48 @@ +/* arch/arm/plat-samsung/include/plat/regs-spi.h + * + * Copyright (c) 2004 Fetron GmbH + * + * 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. + * + * S3C2410 SPI register definition +*/ + +#ifndef __ASM_ARCH_REGS_SPI_H +#define __ASM_ARCH_REGS_SPI_H + +#define S3C2410_SPI1 (0x20) +#define S3C2412_SPI1 (0x100) + +#define S3C2410_SPCON (0x00) + +#define S3C2410_SPCON_SMOD_DMA (2 << 5) /* DMA mode */ +#define S3C2410_SPCON_SMOD_INT (1 << 5) /* interrupt mode */ +#define S3C2410_SPCON_SMOD_POLL (0 << 5) /* polling mode */ +#define S3C2410_SPCON_ENSCK (1 << 4) /* Enable SCK */ +#define S3C2410_SPCON_MSTR (1 << 3) /* Master:1, Slave:0 select */ +#define S3C2410_SPCON_CPOL_HIGH (1 << 2) /* Clock polarity select */ +#define S3C2410_SPCON_CPOL_LOW (0 << 2) /* Clock polarity select */ + +#define S3C2410_SPCON_CPHA_FMTB (1 << 1) /* Clock Phase Select */ +#define S3C2410_SPCON_CPHA_FMTA (0 << 1) /* Clock Phase Select */ + +#define S3C2410_SPSTA (0x04) + +#define S3C2410_SPSTA_DCOL (1 << 2) /* Data Collision Error */ +#define S3C2410_SPSTA_MULD (1 << 1) /* Multi Master Error */ +#define S3C2410_SPSTA_READY (1 << 0) /* Data Tx/Rx ready */ +#define S3C2412_SPSTA_READY_ORG (1 << 3) + +#define S3C2410_SPPIN (0x08) + +#define S3C2410_SPPIN_ENMUL (1 << 2) /* Multi Master Error detect */ +#define S3C2410_SPPIN_RESERVED (1 << 1) +#define S3C2410_SPPIN_KEEP (1 << 0) /* Master Out keep */ + +#define S3C2410_SPPRE (0x0C) +#define S3C2410_SPTDAT (0x10) +#define S3C2410_SPRDAT (0x14) + +#endif /* __ASM_ARCH_REGS_SPI_H */ diff --git a/arch/arm/plat-samsung/include/plat/regs-srom.h b/arch/arm/plat-samsung/include/plat/regs-srom.h new file mode 100644 index 00000000000..9b6729c81cd --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/regs-srom.h @@ -0,0 +1,54 @@ +/* linux/arch/arm/plat-samsung/include/plat/regs-srom.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P SROMC 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_SAMSUNG_REGS_SROM_H +#define __PLAT_SAMSUNG_REGS_SROM_H __FILE__ + +#include <mach/map.h> + +#define S5P_SROMREG(x) (S5P_VA_SROMC + (x)) + +#define S5P_SROM_BW S5P_SROMREG(0x0) +#define S5P_SROM_BC0 S5P_SROMREG(0x4) +#define S5P_SROM_BC1 S5P_SROMREG(0x8) +#define S5P_SROM_BC2 S5P_SROMREG(0xc) +#define S5P_SROM_BC3 S5P_SROMREG(0x10) +#define S5P_SROM_BC4 S5P_SROMREG(0x14) +#define S5P_SROM_BC5 S5P_SROMREG(0x18) + +/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */ + +#define S5P_SROM_BW__DATAWIDTH__SHIFT 0 +#define S5P_SROM_BW__ADDRMODE__SHIFT 1 +#define S5P_SROM_BW__WAITENABLE__SHIFT 2 +#define S5P_SROM_BW__BYTEENABLE__SHIFT 3 + +#define S5P_SROM_BW__CS_MASK 0xf + +#define S5P_SROM_BW__NCS0__SHIFT 0 +#define S5P_SROM_BW__NCS1__SHIFT 4 +#define S5P_SROM_BW__NCS2__SHIFT 8 +#define S5P_SROM_BW__NCS3__SHIFT 12 +#define S5P_SROM_BW__NCS4__SHIFT 16 +#define S5P_SROM_BW__NCS5__SHIFT 20 + +/* applies to same to BCS0 - BCS3 */ + +#define S5P_SROM_BCX__PMC__SHIFT 0 +#define S5P_SROM_BCX__TACP__SHIFT 4 +#define S5P_SROM_BCX__TCAH__SHIFT 8 +#define S5P_SROM_BCX__TCOH__SHIFT 12 +#define S5P_SROM_BCX__TACC__SHIFT 16 +#define S5P_SROM_BCX__TCOS__SHIFT 24 +#define S5P_SROM_BCX__TACS__SHIFT 28 + +#endif /* __PLAT_SAMSUNG_REGS_SROM_H */ diff --git a/arch/arm/plat-samsung/include/plat/regs-timer.h b/arch/arm/plat-samsung/include/plat/regs-timer.h deleted file mode 100644 index d097d92f8cc..00000000000 --- a/arch/arm/plat-samsung/include/plat/regs-timer.h +++ /dev/null @@ -1,124 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-timer.h - * - * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk> - * http://www.simtec.co.uk/products/SWLINUX/ - * - * 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. - * - * S3C2410 Timer configuration -*/ - -#ifndef __ASM_ARCH_REGS_TIMER_H -#define __ASM_ARCH_REGS_TIMER_H - -#define S3C_TIMERREG(x) (S3C_VA_TIMER + (x)) -#define S3C_TIMERREG2(tmr,reg) S3C_TIMERREG((reg)+0x0c+((tmr)*0x0c)) - -#define S3C2410_TCFG0 S3C_TIMERREG(0x00) -#define S3C2410_TCFG1 S3C_TIMERREG(0x04) -#define S3C2410_TCON S3C_TIMERREG(0x08) - -#define S3C64XX_TINT_CSTAT S3C_TIMERREG(0x44) - -#define S3C2410_TCFG_PRESCALER0_MASK (255<<0) -#define S3C2410_TCFG_PRESCALER1_MASK (255<<8) -#define S3C2410_TCFG_PRESCALER1_SHIFT (8) -#define S3C2410_TCFG_DEADZONE_MASK (255<<16) -#define S3C2410_TCFG_DEADZONE_SHIFT (16) - -#define S3C2410_TCFG1_MUX4_DIV2 (0<<16) -#define S3C2410_TCFG1_MUX4_DIV4 (1<<16) -#define S3C2410_TCFG1_MUX4_DIV8 (2<<16) -#define S3C2410_TCFG1_MUX4_DIV16 (3<<16) -#define S3C2410_TCFG1_MUX4_TCLK1 (4<<16) -#define S3C2410_TCFG1_MUX4_MASK (15<<16) -#define S3C2410_TCFG1_MUX4_SHIFT (16) - -#define S3C2410_TCFG1_MUX3_DIV2 (0<<12) -#define S3C2410_TCFG1_MUX3_DIV4 (1<<12) -#define S3C2410_TCFG1_MUX3_DIV8 (2<<12) -#define S3C2410_TCFG1_MUX3_DIV16 (3<<12) -#define S3C2410_TCFG1_MUX3_TCLK1 (4<<12) -#define S3C2410_TCFG1_MUX3_MASK (15<<12) - - -#define S3C2410_TCFG1_MUX2_DIV2 (0<<8) -#define S3C2410_TCFG1_MUX2_DIV4 (1<<8) -#define S3C2410_TCFG1_MUX2_DIV8 (2<<8) -#define S3C2410_TCFG1_MUX2_DIV16 (3<<8) -#define S3C2410_TCFG1_MUX2_TCLK1 (4<<8) -#define S3C2410_TCFG1_MUX2_MASK (15<<8) - - -#define S3C2410_TCFG1_MUX1_DIV2 (0<<4) -#define S3C2410_TCFG1_MUX1_DIV4 (1<<4) -#define S3C2410_TCFG1_MUX1_DIV8 (2<<4) -#define S3C2410_TCFG1_MUX1_DIV16 (3<<4) -#define S3C2410_TCFG1_MUX1_TCLK0 (4<<4) -#define S3C2410_TCFG1_MUX1_MASK (15<<4) - -#define S3C2410_TCFG1_MUX0_DIV2 (0<<0) -#define S3C2410_TCFG1_MUX0_DIV4 (1<<0) -#define S3C2410_TCFG1_MUX0_DIV8 (2<<0) -#define S3C2410_TCFG1_MUX0_DIV16 (3<<0) -#define S3C2410_TCFG1_MUX0_TCLK0 (4<<0) -#define S3C2410_TCFG1_MUX0_MASK (15<<0) - -#define S3C2410_TCFG1_MUX_DIV2 (0<<0) -#define S3C2410_TCFG1_MUX_DIV4 (1<<0) -#define S3C2410_TCFG1_MUX_DIV8 (2<<0) -#define S3C2410_TCFG1_MUX_DIV16 (3<<0) -#define S3C2410_TCFG1_MUX_TCLK (4<<0) -#define S3C2410_TCFG1_MUX_MASK (15<<0) - -#define S3C64XX_TCFG1_MUX_DIV1 (0<<0) -#define S3C64XX_TCFG1_MUX_DIV2 (1<<0) -#define S3C64XX_TCFG1_MUX_DIV4 (2<<0) -#define S3C64XX_TCFG1_MUX_DIV8 (3<<0) -#define S3C64XX_TCFG1_MUX_DIV16 (4<<0) -#define S3C64XX_TCFG1_MUX_TCLK (5<<0) /* 3 sets of TCLK */ -#define S3C64XX_TCFG1_MUX_MASK (15<<0) - -#define S3C2410_TCFG1_SHIFT(x) ((x) * 4) - -/* for each timer, we have an count buffer, an compare buffer and - * an observation buffer -*/ - -/* WARNING - timer 4 has no buffer reg, and it's observation is at +4 */ - -#define S3C2410_TCNTB(tmr) S3C_TIMERREG2(tmr, 0x00) -#define S3C2410_TCMPB(tmr) S3C_TIMERREG2(tmr, 0x04) -#define S3C2410_TCNTO(tmr) S3C_TIMERREG2(tmr, (((tmr) == 4) ? 0x04 : 0x08)) - -#define S3C2410_TCON_T4RELOAD (1<<22) -#define S3C2410_TCON_T4MANUALUPD (1<<21) -#define S3C2410_TCON_T4START (1<<20) - -#define S3C2410_TCON_T3RELOAD (1<<19) -#define S3C2410_TCON_T3INVERT (1<<18) -#define S3C2410_TCON_T3MANUALUPD (1<<17) -#define S3C2410_TCON_T3START (1<<16) - -#define S3C2410_TCON_T2RELOAD (1<<15) -#define S3C2410_TCON_T2INVERT (1<<14) -#define S3C2410_TCON_T2MANUALUPD (1<<13) -#define S3C2410_TCON_T2START (1<<12) - -#define S3C2410_TCON_T1RELOAD (1<<11) -#define S3C2410_TCON_T1INVERT (1<<10) -#define S3C2410_TCON_T1MANUALUPD (1<<9) -#define S3C2410_TCON_T1START (1<<8) - -#define S3C2410_TCON_T0DEADZONE (1<<4) -#define S3C2410_TCON_T0RELOAD (1<<3) -#define S3C2410_TCON_T0INVERT (1<<2) -#define S3C2410_TCON_T0MANUALUPD (1<<1) -#define S3C2410_TCON_T0START (1<<0) - -#endif /* __ASM_ARCH_REGS_TIMER_H */ - - - diff --git a/arch/arm/plat-samsung/include/plat/regs-udc.h b/arch/arm/plat-samsung/include/plat/regs-udc.h new file mode 100644 index 00000000000..4003d3dab4e --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/regs-udc.h @@ -0,0 +1,151 @@ +/* arch/arm/plat-samsung/include/plat/regs-udc.h + * + * Copyright (C) 2004 Herbert Poetzl <herbert@13thfloor.at> + * + * This include file 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. +*/ + +#ifndef __ASM_ARCH_REGS_UDC_H +#define __ASM_ARCH_REGS_UDC_H + +#define S3C2410_USBDREG(x) (x) + +#define S3C2410_UDC_FUNC_ADDR_REG S3C2410_USBDREG(0x0140) +#define S3C2410_UDC_PWR_REG S3C2410_USBDREG(0x0144) +#define S3C2410_UDC_EP_INT_REG S3C2410_USBDREG(0x0148) + +#define S3C2410_UDC_USB_INT_REG S3C2410_USBDREG(0x0158) +#define S3C2410_UDC_EP_INT_EN_REG S3C2410_USBDREG(0x015c) + +#define S3C2410_UDC_USB_INT_EN_REG S3C2410_USBDREG(0x016c) + +#define S3C2410_UDC_FRAME_NUM1_REG S3C2410_USBDREG(0x0170) +#define S3C2410_UDC_FRAME_NUM2_REG S3C2410_USBDREG(0x0174) + +#define S3C2410_UDC_EP0_FIFO_REG S3C2410_USBDREG(0x01c0) +#define S3C2410_UDC_EP1_FIFO_REG S3C2410_USBDREG(0x01c4) +#define S3C2410_UDC_EP2_FIFO_REG S3C2410_USBDREG(0x01c8) +#define S3C2410_UDC_EP3_FIFO_REG S3C2410_USBDREG(0x01cc) +#define S3C2410_UDC_EP4_FIFO_REG S3C2410_USBDREG(0x01d0) + +#define S3C2410_UDC_EP1_DMA_CON S3C2410_USBDREG(0x0200) +#define S3C2410_UDC_EP1_DMA_UNIT S3C2410_USBDREG(0x0204) +#define S3C2410_UDC_EP1_DMA_FIFO S3C2410_USBDREG(0x0208) +#define S3C2410_UDC_EP1_DMA_TTC_L S3C2410_USBDREG(0x020c) +#define S3C2410_UDC_EP1_DMA_TTC_M S3C2410_USBDREG(0x0210) +#define S3C2410_UDC_EP1_DMA_TTC_H S3C2410_USBDREG(0x0214) + +#define S3C2410_UDC_EP2_DMA_CON S3C2410_USBDREG(0x0218) +#define S3C2410_UDC_EP2_DMA_UNIT S3C2410_USBDREG(0x021c) +#define S3C2410_UDC_EP2_DMA_FIFO S3C2410_USBDREG(0x0220) +#define S3C2410_UDC_EP2_DMA_TTC_L S3C2410_USBDREG(0x0224) +#define S3C2410_UDC_EP2_DMA_TTC_M S3C2410_USBDREG(0x0228) +#define S3C2410_UDC_EP2_DMA_TTC_H S3C2410_USBDREG(0x022c) + +#define S3C2410_UDC_EP3_DMA_CON S3C2410_USBDREG(0x0240) +#define S3C2410_UDC_EP3_DMA_UNIT S3C2410_USBDREG(0x0244) +#define S3C2410_UDC_EP3_DMA_FIFO S3C2410_USBDREG(0x0248) +#define S3C2410_UDC_EP3_DMA_TTC_L S3C2410_USBDREG(0x024c) +#define S3C2410_UDC_EP3_DMA_TTC_M S3C2410_USBDREG(0x0250) +#define S3C2410_UDC_EP3_DMA_TTC_H S3C2410_USBDREG(0x0254) + +#define S3C2410_UDC_EP4_DMA_CON S3C2410_USBDREG(0x0258) +#define S3C2410_UDC_EP4_DMA_UNIT S3C2410_USBDREG(0x025c) +#define S3C2410_UDC_EP4_DMA_FIFO S3C2410_USBDREG(0x0260) +#define S3C2410_UDC_EP4_DMA_TTC_L S3C2410_USBDREG(0x0264) +#define S3C2410_UDC_EP4_DMA_TTC_M S3C2410_USBDREG(0x0268) +#define S3C2410_UDC_EP4_DMA_TTC_H S3C2410_USBDREG(0x026c) + +#define S3C2410_UDC_INDEX_REG S3C2410_USBDREG(0x0178) + +/* indexed registers */ + +#define S3C2410_UDC_MAXP_REG S3C2410_USBDREG(0x0180) + +#define S3C2410_UDC_EP0_CSR_REG S3C2410_USBDREG(0x0184) + +#define S3C2410_UDC_IN_CSR1_REG S3C2410_USBDREG(0x0184) +#define S3C2410_UDC_IN_CSR2_REG S3C2410_USBDREG(0x0188) + +#define S3C2410_UDC_OUT_CSR1_REG S3C2410_USBDREG(0x0190) +#define S3C2410_UDC_OUT_CSR2_REG S3C2410_USBDREG(0x0194) +#define S3C2410_UDC_OUT_FIFO_CNT1_REG S3C2410_USBDREG(0x0198) +#define S3C2410_UDC_OUT_FIFO_CNT2_REG S3C2410_USBDREG(0x019c) + +#define S3C2410_UDC_FUNCADDR_UPDATE (1 << 7) + +#define S3C2410_UDC_PWR_ISOUP (1 << 7) /* R/W */ +#define S3C2410_UDC_PWR_RESET (1 << 3) /* R */ +#define S3C2410_UDC_PWR_RESUME (1 << 2) /* R/W */ +#define S3C2410_UDC_PWR_SUSPEND (1 << 1) /* R */ +#define S3C2410_UDC_PWR_ENSUSPEND (1 << 0) /* R/W */ + +#define S3C2410_UDC_PWR_DEFAULT (0x00) + +#define S3C2410_UDC_INT_EP4 (1 << 4) /* R/W (clear only) */ +#define S3C2410_UDC_INT_EP3 (1 << 3) /* R/W (clear only) */ +#define S3C2410_UDC_INT_EP2 (1 << 2) /* R/W (clear only) */ +#define S3C2410_UDC_INT_EP1 (1 << 1) /* R/W (clear only) */ +#define S3C2410_UDC_INT_EP0 (1 << 0) /* R/W (clear only) */ + +#define S3C2410_UDC_USBINT_RESET (1 << 2) /* R/W (clear only) */ +#define S3C2410_UDC_USBINT_RESUME (1 << 1) /* R/W (clear only) */ +#define S3C2410_UDC_USBINT_SUSPEND (1 << 0) /* R/W (clear only) */ + +#define S3C2410_UDC_INTE_EP4 (1 << 4) /* R/W */ +#define S3C2410_UDC_INTE_EP3 (1 << 3) /* R/W */ +#define S3C2410_UDC_INTE_EP2 (1 << 2) /* R/W */ +#define S3C2410_UDC_INTE_EP1 (1 << 1) /* R/W */ +#define S3C2410_UDC_INTE_EP0 (1 << 0) /* R/W */ + +#define S3C2410_UDC_USBINTE_RESET (1 << 2) /* R/W */ +#define S3C2410_UDC_USBINTE_SUSPEND (1 << 0) /* R/W */ + +#define S3C2410_UDC_INDEX_EP0 (0x00) +#define S3C2410_UDC_INDEX_EP1 (0x01) +#define S3C2410_UDC_INDEX_EP2 (0x02) +#define S3C2410_UDC_INDEX_EP3 (0x03) +#define S3C2410_UDC_INDEX_EP4 (0x04) + +#define S3C2410_UDC_ICSR1_CLRDT (1 << 6) /* R/W */ +#define S3C2410_UDC_ICSR1_SENTSTL (1 << 5) /* R/W (clear only) */ +#define S3C2410_UDC_ICSR1_SENDSTL (1 << 4) /* R/W */ +#define S3C2410_UDC_ICSR1_FFLUSH (1 << 3) /* W (set only) */ +#define S3C2410_UDC_ICSR1_UNDRUN (1 << 2) /* R/W (clear only) */ +#define S3C2410_UDC_ICSR1_PKTRDY (1 << 0) /* R/W (set only) */ + +#define S3C2410_UDC_ICSR2_AUTOSET (1 << 7) /* R/W */ +#define S3C2410_UDC_ICSR2_ISO (1 << 6) /* R/W */ +#define S3C2410_UDC_ICSR2_MODEIN (1 << 5) /* R/W */ +#define S3C2410_UDC_ICSR2_DMAIEN (1 << 4) /* R/W */ + +#define S3C2410_UDC_OCSR1_CLRDT (1 << 7) /* R/W */ +#define S3C2410_UDC_OCSR1_SENTSTL (1 << 6) /* R/W (clear only) */ +#define S3C2410_UDC_OCSR1_SENDSTL (1 << 5) /* R/W */ +#define S3C2410_UDC_OCSR1_FFLUSH (1 << 4) /* R/W */ +#define S3C2410_UDC_OCSR1_DERROR (1 << 3) /* R */ +#define S3C2410_UDC_OCSR1_OVRRUN (1 << 2) /* R/W (clear only) */ +#define S3C2410_UDC_OCSR1_PKTRDY (1 << 0) /* R/W (clear only) */ + +#define S3C2410_UDC_OCSR2_AUTOCLR (1 << 7) /* R/W */ +#define S3C2410_UDC_OCSR2_ISO (1 << 6) /* R/W */ +#define S3C2410_UDC_OCSR2_DMAIEN (1 << 5) /* R/W */ + +#define S3C2410_UDC_EP0_CSR_OPKRDY (1 << 0) +#define S3C2410_UDC_EP0_CSR_IPKRDY (1 << 1) +#define S3C2410_UDC_EP0_CSR_SENTSTL (1 << 2) +#define S3C2410_UDC_EP0_CSR_DE (1 << 3) +#define S3C2410_UDC_EP0_CSR_SE (1 << 4) +#define S3C2410_UDC_EP0_CSR_SENDSTL (1 << 5) +#define S3C2410_UDC_EP0_CSR_SOPKTRDY (1 << 6) +#define S3C2410_UDC_EP0_CSR_SSE (1 << 7) + +#define S3C2410_UDC_MAXP_8 (1 << 0) +#define S3C2410_UDC_MAXP_16 (1 << 1) +#define S3C2410_UDC_MAXP_32 (1 << 2) +#define S3C2410_UDC_MAXP_64 (1 << 3) + +#endif diff --git a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h index a111ad87183..fcf27966206 100644 --- a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h +++ b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h @@ -25,8 +25,9 @@ #define S3C_HSOTG_PHYREG(x) ((x) + S3C_VA_USB_HSPHY) #define S3C_PHYPWR S3C_HSOTG_PHYREG(0x00) -#define SRC_PHYPWR_OTG_DISABLE (1 << 4) -#define SRC_PHYPWR_ANALOG_POWERDOWN (1 << 3) +#define S3C_PHYPWR_NORMAL_MASK (0x19 << 0) +#define S3C_PHYPWR_OTG_DISABLE (1 << 4) +#define S3C_PHYPWR_ANALOG_POWERDOWN (1 << 3) #define SRC_PHYPWR_FORCE_SUSPEND (1 << 1) #define S3C_PHYCLK S3C_HSOTG_PHYREG(0x04) @@ -42,7 +43,7 @@ #define S3C_RSTCON S3C_HSOTG_PHYREG(0x08) #define S3C_RSTCON_PHYCLK (1 << 2) -#define S3C_RSTCON_HCLK (1 << 2) +#define S3C_RSTCON_HCLK (1 << 1) #define S3C_RSTCON_PHY (1 << 0) #define S3C_PHYTUNE S3C_HSOTG_PHYREG(0x20) diff --git a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h deleted file mode 100644 index dc90f5ede88..00000000000 --- a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h +++ /dev/null @@ -1,379 +0,0 @@ -/* arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * S3C - USB2.0 Highspeed/OtG device block registers - * - * 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_S3C64XX_REGS_USB_HSOTG_H -#define __PLAT_S3C64XX_REGS_USB_HSOTG_H __FILE__ - -#define S3C_HSOTG_REG(x) (x) - -#define S3C_GOTGCTL S3C_HSOTG_REG(0x000) -#define S3C_GOTGCTL_BSESVLD (1 << 19) -#define S3C_GOTGCTL_ASESVLD (1 << 18) -#define S3C_GOTGCTL_DBNC_SHORT (1 << 17) -#define S3C_GOTGCTL_CONID_B (1 << 16) -#define S3C_GOTGCTL_DEVHNPEN (1 << 11) -#define S3C_GOTGCTL_HSSETHNPEN (1 << 10) -#define S3C_GOTGCTL_HNPREQ (1 << 9) -#define S3C_GOTGCTL_HSTNEGSCS (1 << 8) -#define S3C_GOTGCTL_SESREQ (1 << 1) -#define S3C_GOTGCTL_SESREQSCS (1 << 0) - -#define S3C_GOTGINT S3C_HSOTG_REG(0x004) -#define S3C_GOTGINT_DbnceDone (1 << 19) -#define S3C_GOTGINT_ADevTOUTChg (1 << 18) -#define S3C_GOTGINT_HstNegDet (1 << 17) -#define S3C_GOTGINT_HstnegSucStsChng (1 << 9) -#define S3C_GOTGINT_SesReqSucStsChng (1 << 8) -#define S3C_GOTGINT_SesEndDet (1 << 2) - -#define S3C_GAHBCFG S3C_HSOTG_REG(0x008) -#define S3C_GAHBCFG_PTxFEmpLvl (1 << 8) -#define S3C_GAHBCFG_NPTxFEmpLvl (1 << 7) -#define S3C_GAHBCFG_DMAEn (1 << 5) -#define S3C_GAHBCFG_HBstLen_MASK (0xf << 1) -#define S3C_GAHBCFG_HBstLen_SHIFT (1) -#define S3C_GAHBCFG_HBstLen_Single (0x0 << 1) -#define S3C_GAHBCFG_HBstLen_Incr (0x1 << 1) -#define S3C_GAHBCFG_HBstLen_Incr4 (0x3 << 1) -#define S3C_GAHBCFG_HBstLen_Incr8 (0x5 << 1) -#define S3C_GAHBCFG_HBstLen_Incr16 (0x7 << 1) -#define S3C_GAHBCFG_GlblIntrEn (1 << 0) - -#define S3C_GUSBCFG S3C_HSOTG_REG(0x00C) -#define S3C_GUSBCFG_PHYLPClkSel (1 << 15) -#define S3C_GUSBCFG_HNPCap (1 << 9) -#define S3C_GUSBCFG_SRPCap (1 << 8) -#define S3C_GUSBCFG_PHYIf16 (1 << 3) -#define S3C_GUSBCFG_TOutCal_MASK (0x7 << 0) -#define S3C_GUSBCFG_TOutCal_SHIFT (0) -#define S3C_GUSBCFG_TOutCal_LIMIT (0x7) -#define S3C_GUSBCFG_TOutCal(_x) ((_x) << 0) - -#define S3C_GRSTCTL S3C_HSOTG_REG(0x010) - -#define S3C_GRSTCTL_AHBIdle (1 << 31) -#define S3C_GRSTCTL_DMAReq (1 << 30) -#define S3C_GRSTCTL_TxFNum_MASK (0x1f << 6) -#define S3C_GRSTCTL_TxFNum_SHIFT (6) -#define S3C_GRSTCTL_TxFNum_LIMIT (0x1f) -#define S3C_GRSTCTL_TxFNum(_x) ((_x) << 6) -#define S3C_GRSTCTL_TxFFlsh (1 << 5) -#define S3C_GRSTCTL_RxFFlsh (1 << 4) -#define S3C_GRSTCTL_INTknQFlsh (1 << 3) -#define S3C_GRSTCTL_FrmCntrRst (1 << 2) -#define S3C_GRSTCTL_HSftRst (1 << 1) -#define S3C_GRSTCTL_CSftRst (1 << 0) - -#define S3C_GINTSTS S3C_HSOTG_REG(0x014) -#define S3C_GINTMSK S3C_HSOTG_REG(0x018) - -#define S3C_GINTSTS_WkUpInt (1 << 31) -#define S3C_GINTSTS_SessReqInt (1 << 30) -#define S3C_GINTSTS_DisconnInt (1 << 29) -#define S3C_GINTSTS_ConIDStsChng (1 << 28) -#define S3C_GINTSTS_PTxFEmp (1 << 26) -#define S3C_GINTSTS_HChInt (1 << 25) -#define S3C_GINTSTS_PrtInt (1 << 24) -#define S3C_GINTSTS_FetSusp (1 << 22) -#define S3C_GINTSTS_incompIP (1 << 21) -#define S3C_GINTSTS_IncomplSOIN (1 << 20) -#define S3C_GINTSTS_OEPInt (1 << 19) -#define S3C_GINTSTS_IEPInt (1 << 18) -#define S3C_GINTSTS_EPMis (1 << 17) -#define S3C_GINTSTS_EOPF (1 << 15) -#define S3C_GINTSTS_ISOutDrop (1 << 14) -#define S3C_GINTSTS_EnumDone (1 << 13) -#define S3C_GINTSTS_USBRst (1 << 12) -#define S3C_GINTSTS_USBSusp (1 << 11) -#define S3C_GINTSTS_ErlySusp (1 << 10) -#define S3C_GINTSTS_GOUTNakEff (1 << 7) -#define S3C_GINTSTS_GINNakEff (1 << 6) -#define S3C_GINTSTS_NPTxFEmp (1 << 5) -#define S3C_GINTSTS_RxFLvl (1 << 4) -#define S3C_GINTSTS_SOF (1 << 3) -#define S3C_GINTSTS_OTGInt (1 << 2) -#define S3C_GINTSTS_ModeMis (1 << 1) -#define S3C_GINTSTS_CurMod_Host (1 << 0) - -#define S3C_GRXSTSR S3C_HSOTG_REG(0x01C) -#define S3C_GRXSTSP S3C_HSOTG_REG(0x020) - -#define S3C_GRXSTS_FN_MASK (0x7f << 25) -#define S3C_GRXSTS_FN_SHIFT (25) - -#define S3C_GRXSTS_PktSts_MASK (0xf << 17) -#define S3C_GRXSTS_PktSts_SHIFT (17) -#define S3C_GRXSTS_PktSts_GlobalOutNAK (0x1 << 17) -#define S3C_GRXSTS_PktSts_OutRX (0x2 << 17) -#define S3C_GRXSTS_PktSts_OutDone (0x3 << 17) -#define S3C_GRXSTS_PktSts_SetupDone (0x4 << 17) -#define S3C_GRXSTS_PktSts_SetupRX (0x6 << 17) - -#define S3C_GRXSTS_DPID_MASK (0x3 << 15) -#define S3C_GRXSTS_DPID_SHIFT (15) -#define S3C_GRXSTS_ByteCnt_MASK (0x7ff << 4) -#define S3C_GRXSTS_ByteCnt_SHIFT (4) -#define S3C_GRXSTS_EPNum_MASK (0xf << 0) -#define S3C_GRXSTS_EPNum_SHIFT (0) - -#define S3C_GRXFSIZ S3C_HSOTG_REG(0x024) - -#define S3C_GNPTXFSIZ S3C_HSOTG_REG(0x028) - -#define S3C_GNPTXFSIZ_NPTxFDep_MASK (0xffff << 16) -#define S3C_GNPTXFSIZ_NPTxFDep_SHIFT (16) -#define S3C_GNPTXFSIZ_NPTxFDep_LIMIT (0xffff) -#define S3C_GNPTXFSIZ_NPTxFDep(_x) ((_x) << 16) -#define S3C_GNPTXFSIZ_NPTxFStAddr_MASK (0xffff << 0) -#define S3C_GNPTXFSIZ_NPTxFStAddr_SHIFT (0) -#define S3C_GNPTXFSIZ_NPTxFStAddr_LIMIT (0xffff) -#define S3C_GNPTXFSIZ_NPTxFStAddr(_x) ((_x) << 0) - -#define S3C_GNPTXSTS S3C_HSOTG_REG(0x02C) - -#define S3C_GNPTXSTS_NPtxQTop_MASK (0x7f << 24) -#define S3C_GNPTXSTS_NPtxQTop_SHIFT (24) - -#define S3C_GNPTXSTS_NPTxQSpcAvail_MASK (0xff << 16) -#define S3C_GNPTXSTS_NPTxQSpcAvail_SHIFT (16) -#define S3C_GNPTXSTS_NPTxQSpcAvail_GET(_v) (((_v) >> 16) & 0xff) - -#define S3C_GNPTXSTS_NPTxFSpcAvail_MASK (0xffff << 0) -#define S3C_GNPTXSTS_NPTxFSpcAvail_SHIFT (0) -#define S3C_GNPTXSTS_NPTxFSpcAvail_GET(_v) (((_v) >> 0) & 0xffff) - - -#define S3C_HPTXFSIZ S3C_HSOTG_REG(0x100) - -#define S3C_DPTXFSIZn(_a) S3C_HSOTG_REG(0x104 + (((_a) - 1) * 4)) - -#define S3C_DPTXFSIZn_DPTxFSize_MASK (0xffff << 16) -#define S3C_DPTXFSIZn_DPTxFSize_SHIFT (16) -#define S3C_DPTXFSIZn_DPTxFSize_GET(_v) (((_v) >> 16) & 0xffff) -#define S3C_DPTXFSIZn_DPTxFSize_LIMIT (0xffff) -#define S3C_DPTXFSIZn_DPTxFSize(_x) ((_x) << 16) - -#define S3C_DPTXFSIZn_DPTxFStAddr_MASK (0xffff << 0) -#define S3C_DPTXFSIZn_DPTxFStAddr_SHIFT (0) - -/* Device mode registers */ -#define S3C_DCFG S3C_HSOTG_REG(0x800) - -#define S3C_DCFG_EPMisCnt_MASK (0x1f << 18) -#define S3C_DCFG_EPMisCnt_SHIFT (18) -#define S3C_DCFG_EPMisCnt_LIMIT (0x1f) -#define S3C_DCFG_EPMisCnt(_x) ((_x) << 18) - -#define S3C_DCFG_PerFrInt_MASK (0x3 << 11) -#define S3C_DCFG_PerFrInt_SHIFT (11) -#define S3C_DCFG_PerFrInt_LIMIT (0x3) -#define S3C_DCFG_PerFrInt(_x) ((_x) << 11) - -#define S3C_DCFG_DevAddr_MASK (0x7f << 4) -#define S3C_DCFG_DevAddr_SHIFT (4) -#define S3C_DCFG_DevAddr_LIMIT (0x7f) -#define S3C_DCFG_DevAddr(_x) ((_x) << 4) - -#define S3C_DCFG_NZStsOUTHShk (1 << 2) - -#define S3C_DCFG_DevSpd_MASK (0x3 << 0) -#define S3C_DCFG_DevSpd_SHIFT (0) -#define S3C_DCFG_DevSpd_HS (0x0 << 0) -#define S3C_DCFG_DevSpd_FS (0x1 << 0) -#define S3C_DCFG_DevSpd_LS (0x2 << 0) -#define S3C_DCFG_DevSpd_FS48 (0x3 << 0) - -#define S3C_DCTL S3C_HSOTG_REG(0x804) - -#define S3C_DCTL_PWROnPrgDone (1 << 11) -#define S3C_DCTL_CGOUTNak (1 << 10) -#define S3C_DCTL_SGOUTNak (1 << 9) -#define S3C_DCTL_CGNPInNAK (1 << 8) -#define S3C_DCTL_SGNPInNAK (1 << 7) -#define S3C_DCTL_TstCtl_MASK (0x7 << 4) -#define S3C_DCTL_TstCtl_SHIFT (4) -#define S3C_DCTL_GOUTNakSts (1 << 3) -#define S3C_DCTL_GNPINNakSts (1 << 2) -#define S3C_DCTL_SftDiscon (1 << 1) -#define S3C_DCTL_RmtWkUpSig (1 << 0) - -#define S3C_DSTS S3C_HSOTG_REG(0x808) - -#define S3C_DSTS_SOFFN_MASK (0x3fff << 8) -#define S3C_DSTS_SOFFN_SHIFT (8) -#define S3C_DSTS_SOFFN_LIMIT (0x3fff) -#define S3C_DSTS_SOFFN(_x) ((_x) << 8) -#define S3C_DSTS_ErraticErr (1 << 3) -#define S3C_DSTS_EnumSpd_MASK (0x3 << 1) -#define S3C_DSTS_EnumSpd_SHIFT (1) -#define S3C_DSTS_EnumSpd_HS (0x0 << 1) -#define S3C_DSTS_EnumSpd_FS (0x1 << 1) -#define S3C_DSTS_EnumSpd_LS (0x2 << 1) -#define S3C_DSTS_EnumSpd_FS48 (0x3 << 1) - -#define S3C_DSTS_SuspSts (1 << 0) - -#define S3C_DIEPMSK S3C_HSOTG_REG(0x810) - -#define S3C_DIEPMSK_TxFIFOEmpty (1 << 7) -#define S3C_DIEPMSK_INEPNakEffMsk (1 << 6) -#define S3C_DIEPMSK_INTknEPMisMsk (1 << 5) -#define S3C_DIEPMSK_INTknTXFEmpMsk (1 << 4) -#define S3C_DIEPMSK_TimeOUTMsk (1 << 3) -#define S3C_DIEPMSK_AHBErrMsk (1 << 2) -#define S3C_DIEPMSK_EPDisbldMsk (1 << 1) -#define S3C_DIEPMSK_XferComplMsk (1 << 0) - -#define S3C_DOEPMSK S3C_HSOTG_REG(0x814) - -#define S3C_DOEPMSK_Back2BackSetup (1 << 6) -#define S3C_DOEPMSK_OUTTknEPdisMsk (1 << 4) -#define S3C_DOEPMSK_SetupMsk (1 << 3) -#define S3C_DOEPMSK_AHBErrMsk (1 << 2) -#define S3C_DOEPMSK_EPDisbldMsk (1 << 1) -#define S3C_DOEPMSK_XferComplMsk (1 << 0) - -#define S3C_DAINT S3C_HSOTG_REG(0x818) -#define S3C_DAINTMSK S3C_HSOTG_REG(0x81C) - -#define S3C_DAINT_OutEP_SHIFT (16) -#define S3C_DAINT_OutEP(x) (1 << ((x) + 16)) -#define S3C_DAINT_InEP(x) (1 << (x)) - -#define S3C_DTKNQR1 S3C_HSOTG_REG(0x820) -#define S3C_DTKNQR2 S3C_HSOTG_REG(0x824) -#define S3C_DTKNQR3 S3C_HSOTG_REG(0x830) -#define S3C_DTKNQR4 S3C_HSOTG_REG(0x834) - -#define S3C_DVBUSDIS S3C_HSOTG_REG(0x828) -#define S3C_DVBUSPULSE S3C_HSOTG_REG(0x82C) - -#define S3C_DIEPCTL0 S3C_HSOTG_REG(0x900) -#define S3C_DOEPCTL0 S3C_HSOTG_REG(0xB00) -#define S3C_DIEPCTL(_a) S3C_HSOTG_REG(0x900 + ((_a) * 0x20)) -#define S3C_DOEPCTL(_a) S3C_HSOTG_REG(0xB00 + ((_a) * 0x20)) - -/* EP0 specialness: - * bits[29..28] - reserved (no SetD0PID, SetD1PID) - * bits[25..22] - should always be zero, this isn't a periodic endpoint - * bits[10..0] - MPS setting differenct for EP0 -*/ -#define S3C_D0EPCTL_MPS_MASK (0x3 << 0) -#define S3C_D0EPCTL_MPS_SHIFT (0) -#define S3C_D0EPCTL_MPS_64 (0x0 << 0) -#define S3C_D0EPCTL_MPS_32 (0x1 << 0) -#define S3C_D0EPCTL_MPS_16 (0x2 << 0) -#define S3C_D0EPCTL_MPS_8 (0x3 << 0) - -#define S3C_DxEPCTL_EPEna (1 << 31) -#define S3C_DxEPCTL_EPDis (1 << 30) -#define S3C_DxEPCTL_SetD1PID (1 << 29) -#define S3C_DxEPCTL_SetOddFr (1 << 29) -#define S3C_DxEPCTL_SetD0PID (1 << 28) -#define S3C_DxEPCTL_SetEvenFr (1 << 28) -#define S3C_DxEPCTL_SNAK (1 << 27) -#define S3C_DxEPCTL_CNAK (1 << 26) -#define S3C_DxEPCTL_TxFNum_MASK (0xf << 22) -#define S3C_DxEPCTL_TxFNum_SHIFT (22) -#define S3C_DxEPCTL_TxFNum_LIMIT (0xf) -#define S3C_DxEPCTL_TxFNum(_x) ((_x) << 22) - -#define S3C_DxEPCTL_Stall (1 << 21) -#define S3C_DxEPCTL_Snp (1 << 20) -#define S3C_DxEPCTL_EPType_MASK (0x3 << 18) -#define S3C_DxEPCTL_EPType_SHIFT (18) -#define S3C_DxEPCTL_EPType_Control (0x0 << 18) -#define S3C_DxEPCTL_EPType_Iso (0x1 << 18) -#define S3C_DxEPCTL_EPType_Bulk (0x2 << 18) -#define S3C_DxEPCTL_EPType_Intterupt (0x3 << 18) - -#define S3C_DxEPCTL_NAKsts (1 << 17) -#define S3C_DxEPCTL_DPID (1 << 16) -#define S3C_DxEPCTL_EOFrNum (1 << 16) -#define S3C_DxEPCTL_USBActEp (1 << 15) -#define S3C_DxEPCTL_NextEp_MASK (0xf << 11) -#define S3C_DxEPCTL_NextEp_SHIFT (11) -#define S3C_DxEPCTL_NextEp_LIMIT (0xf) -#define S3C_DxEPCTL_NextEp(_x) ((_x) << 11) - -#define S3C_DxEPCTL_MPS_MASK (0x7ff << 0) -#define S3C_DxEPCTL_MPS_SHIFT (0) -#define S3C_DxEPCTL_MPS_LIMIT (0x7ff) -#define S3C_DxEPCTL_MPS(_x) ((_x) << 0) - -#define S3C_DIEPINT(_a) S3C_HSOTG_REG(0x908 + ((_a) * 0x20)) -#define S3C_DOEPINT(_a) S3C_HSOTG_REG(0xB08 + ((_a) * 0x20)) - -#define S3C_DxEPINT_INEPNakEff (1 << 6) -#define S3C_DxEPINT_Back2BackSetup (1 << 6) -#define S3C_DxEPINT_INTknEPMis (1 << 5) -#define S3C_DxEPINT_INTknTXFEmp (1 << 4) -#define S3C_DxEPINT_OUTTknEPdis (1 << 4) -#define S3C_DxEPINT_Timeout (1 << 3) -#define S3C_DxEPINT_Setup (1 << 3) -#define S3C_DxEPINT_AHBErr (1 << 2) -#define S3C_DxEPINT_EPDisbld (1 << 1) -#define S3C_DxEPINT_XferCompl (1 << 0) - -#define S3C_DIEPTSIZ0 S3C_HSOTG_REG(0x910) - -#define S3C_DIEPTSIZ0_PktCnt_MASK (0x3 << 19) -#define S3C_DIEPTSIZ0_PktCnt_SHIFT (19) -#define S3C_DIEPTSIZ0_PktCnt_LIMIT (0x3) -#define S3C_DIEPTSIZ0_PktCnt(_x) ((_x) << 19) - -#define S3C_DIEPTSIZ0_XferSize_MASK (0x7f << 0) -#define S3C_DIEPTSIZ0_XferSize_SHIFT (0) -#define S3C_DIEPTSIZ0_XferSize_LIMIT (0x7f) -#define S3C_DIEPTSIZ0_XferSize(_x) ((_x) << 0) - - -#define DOEPTSIZ0 S3C_HSOTG_REG(0xB10) -#define S3C_DOEPTSIZ0_SUPCnt_MASK (0x3 << 29) -#define S3C_DOEPTSIZ0_SUPCnt_SHIFT (29) -#define S3C_DOEPTSIZ0_SUPCnt_LIMIT (0x3) -#define S3C_DOEPTSIZ0_SUPCnt(_x) ((_x) << 29) - -#define S3C_DOEPTSIZ0_PktCnt (1 << 19) -#define S3C_DOEPTSIZ0_XferSize_MASK (0x7f << 0) -#define S3C_DOEPTSIZ0_XferSize_SHIFT (0) - -#define S3C_DIEPTSIZ(_a) S3C_HSOTG_REG(0x910 + ((_a) * 0x20)) -#define S3C_DOEPTSIZ(_a) S3C_HSOTG_REG(0xB10 + ((_a) * 0x20)) - -#define S3C_DxEPTSIZ_MC_MASK (0x3 << 29) -#define S3C_DxEPTSIZ_MC_SHIFT (29) -#define S3C_DxEPTSIZ_MC_LIMIT (0x3) -#define S3C_DxEPTSIZ_MC(_x) ((_x) << 29) - -#define S3C_DxEPTSIZ_PktCnt_MASK (0x3ff << 19) -#define S3C_DxEPTSIZ_PktCnt_SHIFT (19) -#define S3C_DxEPTSIZ_PktCnt_GET(_v) (((_v) >> 19) & 0x3ff) -#define S3C_DxEPTSIZ_PktCnt_LIMIT (0x3ff) -#define S3C_DxEPTSIZ_PktCnt(_x) ((_x) << 19) - -#define S3C_DxEPTSIZ_XferSize_MASK (0x7ffff << 0) -#define S3C_DxEPTSIZ_XferSize_SHIFT (0) -#define S3C_DxEPTSIZ_XferSize_GET(_v) (((_v) >> 0) & 0x7ffff) -#define S3C_DxEPTSIZ_XferSize_LIMIT (0x7ffff) -#define S3C_DxEPTSIZ_XferSize(_x) ((_x) << 0) - - -#define S3C_DIEPDMA(_a) S3C_HSOTG_REG(0x914 + ((_a) * 0x20)) -#define S3C_DOEPDMA(_a) S3C_HSOTG_REG(0xB14 + ((_a) * 0x20)) -#define S3C_DTXFSTS(_a) S3C_HSOTG_REG(0x918 + ((_a) * 0x20)) - -#define S3C_EPFIFO(_a) S3C_HSOTG_REG(0x1000 + ((_a) * 0x1000)) - -#endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_H */ diff --git a/arch/arm/plat-samsung/include/plat/regs-watchdog.h b/arch/arm/plat-samsung/include/plat/regs-watchdog.h deleted file mode 100644 index 4938492470f..00000000000 --- a/arch/arm/plat-samsung/include/plat/regs-watchdog.h +++ /dev/null @@ -1,41 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-watchdog.h - * - * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk> - * http://www.simtec.co.uk/products/SWLINUX/ - * - * 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. - * - * S3C2410 Watchdog timer control -*/ - - -#ifndef __ASM_ARCH_REGS_WATCHDOG_H -#define __ASM_ARCH_REGS_WATCHDOG_H - -#define S3C_WDOGREG(x) ((x) + S3C_VA_WATCHDOG) - -#define S3C2410_WTCON S3C_WDOGREG(0x00) -#define S3C2410_WTDAT S3C_WDOGREG(0x04) -#define S3C2410_WTCNT S3C_WDOGREG(0x08) - -/* the watchdog can either generate a reset pulse, or an - * interrupt. - */ - -#define S3C2410_WTCON_RSTEN (0x01) -#define S3C2410_WTCON_INTEN (1<<2) -#define S3C2410_WTCON_ENABLE (1<<5) - -#define S3C2410_WTCON_DIV16 (0<<3) -#define S3C2410_WTCON_DIV32 (1<<3) -#define S3C2410_WTCON_DIV64 (2<<3) -#define S3C2410_WTCON_DIV128 (3<<3) - -#define S3C2410_WTCON_PRESCALE(x) ((x) << 8) -#define S3C2410_WTCON_PRESCALE_MASK (0xff00) - -#endif /* __ASM_ARCH_REGS_WATCHDOG_H */ - - diff --git a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h deleted file mode 100644 index bf5e2a9d408..00000000000 --- a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h +++ /dev/null @@ -1,32 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h - * - * Copyright (C) 2010 Samsung Electronics Co. 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 as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __S3C_PL330_PDATA_H -#define __S3C_PL330_PDATA_H - -#include <plat/s3c-dma-pl330.h> - -/* - * Every PL330 DMAC has max 32 peripheral interfaces, - * of which some may be not be really used in your - * DMAC's configuration. - * Populate this array of 32 peri i/fs with relevant - * channel IDs for used peri i/f and DMACH_MAX for - * those unused. - * - * The platforms just need to provide this info - * to the S3C DMA API driver for PL330. - */ -struct s3c_pl330_platdata { - enum dma_ch peri[32]; -}; - -#endif /* __S3C_PL330_PDATA_H */ diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h deleted file mode 100644 index ff1a561b326..00000000000 --- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h +++ /dev/null @@ -1,74 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/s3c64xx-spi.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_H -#define __S3C64XX_PLAT_SPI_H - -/** - * struct s3c64xx_spi_csinfo - ChipSelect description - * @fb_delay: Slave specific feedback delay. - * Refer to FB_CLK_SEL register definition in SPI chapter. - * @line: Custom 'identity' of the CS line. - * @set_level: CS line control. - * - * This is per SPI-Slave Chipselect information. - * Allocate and initialize one in machine init code and make the - * spi_board_info.controller_data point to it. - */ -struct s3c64xx_spi_csinfo { - u8 fb_delay; - unsigned line; - void (*set_level)(unsigned line_id, int lvl); -}; - -/** - * struct s3c64xx_spi_info - SPI Controller defining structure - * @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field. - * @src_clk_name: Platform name of the corresponding clock. - * @clk_from_cmu: If the SPI clock/prescalar control block is present - * by the platform's clock-management-unit and not in SPI controller. - * @num_cs: Number of CS this controller emulates. - * @cfg_gpio: Configure pins for this SPI controller. - * @fifo_lvl_mask: All tx fifo_lvl fields start at offset-6 - * @rx_lvl_offset: Depends on tx fifo_lvl field and bus number - * @high_speed: If the controller supports HIGH_SPEED_EN bit - */ -struct s3c64xx_spi_info { - int src_clk_nr; - char *src_clk_name; - bool clk_from_cmu; - - int num_cs; - - int (*cfg_gpio)(struct platform_device *pdev); - - /* Following two fields are for future compatibility */ - int fifo_lvl_mask; - int rx_lvl_offset; - int high_speed; -}; - -/** - * s3c64xx_spi_set_info - SPI Controller configure callback by the board - * initialization code. - * @cntrlr: SPI controller number the configuration is for. - * @src_clk_nr: Clock the SPI controller is to use to generate SPI clocks. - * @num_cs: Number of elements in the 'cs' array. - * - * Call this from machine init code for each SPI Controller that - * has some chips attached to it. - */ -extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); -extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); -extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); -extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); -extern void s5p6442_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); - -#endif /* __S3C64XX_PLAT_SPI_H */ diff --git a/arch/arm/plat-samsung/include/plat/s5p-clock.h b/arch/arm/plat-samsung/include/plat/s5p-clock.h new file mode 100644 index 00000000000..8364b4bea8b --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/s5p-clock.h @@ -0,0 +1,65 @@ +/* linux/arch/arm/plat-samsung/include/plat/s5p-clock.h + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Header file for s5p 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. +*/ + +#ifndef __ASM_PLAT_S5P_CLOCK_H +#define __ASM_PLAT_S5P_CLOCK_H __FILE__ + +#include <linux/clk.h> + +#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) + +#define clk_fin_apll clk_ext_xtal_mux +#define clk_fin_bpll clk_ext_xtal_mux +#define clk_fin_cpll clk_ext_xtal_mux +#define clk_fin_mpll clk_ext_xtal_mux +#define clk_fin_epll clk_ext_xtal_mux +#define clk_fin_dpll clk_ext_xtal_mux +#define clk_fin_vpll clk_ext_xtal_mux +#define clk_fin_hpll clk_ext_xtal_mux + +extern struct clk clk_ext_xtal_mux; +extern struct clk clk_xusbxti; +extern struct clk clk_48m; +extern struct clk s5p_clk_27m; +extern struct clk clk_fout_apll; +extern struct clk clk_fout_bpll; +extern struct clk clk_fout_bpll_div2; +extern struct clk clk_fout_cpll; +extern struct clk clk_fout_mpll; +extern struct clk clk_fout_mpll_div2; +extern struct clk clk_fout_epll; +extern struct clk clk_fout_dpll; +extern struct clk clk_fout_vpll; +extern struct clk clk_arm; +extern struct clk clk_vpll; + +extern struct clksrc_sources clk_src_apll; +extern struct clksrc_sources clk_src_bpll; +extern struct clksrc_sources clk_src_bpll_fout; +extern struct clksrc_sources clk_src_cpll; +extern struct clksrc_sources clk_src_mpll; +extern struct clksrc_sources clk_src_mpll_fout; +extern struct clksrc_sources clk_src_epll; +extern struct clksrc_sources clk_src_dpll; + +extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable); + +/* Common EPLL operations for S5P platform */ +extern int s5p_epll_enable(struct clk *clk, int enable); +extern unsigned long s5p_epll_get_rate(struct clk *clk); + +/* SPDIF clk operations common for S5PC100/V210/C110 and Exynos4 */ +extern int s5p_spdif_set_rate(struct clk *clk, unsigned long rate); +extern unsigned long s5p_spdif_get_rate(struct clk *clk); + +extern struct clk_ops s5p_sclk_spdif_ops; +#endif /* __ASM_PLAT_S5P_CLOCK_H */ diff --git a/arch/arm/plat-samsung/include/plat/samsung-time.h b/arch/arm/plat-samsung/include/plat/samsung-time.h new file mode 100644 index 00000000000..209464adef9 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/samsung-time.h @@ -0,0 +1,30 @@ +/* linux/arch/arm/plat-samsung/include/plat/samsung-time.h + * + * Copyright 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Header file for samsung s3c and s5p time 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. +*/ + +#ifndef __ASM_PLAT_SAMSUNG_TIME_H +#define __ASM_PLAT_SAMSUNG_TIME_H __FILE__ + +/* SAMSUNG HR-Timer Clock mode */ +enum samsung_timer_mode { + SAMSUNG_PWM0, + SAMSUNG_PWM1, + SAMSUNG_PWM2, + SAMSUNG_PWM3, + SAMSUNG_PWM4, +}; + +extern void __init samsung_set_timer_source(enum samsung_timer_mode event, + enum samsung_timer_mode source); + +extern void __init samsung_timer_init(void); + +#endif /* __ASM_PLAT_SAMSUNG_TIME_H */ diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h index b0bdf16549d..bf650218b40 100644 --- a/arch/arm/plat-samsung/include/plat/sdhci.h +++ b/arch/arm/plat-samsung/include/plat/sdhci.h @@ -18,73 +18,15 @@ #ifndef __PLAT_S3C_SDHCI_H #define __PLAT_S3C_SDHCI_H __FILE__ -struct platform_device; -struct mmc_host; -struct mmc_card; -struct mmc_ios; - -enum cd_types { - S3C_SDHCI_CD_INTERNAL, /* use mmc internal CD line */ - S3C_SDHCI_CD_EXTERNAL, /* use external callback */ - S3C_SDHCI_CD_GPIO, /* use external gpio pin for CD line */ - S3C_SDHCI_CD_NONE, /* no CD line, use polling to detect card */ - S3C_SDHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */ -}; - -enum clk_types { - S3C_SDHCI_CLK_DIV_INTERNAL, /* use mmc internal clock divider */ - S3C_SDHCI_CLK_DIV_EXTERNAL, /* use external clock divider */ -}; +#include <linux/platform_data/mmc-sdhci-s3c.h> +#include <plat/devs.h> -/** - * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI - * @max_width: The maximum number of data bits supported. - * @host_caps: Standard MMC host capabilities bit field. - * @cd_type: Type of Card Detection method (see cd_types enum above) - * @clk_type: Type of clock divider method (see clk_types enum above) - * @ext_cd_init: Initialize external card detect subsystem. Called on - * sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL. - * notify_func argument is a callback to the sdhci-s3c driver - * that triggers the card detection event. Callback arguments: - * dev is pointer to platform device of the host controller, - * state is new state of the card (0 - removed, 1 - inserted). - * @ext_cd_cleanup: Cleanup external card detect subsystem. Called on - * sdhci-s3c driver remove when cd_type == S3C_SDHCI_CD_EXTERNAL. - * notify_func argument is the same callback as for ext_cd_init. - * @ext_cd_gpio: gpio pin used for external CD line, valid only if - * cd_type == S3C_SDHCI_CD_GPIO - * @ext_cd_gpio_invert: invert values for external CD gpio line - * @cfg_gpio: Configure the GPIO for a specific card bit-width - * @cfg_card: Configure the interface for a specific card and speed. This - * is necessary the controllers and/or GPIO blocks require the - * changing of driver-strength and other controls dependant on - * the card and speed of operation. - * - * Initialisation data specific to either the machine or the platform - * for the device driver to use or call-back when configuring gpio or - * card speed information. -*/ -struct s3c_sdhci_platdata { - unsigned int max_width; - unsigned int host_caps; - enum cd_types cd_type; - enum clk_types clk_type; - - char **clocks; /* set of clock sources */ - - int ext_cd_gpio; - bool ext_cd_gpio_invert; - int (*ext_cd_init)(void (*notify_func)(struct platform_device *, - int state)); - int (*ext_cd_cleanup)(void (*notify_func)(struct platform_device *, - int state)); - - void (*cfg_gpio)(struct platform_device *dev, int width); - void (*cfg_card)(struct platform_device *dev, - void __iomem *regbase, - struct mmc_ios *ios, - struct mmc_card *card); -}; +/* s3c_sdhci_set_platdata() - common helper for setting SDHCI platform data + * @pd: The default platform data for this device. + * @set: Pointer to the platform data to fill in. + */ +extern void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd, + struct s3c_sdhci_platdata *set); /** * s3c_sdhci0_set_platdata - Set platform data for S3C SDHCI device. @@ -108,7 +50,7 @@ extern struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata; extern struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata; extern struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata; -/* Helper function availablity */ +/* Helper function availability */ extern void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *, int w); extern void s3c2416_setup_sdhci1_cfg_gpio(struct platform_device *, int w); @@ -126,32 +68,25 @@ extern void exynos4_setup_sdhci0_cfg_gpio(struct platform_device *, int w); extern void exynos4_setup_sdhci1_cfg_gpio(struct platform_device *, int w); extern void exynos4_setup_sdhci2_cfg_gpio(struct platform_device *, int w); extern void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *, int w); +extern void s5p64x0_setup_sdhci0_cfg_gpio(struct platform_device *, int w); +extern void s5p64x0_setup_sdhci1_cfg_gpio(struct platform_device *, int w); +extern void s5p6440_setup_sdhci2_cfg_gpio(struct platform_device *, int w); +extern void s5p6450_setup_sdhci2_cfg_gpio(struct platform_device *, int w); /* S3C2416 SDHCI setup */ #ifdef CONFIG_S3C2416_SETUP_SDHCI -extern char *s3c2416_hsmmc_clksrcs[4]; - -extern void s3c2416_setup_sdhci_cfg_card(struct platform_device *dev, - void __iomem *r, - struct mmc_ios *ios, - struct mmc_card *card); - static inline void s3c2416_default_sdhci0(void) { #ifdef CONFIG_S3C_DEV_HSMMC - s3c_hsmmc0_def_platdata.clocks = s3c2416_hsmmc_clksrcs; s3c_hsmmc0_def_platdata.cfg_gpio = s3c2416_setup_sdhci0_cfg_gpio; - s3c_hsmmc0_def_platdata.cfg_card = s3c2416_setup_sdhci_cfg_card; #endif /* CONFIG_S3C_DEV_HSMMC */ } static inline void s3c2416_default_sdhci1(void) { #ifdef CONFIG_S3C_DEV_HSMMC1 - s3c_hsmmc1_def_platdata.clocks = s3c2416_hsmmc_clksrcs; s3c_hsmmc1_def_platdata.cfg_gpio = s3c2416_setup_sdhci1_cfg_gpio; - s3c_hsmmc1_def_platdata.cfg_card = s3c2416_setup_sdhci_cfg_card; #endif /* CONFIG_S3C_DEV_HSMMC1 */ } @@ -160,72 +95,49 @@ static inline void s3c2416_default_sdhci0(void) { } static inline void s3c2416_default_sdhci1(void) { } #endif /* CONFIG_S3C2416_SETUP_SDHCI */ + /* S3C64XX SDHCI setup */ #ifdef CONFIG_S3C64XX_SETUP_SDHCI -extern char *s3c64xx_hsmmc_clksrcs[4]; - -extern void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev, - void __iomem *r, - struct mmc_ios *ios, - struct mmc_card *card); - static inline void s3c6400_default_sdhci0(void) { #ifdef CONFIG_S3C_DEV_HSMMC - s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio; - s3c_hsmmc0_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card; #endif } static inline void s3c6400_default_sdhci1(void) { #ifdef CONFIG_S3C_DEV_HSMMC1 - s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio; - s3c_hsmmc1_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card; #endif } static inline void s3c6400_default_sdhci2(void) { #ifdef CONFIG_S3C_DEV_HSMMC2 - s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio; - s3c_hsmmc2_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card; #endif } -extern void s3c6410_setup_sdhci_cfg_card(struct platform_device *dev, - void __iomem *r, - struct mmc_ios *ios, - struct mmc_card *card); - static inline void s3c6410_default_sdhci0(void) { #ifdef CONFIG_S3C_DEV_HSMMC - s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio; - s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card; #endif } static inline void s3c6410_default_sdhci1(void) { #ifdef CONFIG_S3C_DEV_HSMMC1 - s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio; - s3c_hsmmc1_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card; #endif } static inline void s3c6410_default_sdhci2(void) { #ifdef CONFIG_S3C_DEV_HSMMC2 - s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio; - s3c_hsmmc2_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card; #endif } @@ -239,40 +151,66 @@ static inline void s3c6400_default_sdhci2(void) { } #endif /* CONFIG_S3C64XX_SETUP_SDHCI */ -/* S5PC100 SDHCI setup */ +/* S5P64X0 SDHCI setup */ -#ifdef CONFIG_S5PC100_SETUP_SDHCI -extern char *s5pc100_hsmmc_clksrcs[4]; +#ifdef CONFIG_S5P64X0_SETUP_SDHCI_GPIO +static inline void s5p64x0_default_sdhci0(void) +{ +#ifdef CONFIG_S3C_DEV_HSMMC + s3c_hsmmc0_def_platdata.cfg_gpio = s5p64x0_setup_sdhci0_cfg_gpio; +#endif +} -extern void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev, - void __iomem *r, - struct mmc_ios *ios, - struct mmc_card *card); +static inline void s5p64x0_default_sdhci1(void) +{ +#ifdef CONFIG_S3C_DEV_HSMMC1 + s3c_hsmmc1_def_platdata.cfg_gpio = s5p64x0_setup_sdhci1_cfg_gpio; +#endif +} +static inline void s5p6440_default_sdhci2(void) +{ +#ifdef CONFIG_S3C_DEV_HSMMC2 + s3c_hsmmc2_def_platdata.cfg_gpio = s5p6440_setup_sdhci2_cfg_gpio; +#endif +} + +static inline void s5p6450_default_sdhci2(void) +{ +#ifdef CONFIG_S3C_DEV_HSMMC2 + s3c_hsmmc2_def_platdata.cfg_gpio = s5p6450_setup_sdhci2_cfg_gpio; +#endif +} + +#else +static inline void s5p64x0_default_sdhci0(void) { } +static inline void s5p64x0_default_sdhci1(void) { } +static inline void s5p6440_default_sdhci2(void) { } +static inline void s5p6450_default_sdhci2(void) { } + +#endif /* CONFIG_S5P64X0_SETUP_SDHCI_GPIO */ + +/* S5PC100 SDHCI setup */ + +#ifdef CONFIG_S5PC100_SETUP_SDHCI static inline void s5pc100_default_sdhci0(void) { #ifdef CONFIG_S3C_DEV_HSMMC - s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs; s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio; - s3c_hsmmc0_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card; #endif } static inline void s5pc100_default_sdhci1(void) { #ifdef CONFIG_S3C_DEV_HSMMC1 - s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs; s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio; - s3c_hsmmc1_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card; #endif } static inline void s5pc100_default_sdhci2(void) { #ifdef CONFIG_S3C_DEV_HSMMC2 - s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs; s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio; - s3c_hsmmc2_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card; #endif } @@ -286,46 +224,31 @@ static inline void s5pc100_default_sdhci2(void) { } /* S5PV210 SDHCI setup */ #ifdef CONFIG_S5PV210_SETUP_SDHCI -extern char *s5pv210_hsmmc_clksrcs[4]; - -extern void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev, - void __iomem *r, - struct mmc_ios *ios, - struct mmc_card *card); - static inline void s5pv210_default_sdhci0(void) { #ifdef CONFIG_S3C_DEV_HSMMC - s3c_hsmmc0_def_platdata.clocks = s5pv210_hsmmc_clksrcs; s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio; - s3c_hsmmc0_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card; #endif } static inline void s5pv210_default_sdhci1(void) { #ifdef CONFIG_S3C_DEV_HSMMC1 - s3c_hsmmc1_def_platdata.clocks = s5pv210_hsmmc_clksrcs; s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio; - s3c_hsmmc1_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card; #endif } static inline void s5pv210_default_sdhci2(void) { #ifdef CONFIG_S3C_DEV_HSMMC2 - s3c_hsmmc2_def_platdata.clocks = s5pv210_hsmmc_clksrcs; s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio; - s3c_hsmmc2_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card; #endif } static inline void s5pv210_default_sdhci3(void) { #ifdef CONFIG_S3C_DEV_HSMMC3 - s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs; s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio; - s3c_hsmmc3_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card; #endif } @@ -337,57 +260,31 @@ static inline void s5pv210_default_sdhci3(void) { } #endif /* CONFIG_S5PV210_SETUP_SDHCI */ -/* EXYNOS4 SDHCI setup */ -#ifdef CONFIG_EXYNOS4_SETUP_SDHCI -extern char *exynos4_hsmmc_clksrcs[4]; - -extern void exynos4_setup_sdhci_cfg_card(struct platform_device *dev, - void __iomem *r, - struct mmc_ios *ios, - struct mmc_card *card); - -static inline void exynos4_default_sdhci0(void) +static inline void s3c_sdhci_setname(int id, char *name) { + switch (id) { #ifdef CONFIG_S3C_DEV_HSMMC - s3c_hsmmc0_def_platdata.clocks = exynos4_hsmmc_clksrcs; - s3c_hsmmc0_def_platdata.cfg_gpio = exynos4_setup_sdhci0_cfg_gpio; - s3c_hsmmc0_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card; + case 0: + s3c_device_hsmmc0.name = name; + break; #endif -} - -static inline void exynos4_default_sdhci1(void) -{ #ifdef CONFIG_S3C_DEV_HSMMC1 - s3c_hsmmc1_def_platdata.clocks = exynos4_hsmmc_clksrcs; - s3c_hsmmc1_def_platdata.cfg_gpio = exynos4_setup_sdhci1_cfg_gpio; - s3c_hsmmc1_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card; + case 1: + s3c_device_hsmmc1.name = name; + break; #endif -} - -static inline void exynos4_default_sdhci2(void) -{ #ifdef CONFIG_S3C_DEV_HSMMC2 - s3c_hsmmc2_def_platdata.clocks = exynos4_hsmmc_clksrcs; - s3c_hsmmc2_def_platdata.cfg_gpio = exynos4_setup_sdhci2_cfg_gpio; - s3c_hsmmc2_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card; + case 2: + s3c_device_hsmmc2.name = name; + break; #endif -} - -static inline void exynos4_default_sdhci3(void) -{ #ifdef CONFIG_S3C_DEV_HSMMC3 - s3c_hsmmc3_def_platdata.clocks = exynos4_hsmmc_clksrcs; - s3c_hsmmc3_def_platdata.cfg_gpio = exynos4_setup_sdhci3_cfg_gpio; - s3c_hsmmc3_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card; + case 3: + s3c_device_hsmmc3.name = name; + break; #endif + default: + break; + } } - -#else -static inline void exynos4_default_sdhci0(void) { } -static inline void exynos4_default_sdhci1(void) { } -static inline void exynos4_default_sdhci2(void) { } -static inline void exynos4_default_sdhci3(void) { } - -#endif /* CONFIG_EXYNOS4_SETUP_SDHCI */ - #endif /* __PLAT_S3C_SDHCI_H */ diff --git a/arch/arm/plat-samsung/include/plat/spi-core.h b/arch/arm/plat-samsung/include/plat/spi-core.h new file mode 100644 index 00000000000..0b9428ab3fc --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/spi-core.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2012 Heiko Stuebner <heiko@sntech.de> + * + * 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_S3C_SPI_CORE_H +#define __PLAT_S3C_SPI_CORE_H + +/* These functions are only for use with the core support code, such as + * the cpu specific initialisation code + */ + +/* re-define device name depending on support. */ +static inline void s3c64xx_spi_setname(char *name) +{ +#ifdef CONFIG_S3C64XX_DEV_SPI0 + s3c64xx_device_spi0.name = name; +#endif +#ifdef CONFIG_S3C64XX_DEV_SPI1 + s3c64xx_device_spi1.name = name; +#endif +#ifdef CONFIG_S3C64XX_DEV_SPI2 + s3c64xx_device_spi2.name = name; +#endif +} + +#endif /* __PLAT_S3C_SPI_CORE_H */ diff --git a/arch/arm/plat-samsung/include/plat/ts.h b/arch/arm/plat-samsung/include/plat/ts.h deleted file mode 100644 index 26fdb22e0fc..00000000000 --- a/arch/arm/plat-samsung/include/plat/ts.h +++ /dev/null @@ -1,25 +0,0 @@ -/* arch/arm/plat-samsung/include/plat/ts.h - * - * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org> - * - * 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_ARM_TS_H -#define __ASM_ARM_TS_H - -struct s3c2410_ts_mach_info { - int delay; - int presc; - int oversampling_shift; - void (*cfg_gpio)(struct platform_device *dev); -}; - -extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *); - -/* defined by architecture to configure gpio */ -extern void s3c24xx_ts_cfg_gpio(struct platform_device *dev); - -#endif /* __ASM_ARM_TS_H */ diff --git a/arch/arm/plat-samsung/include/plat/tv-core.h b/arch/arm/plat-samsung/include/plat/tv-core.h new file mode 100644 index 00000000000..3bc34f3ce28 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/tv-core.h @@ -0,0 +1,44 @@ +/* + * arch/arm/plat-samsung/include/plat/tv.h + * + * Copyright 2011 Samsung Electronics Co., Ltd. + * Tomasz Stanislawski <t.stanislaws@samsung.com> + * + * Samsung TV driver core functions + * + * 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 __SAMSUNG_PLAT_TV_H +#define __SAMSUNG_PLAT_TV_H __FILE__ + +/* + * These functions are only for use with the core support code, such as + * the CPU-specific initialization code. + */ + +/* Re-define device name to differentiate the subsystem in various SoCs. */ +static inline void s5p_hdmi_setname(char *name) +{ +#ifdef CONFIG_S5P_DEV_TV + s5p_device_hdmi.name = name; +#endif +} + +static inline void s5p_mixer_setname(char *name) +{ +#ifdef CONFIG_S5P_DEV_TV + s5p_device_mixer.name = name; +#endif +} + +static inline void s5p_sdo_setname(char *name) +{ +#ifdef CONFIG_S5P_DEV_TV + s5p_device_sdo.name = name; +#endif +} + +#endif /* __SAMSUNG_PLAT_TV_H */ diff --git a/arch/arm/plat-samsung/include/plat/udc-hs.h b/arch/arm/plat-samsung/include/plat/udc-hs.h deleted file mode 100644 index a22a4f2eea9..00000000000 --- a/arch/arm/plat-samsung/include/plat/udc-hs.h +++ /dev/null @@ -1,29 +0,0 @@ -/* arch/arm/plat-s3c/include/plat/udc-hs.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C USB2.0 High-speed / OtG platform information - * - * 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. -*/ - -enum s3c_hsotg_dmamode { - S3C_HSOTG_DMA_NONE, /* do not use DMA at-all */ - S3C_HSOTG_DMA_ONLY, /* always use DMA */ - S3C_HSOTG_DMA_DRV, /* DMA is chosen by driver */ -}; - -/** - * struct s3c_hsotg_plat - platform data for high-speed otg/udc - * @dma: Whether to use DMA or not. - * @is_osc: The clock source is an oscillator, not a crystal - */ -struct s3c_hsotg_plat { - enum s3c_hsotg_dmamode dma; - unsigned int is_osc : 1; -}; diff --git a/arch/arm/plat-samsung/include/plat/uncompress.h b/arch/arm/plat-samsung/include/plat/uncompress.h deleted file mode 100644 index 7d6ed7263d5..00000000000 --- a/arch/arm/plat-samsung/include/plat/uncompress.h +++ /dev/null @@ -1,184 +0,0 @@ -/* arch/arm/plat-samsung/include/plat/uncompress.h - * - * Copyright 2003, 2007 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * S3C - 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_PLAT_UNCOMPRESS_H -#define __ASM_PLAT_UNCOMPRESS_H - -typedef unsigned int upf_t; /* cannot include linux/serial_core.h */ - -/* uart setup */ - -static unsigned int fifo_mask; -static unsigned int fifo_max; - -/* forward declerations */ - -static void arch_detect_cpu(void); - -/* defines for UART registers */ - -#include <plat/regs-serial.h> -#include <plat/regs-watchdog.h> - -/* working in physical space... */ -#undef S3C2410_WDOGREG -#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x))) - -/* how many bytes we allow into the FIFO at a time in FIFO mode */ -#define FIFO_MAX (14) - -#define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT) - -static __inline__ void -uart_wr(unsigned int reg, unsigned int val) -{ - volatile unsigned int *ptr; - - ptr = (volatile unsigned int *)(reg + uart_base); - *ptr = val; -} - -static __inline__ unsigned int -uart_rd(unsigned int reg) -{ - volatile unsigned int *ptr; - - ptr = (volatile unsigned int *)(reg + uart_base); - return *ptr; -} - -/* we can deal with the case the UARTs are being run - * in FIFO mode, so that we don't hold up our execution - * waiting for tx to happen... -*/ - -static void putc(int ch) -{ - if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) { - int level; - - while (1) { - level = uart_rd(S3C2410_UFSTAT); - level &= fifo_mask; - - if (level < fifo_max) - break; - } - - } else { - /* not using fifos */ - - while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE) - barrier(); - } - - /* write byte to transmission register */ - uart_wr(S3C2410_UTXH, ch); -} - -static inline void flush(void) -{ -} - -#define __raw_writel(d, ad) \ - do { \ - *((volatile unsigned int __force *)(ad)) = (d); \ - } while (0) - -/* CONFIG_S3C_BOOT_WATCHDOG - * - * Simple boot-time watchdog setup, to reboot the system if there is - * any problem with the boot process -*/ - -#ifdef CONFIG_S3C_BOOT_WATCHDOG - -#define WDOG_COUNT (0xff00) - -static inline void arch_decomp_wdog(void) -{ - __raw_writel(WDOG_COUNT, S3C2410_WTCNT); -} - -static void arch_decomp_wdog_start(void) -{ - __raw_writel(WDOG_COUNT, S3C2410_WTDAT); - __raw_writel(WDOG_COUNT, S3C2410_WTCNT); - __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON); -} - -#else -#define arch_decomp_wdog_start() -#define arch_decomp_wdog() -#endif - -#ifdef CONFIG_S3C_BOOT_ERROR_RESET - -static void arch_decomp_error(const char *x) -{ - putstr("\n\n"); - putstr(x); - putstr("\n\n -- System resetting\n"); - - __raw_writel(0x4000, S3C2410_WTDAT); - __raw_writel(0x4000, S3C2410_WTCNT); - __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON); - - while(1); -} - -#define arch_error arch_decomp_error -#endif - -#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO -static inline void arch_enable_uart_fifo(void) -{ - u32 fifocon = uart_rd(S3C2410_UFCON); - - if (!(fifocon & S3C2410_UFCON_FIFOMODE)) { - fifocon |= S3C2410_UFCON_RESETBOTH; - uart_wr(S3C2410_UFCON, fifocon); - - /* wait for fifo reset to complete */ - while (1) { - fifocon = uart_rd(S3C2410_UFCON); - if (!(fifocon & S3C2410_UFCON_RESETBOTH)) - break; - } - } -} -#else -#define arch_enable_uart_fifo() do { } while(0) -#endif - - -static void -arch_decomp_setup(void) -{ - /* we may need to setup the uart(s) here if we are not running - * on an BAST... the BAST will have left the uarts configured - * after calling linux. - */ - - arch_detect_cpu(); - arch_decomp_wdog_start(); - - /* Enable the UART FIFOs if they where not enabled and our - * configuration says we should turn them on. - */ - - arch_enable_uart_fifo(); -} - - -#endif /* __ASM_PLAT_UNCOMPRESS_H */ diff --git a/arch/arm/plat-samsung/include/plat/usb-control.h b/arch/arm/plat-samsung/include/plat/usb-control.h deleted file mode 100644 index 7fa1fbefc3f..00000000000 --- a/arch/arm/plat-samsung/include/plat/usb-control.h +++ /dev/null @@ -1,43 +0,0 @@ -/* arch/arm/plat-samsung/include/plat/usb-control.h - * - * Copyright (c) 2004 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * S3C - USB host port information - * - * 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_USBCONTROL_H -#define __ASM_ARCH_USBCONTROL_H - -#define S3C_HCDFLG_USED (1) - -struct s3c2410_hcd_port { - unsigned char flags; - unsigned char power; - unsigned char oc_status; - unsigned char oc_changed; -}; - -struct s3c2410_hcd_info { - struct usb_hcd *hcd; - struct s3c2410_hcd_port port[2]; - - void (*power_control)(int port, int to); - void (*enable_oc)(struct s3c2410_hcd_info *, int on); - void (*report_oc)(struct s3c2410_hcd_info *, int ports); -}; - -static void inline s3c2410_usb_report_oc(struct s3c2410_hcd_info *info, int ports) -{ - if (info->report_oc != NULL) { - (info->report_oc)(info, ports); - } -} - -extern void s3c_ohci_set_platdata(struct s3c2410_hcd_info *info); - -#endif /*__ASM_ARCH_USBCONTROL_H */ diff --git a/arch/arm/plat-samsung/include/plat/usb-phy.h b/arch/arm/plat-samsung/include/plat/usb-phy.h new file mode 100644 index 00000000000..ab34dfadb7f --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/usb-phy.h @@ -0,0 +1,19 @@ +/* + * 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. + */ + +#ifndef __PLAT_SAMSUNG_USB_PHY_H +#define __PLAT_SAMSUNG_USB_PHY_H __FILE__ + +#include <linux/usb/samsung_usb_phy.h> + +extern int s5p_usb_phy_init(struct platform_device *pdev, int type); +extern int s5p_usb_phy_exit(struct platform_device *pdev, int type); + +#endif /* __PLAT_SAMSUNG_USB_PHY_H */ diff --git a/arch/arm/plat-samsung/include/plat/watchdog-reset.h b/arch/arm/plat-samsung/include/plat/watchdog-reset.h index 54b762acb5a..0386b8f7662 100644 --- a/arch/arm/plat-samsung/include/plat/watchdog-reset.h +++ b/arch/arm/plat-samsung/include/plat/watchdog-reset.h @@ -10,40 +10,11 @@ * published by the Free Software Foundation. */ -#include <plat/regs-watchdog.h> -#include <mach/map.h> +#ifndef __PLAT_SAMSUNG_WATCHDOG_RESET_H +#define __PLAT_SAMSUNG_WATCHDOG_RESET_H -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/io.h> +extern void samsung_wdt_reset(void); +extern void samsung_wdt_reset_of_init(void); +extern void samsung_wdt_reset_init(void __iomem *base); -static inline void arch_wdt_reset(void) -{ - struct clk *wdtclk; - - printk("arch_reset: attempting watchdog reset\n"); - - __raw_writel(0, S3C2410_WTCON); /* disable watchdog, to be safe */ - - wdtclk = clk_get(NULL, "watchdog"); - if (!IS_ERR(wdtclk)) { - clk_enable(wdtclk); - } else - printk(KERN_WARNING "%s: warning: cannot get watchdog clock\n", __func__); - - /* put initial values into count and data */ - __raw_writel(0x80, S3C2410_WTCNT); - __raw_writel(0x80, S3C2410_WTDAT); - - /* set the watchdog to go and reset... */ - __raw_writel(S3C2410_WTCON_ENABLE|S3C2410_WTCON_DIV16|S3C2410_WTCON_RSTEN | - S3C2410_WTCON_PRESCALE(0x20), S3C2410_WTCON); - - /* wait for reset to assert... */ - mdelay(500); - - printk(KERN_ERR "Watchdog reset failed to assert reset\n"); - - /* delay to allow the serial port to show the message */ - mdelay(50); -} +#endif /* __PLAT_SAMSUNG_WATCHDOG_RESET_H */ diff --git a/arch/arm/plat-samsung/init.c b/arch/arm/plat-samsung/init.c index 6790edfaca6..a1f925f3121 100644 --- a/arch/arm/plat-samsung/init.c +++ b/arch/arm/plat-samsung/init.c @@ -11,14 +11,19 @@ * published by the Free Software Foundation. */ +/* + * NOTE: Code in this file is not used on S3C64xx when booting with + * Device Tree support. + */ + #include <linux/init.h> #include <linux/module.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 <mach/hardware.h> +#include <linux/of.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -27,8 +32,6 @@ #include <plat/devs.h> #include <plat/clock.h> -#include <plat/regs-serial.h> - static struct cpu_table *cpu; static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode, @@ -36,7 +39,7 @@ static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode, unsigned int count) { for (; count != 0; count--, tab++) { - if ((idcode & tab->idmask) == tab->idcode) + if ((idcode & tab->idmask) == (tab->idcode & tab->idmask)) return tab; } @@ -55,12 +58,13 @@ void __init s3c_init_cpu(unsigned long idcode, printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode); - if (cpu->map_io == NULL || cpu->init == NULL) { + if (cpu->init == NULL) { printk(KERN_ERR "CPU %s support not enabled\n", cpu->name); panic("Unsupported Samsung CPU"); } - cpu->map_io(); + if (cpu->map_io) + cpu->map_io(); } /* s3c24xx_init_clocks @@ -87,10 +91,12 @@ void __init s3c24xx_init_clocks(int xtal) } /* uart management */ - +#if IS_ENABLED(CONFIG_SAMSUNG_ATAGS) static int nr_uarts __initdata = 0; +#ifdef CONFIG_SERIAL_SAMSUNG_UARTS static struct s3c2410_uartcfg uart_cfgs[CONFIG_SERIAL_SAMSUNG_UARTS]; +#endif /* s3c24xx_init_uartdevs * @@ -105,6 +111,7 @@ void __init s3c24xx_init_uartdevs(char *name, struct s3c24xx_uart_resources *res, struct s3c2410_uartcfg *cfg, int no) { +#ifdef CONFIG_SERIAL_SAMSUNG_UARTS struct platform_device *platdev; struct s3c2410_uartcfg *cfgptr = uart_cfgs; struct s3c24xx_uart_resources *resp; @@ -127,6 +134,7 @@ void __init s3c24xx_init_uartdevs(char *name, } nr_uarts = no; +#endif } void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no) @@ -134,11 +142,12 @@ void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no) if (cpu == NULL) return; - if (cpu->init_uarts == NULL) { + if (cpu->init_uarts == NULL && IS_ENABLED(CONFIG_SAMSUNG_ATAGS)) { printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n"); } else (cpu->init_uarts)(cfg, no); } +#endif static int __init s3c_arch_init(void) { @@ -146,14 +155,19 @@ static int __init s3c_arch_init(void) // do the correct init for cpu - if (cpu == NULL) + if (cpu == NULL) { + /* Not needed when booting with device tree. */ + if (of_have_populated_dt()) + return 0; panic("s3c_arch_init: NULL cpu\n"); + } ret = (cpu->init)(); if (ret != 0) return ret; - +#if IS_ENABLED(CONFIG_SAMSUNG_ATAGS) ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts); +#endif return ret; } diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c deleted file mode 100644 index 4e770355ccb..00000000000 --- a/arch/arm/plat-samsung/irq-uart.c +++ /dev/null @@ -1,143 +0,0 @@ -/* arch/arm/plat-samsung/irq-uart.c - * originally part of arch/arm/plat-s3c64xx/irq.c - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * Samsung- UART Interrupt handling - * - * 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/interrupt.h> -#include <linux/serial_core.h> -#include <linux/irq.h> -#include <linux/io.h> - -#include <mach/map.h> -#include <plat/irq-uart.h> -#include <plat/regs-serial.h> -#include <plat/cpu.h> - -/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3] - * are consecutive when looking up the interrupt in the demux routines. - */ - -static inline void __iomem *s3c_irq_uart_base(struct irq_data *data) -{ - struct s3c_uart_irq *uirq = irq_data_get_irq_chip_data(data); - return uirq->regs; -} - -static inline unsigned int s3c_irq_uart_bit(unsigned int irq) -{ - return irq & 3; -} - -static void s3c_irq_uart_mask(struct irq_data *data) -{ - void __iomem *regs = s3c_irq_uart_base(data); - unsigned int bit = s3c_irq_uart_bit(data->irq); - u32 reg; - - reg = __raw_readl(regs + S3C64XX_UINTM); - reg |= (1 << bit); - __raw_writel(reg, regs + S3C64XX_UINTM); -} - -static void s3c_irq_uart_maskack(struct irq_data *data) -{ - void __iomem *regs = s3c_irq_uart_base(data); - unsigned int bit = s3c_irq_uart_bit(data->irq); - u32 reg; - - reg = __raw_readl(regs + S3C64XX_UINTM); - reg |= (1 << bit); - __raw_writel(reg, regs + S3C64XX_UINTM); - __raw_writel(1 << bit, regs + S3C64XX_UINTP); -} - -static void s3c_irq_uart_unmask(struct irq_data *data) -{ - void __iomem *regs = s3c_irq_uart_base(data); - unsigned int bit = s3c_irq_uart_bit(data->irq); - u32 reg; - - reg = __raw_readl(regs + S3C64XX_UINTM); - reg &= ~(1 << bit); - __raw_writel(reg, regs + S3C64XX_UINTM); -} - -static void s3c_irq_uart_ack(struct irq_data *data) -{ - void __iomem *regs = s3c_irq_uart_base(data); - unsigned int bit = s3c_irq_uart_bit(data->irq); - - __raw_writel(1 << bit, regs + S3C64XX_UINTP); -} - -static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc) -{ - struct s3c_uart_irq *uirq = desc->irq_data.handler_data; - u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP); - int base = uirq->base_irq; - - if (pend & (1 << 0)) - generic_handle_irq(base); - if (pend & (1 << 1)) - generic_handle_irq(base + 1); - if (pend & (1 << 2)) - generic_handle_irq(base + 2); - if (pend & (1 << 3)) - generic_handle_irq(base + 3); -} - -static struct irq_chip s3c_irq_uart = { - .name = "s3c-uart", - .irq_mask = s3c_irq_uart_mask, - .irq_unmask = s3c_irq_uart_unmask, - .irq_mask_ack = s3c_irq_uart_maskack, - .irq_ack = s3c_irq_uart_ack, -}; - -static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) -{ - struct irq_desc *desc = irq_to_desc(uirq->parent_irq); - void __iomem *reg_base = uirq->regs; - unsigned int irq; - int offs; - - /* mask all interrupts at the start. */ - __raw_writel(0xf, reg_base + S3C64XX_UINTM); - - for (offs = 0; offs < 3; offs++) { - irq = uirq->base_irq + offs; - - set_irq_chip(irq, &s3c_irq_uart); - set_irq_chip_data(irq, uirq); - set_irq_handler(irq, handle_level_irq); - set_irq_flags(irq, IRQF_VALID); - } - - desc->irq_data.handler_data = uirq; - set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart); -} - -/** - * s3c_init_uart_irqs() - initialise UART IRQs and the necessary demuxing - * @irq: The interrupt data for registering - * @nr_irqs: The number of interrupt descriptions in @irq. - * - * Register the UART interrupts specified by @irq including the demuxing - * routines. This supports the S3C6400 and newer style of devices. - */ -void __init s3c_init_uart_irqs(struct s3c_uart_irq *irq, unsigned int nr_irqs) -{ - for (; nr_irqs > 0; nr_irqs--, irq++) - s3c_init_uart_irq(irq); -} diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c deleted file mode 100644 index dd8692ae5c4..00000000000 --- a/arch/arm/plat-samsung/irq-vic-timer.c +++ /dev/null @@ -1,90 +0,0 @@ -/* arch/arm/plat-samsung/irq-vic-timer.c - * originally part of arch/arm/plat-s3c64xx/irq.c - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C64XX - Interrupt handling - * - * 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/interrupt.h> -#include <linux/irq.h> -#include <linux/io.h> - -#include <mach/map.h> -#include <plat/irq-vic-timer.h> -#include <plat/regs-timer.h> - -static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc) -{ - generic_handle_irq((int)desc->irq_data.handler_data); -} - -/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ - -static void s3c_irq_timer_mask(struct irq_data *data) -{ - u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); - u32 mask = (u32)data->chip_data; - - reg &= 0x1f; /* mask out pending interrupts */ - reg &= ~mask; - __raw_writel(reg, S3C64XX_TINT_CSTAT); -} - -static void s3c_irq_timer_unmask(struct irq_data *data) -{ - u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); - u32 mask = (u32)data->chip_data; - - reg &= 0x1f; /* mask out pending interrupts */ - reg |= mask; - __raw_writel(reg, S3C64XX_TINT_CSTAT); -} - -static void s3c_irq_timer_ack(struct irq_data *data) -{ - u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); - u32 mask = (u32)data->chip_data; - - reg &= 0x1f; - reg |= mask << 5; - __raw_writel(reg, S3C64XX_TINT_CSTAT); -} - -static struct irq_chip s3c_irq_timer = { - .name = "s3c-timer", - .irq_mask = s3c_irq_timer_mask, - .irq_unmask = s3c_irq_timer_unmask, - .irq_ack = s3c_irq_timer_ack, -}; - -/** - * s3c_init_vic_timer_irq() - initialise timer irq chanined off VIC.\ - * @parent_irq: The parent IRQ on the VIC for the timer. - * @timer_irq: The IRQ to be used for the timer. - * - * Register the necessary IRQ chaining and support for the timer IRQs - * chained of the VIC. - */ -void __init s3c_init_vic_timer_irq(unsigned int parent_irq, - unsigned int timer_irq) -{ - struct irq_desc *desc = irq_to_desc(parent_irq); - - set_irq_chained_handler(parent_irq, s3c_irq_demux_vic_timer); - - set_irq_chip(timer_irq, &s3c_irq_timer); - set_irq_chip_data(timer_irq, (void *)(1 << (timer_irq - IRQ_TIMER0))); - set_irq_handler(timer_irq, handle_level_irq); - set_irq_flags(timer_irq, IRQF_VALID); - - desc->irq_data.handler_data = (void *)timer_irq; -} diff --git a/arch/arm/plat-samsung/pd.c b/arch/arm/plat-samsung/pd.c deleted file mode 100644 index efe1d564473..00000000000 --- a/arch/arm/plat-samsung/pd.c +++ /dev/null @@ -1,95 +0,0 @@ -/* linux/arch/arm/plat-samsung/pd.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Samsung Power domain 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/platform_device.h> -#include <linux/err.h> -#include <linux/pm_runtime.h> - -#include <plat/pd.h> - -static int samsung_pd_probe(struct platform_device *pdev) -{ - struct samsung_pd_info *pdata = pdev->dev.platform_data; - struct device *dev = &pdev->dev; - - if (!pdata) { - dev_err(dev, "no device data specified\n"); - return -ENOENT; - } - - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - - dev_info(dev, "power domain registered\n"); - return 0; -} - -static int __devexit samsung_pd_remove(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - - pm_runtime_disable(dev); - return 0; -} - -static int samsung_pd_runtime_suspend(struct device *dev) -{ - struct samsung_pd_info *pdata = dev->platform_data; - int ret = 0; - - if (pdata->disable) - ret = pdata->disable(dev); - - dev_dbg(dev, "suspended\n"); - return ret; -} - -static int samsung_pd_runtime_resume(struct device *dev) -{ - struct samsung_pd_info *pdata = dev->platform_data; - int ret = 0; - - if (pdata->enable) - ret = pdata->enable(dev); - - dev_dbg(dev, "resumed\n"); - return ret; -} - -static const struct dev_pm_ops samsung_pd_pm_ops = { - .runtime_suspend = samsung_pd_runtime_suspend, - .runtime_resume = samsung_pd_runtime_resume, -}; - -static struct platform_driver samsung_pd_driver = { - .driver = { - .name = "samsung-pd", - .owner = THIS_MODULE, - .pm = &samsung_pd_pm_ops, - }, - .probe = samsung_pd_probe, - .remove = __devexit_p(samsung_pd_remove), -}; - -static int __init samsung_pd_init(void) -{ - int ret; - - ret = platform_driver_register(&samsung_pd_driver); - if (ret) - printk(KERN_ERR "%s: failed to add PD driver\n", __func__); - - return ret; -} -arch_initcall(samsung_pd_init); diff --git a/arch/arm/plat-samsung/platformdata.c b/arch/arm/plat-samsung/platformdata.c index 7cf2e1e3b20..b430e994628 100644 --- a/arch/arm/plat-samsung/platformdata.c +++ b/arch/arm/plat-samsung/platformdata.c @@ -10,10 +10,12 @@ */ #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/string.h> #include <linux/platform_device.h> #include <plat/devs.h> +#include <plat/sdhci.h> void __init *s3c_set_platdata(void *pd, size_t pdsize, struct platform_device *pdev) @@ -35,3 +37,24 @@ void __init *s3c_set_platdata(void *pd, size_t pdsize, pdev->dev.platform_data = npd; return npd; } + +void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd, + struct s3c_sdhci_platdata *set) +{ + set->cd_type = pd->cd_type; + set->ext_cd_init = pd->ext_cd_init; + set->ext_cd_cleanup = pd->ext_cd_cleanup; + set->ext_cd_gpio = pd->ext_cd_gpio; + set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; + + if (pd->max_width) + set->max_width = pd->max_width; + if (pd->cfg_gpio) + set->cfg_gpio = pd->cfg_gpio; + if (pd->host_caps) + set->host_caps |= pd->host_caps; + if (pd->host_caps2) + set->host_caps2 |= pd->host_caps2; + if (pd->pm_caps) + set->pm_caps |= pd->pm_caps; +} diff --git a/arch/arm/plat-samsung/pm-check.c b/arch/arm/plat-samsung/pm-check.c index e4baf76f374..04aff2c31b4 100644 --- a/arch/arm/plat-samsung/pm-check.c +++ b/arch/arm/plat-samsung/pm-check.c @@ -19,7 +19,7 @@ #include <linux/ioport.h> #include <linux/slab.h> -#include <plat/pm.h> +#include <plat/pm-common.h> #if CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE < 1 #error CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE must be a positive non-zero value @@ -72,7 +72,7 @@ static void s3c_pm_run_sysram(run_fn_t fn, u32 *arg) static u32 *s3c_pm_countram(struct resource *res, u32 *val) { - u32 size = (u32)(res->end - res->start)+1; + u32 size = (u32)resource_size(res); size += CHECK_CHUNKSIZE-1; size /= CHECK_CHUNKSIZE; @@ -164,7 +164,6 @@ static inline int in_region(void *ptr, int size, void *what, size_t whatsz) */ static u32 *s3c_pm_runcheck(struct resource *res, u32 *val) { - void *save_at = phys_to_virt(s3c_sleep_save_phys); unsigned long addr; unsigned long left; void *stkpage; @@ -192,11 +191,6 @@ static u32 *s3c_pm_runcheck(struct resource *res, u32 *val) goto skip_check; } - if (in_region(ptr, left, save_at, 32*4 )) { - S3C_PMDBG("skipping %08lx, has save block in\n", addr); - goto skip_check; - } - /* calculate and check the checksum */ calc = crc32_le(~0, ptr, left); diff --git a/arch/arm/plat-samsung/pm-common.c b/arch/arm/plat-samsung/pm-common.c new file mode 100644 index 00000000000..515cd53372b --- /dev/null +++ b/arch/arm/plat-samsung/pm-common.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Tomasz Figa <t.figa@samsung.com> + * Copyright (C) 2008 Openmoko, Inc. + * Copyright (C) 2004-2008 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * http://armlinux.simtec.co.uk/ + * + * Samsung common power management helper functions. + * + * 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/io.h> +#include <linux/kernel.h> + +#include <plat/pm-common.h> + +/* helper functions to save and restore register state */ + +/** + * s3c_pm_do_save() - save a set of registers for restoration on resume. + * @ptr: Pointer to an array of registers. + * @count: Size of the ptr array. + * + * Run through the list of registers given, saving their contents in the + * array for later restoration when we wakeup. + */ +void s3c_pm_do_save(struct sleep_save *ptr, int count) +{ + for (; count > 0; count--, ptr++) { + ptr->val = __raw_readl(ptr->reg); + S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val); + } +} + +/** + * s3c_pm_do_restore() - restore register values from the save list. + * @ptr: Pointer to an array of registers. + * @count: Size of the ptr array. + * + * Restore the register values saved from s3c_pm_do_save(). + * + * Note, we do not use S3C_PMDBG() in here, as the system may not have + * restore the UARTs state yet +*/ + +void s3c_pm_do_restore(const struct sleep_save *ptr, int count) +{ + for (; count > 0; count--, ptr++) { + pr_debug("restore %p (restore %08lx, was %08x)\n", + ptr->reg, ptr->val, __raw_readl(ptr->reg)); + + __raw_writel(ptr->val, ptr->reg); + } +} + +/** + * s3c_pm_do_restore_core() - early restore register values from save list. + * + * This is similar to s3c_pm_do_restore() except we try and minimise the + * side effects of the function in case registers that hardware might need + * to work has been restored. + * + * WARNING: Do not put any debug in here that may effect memory or use + * peripherals, as things may be changing! +*/ + +void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count) +{ + for (; count > 0; count--, ptr++) + __raw_writel(ptr->val, ptr->reg); +} diff --git a/arch/arm/plat-samsung/pm-debug.c b/arch/arm/plat-samsung/pm-debug.c new file mode 100644 index 00000000000..8f19f66388d --- /dev/null +++ b/arch/arm/plat-samsung/pm-debug.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Tomasz Figa <t.figa@samsung.com> + * Copyright (C) 2008 Openmoko, Inc. + * Copyright (C) 2004-2008 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * http://armlinux.simtec.co.uk/ + * + * Samsung common power management (suspend to RAM) debug 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/serial_core.h> +#include <linux/io.h> + +#include <asm/mach/map.h> + +#include <plat/cpu.h> +#include <plat/pm-common.h> + +#ifdef CONFIG_SAMSUNG_ATAGS +#include <mach/pm-core.h> +#else +static inline void s3c_pm_debug_init_uart(void) {} +static inline void s3c_pm_arch_update_uart(void __iomem *regs, + struct pm_uart_save *save) {} +#endif + +static struct pm_uart_save uart_save; + +extern void printascii(const char *); + +void s3c_pm_dbg(const char *fmt, ...) +{ + va_list va; + char buff[256]; + + va_start(va, fmt); + vsnprintf(buff, sizeof(buff), fmt, va); + va_end(va); + + printascii(buff); +} + +void s3c_pm_debug_init(void) +{ + /* restart uart clocks so we can use them to output */ + s3c_pm_debug_init_uart(); +} + +static inline void __iomem *s3c_pm_uart_base(void) +{ + unsigned long paddr; + unsigned long vaddr; + + debug_ll_addr(&paddr, &vaddr); + + return (void __iomem *)vaddr; +} + +void s3c_pm_save_uarts(void) +{ + void __iomem *regs = s3c_pm_uart_base(); + struct pm_uart_save *save = &uart_save; + + save->ulcon = __raw_readl(regs + S3C2410_ULCON); + save->ucon = __raw_readl(regs + S3C2410_UCON); + save->ufcon = __raw_readl(regs + S3C2410_UFCON); + save->umcon = __raw_readl(regs + S3C2410_UMCON); + save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV); + + if (!soc_is_s3c2410()) + save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT); + + S3C_PMDBG("UART[%p]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n", + regs, save->ulcon, save->ucon, save->ufcon, save->ubrdiv); +} + +void s3c_pm_restore_uarts(void) +{ + void __iomem *regs = s3c_pm_uart_base(); + struct pm_uart_save *save = &uart_save; + + s3c_pm_arch_update_uart(regs, save); + + __raw_writel(save->ulcon, regs + S3C2410_ULCON); + __raw_writel(save->ucon, regs + S3C2410_UCON); + __raw_writel(save->ufcon, regs + S3C2410_UFCON); + __raw_writel(save->umcon, regs + S3C2410_UMCON); + __raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV); + + if (!soc_is_s3c2410()) + __raw_writel(save->udivslot, regs + S3C2443_DIVSLOT); +} diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c index 96528200eb7..da268813901 100644 --- a/arch/arm/plat-samsung/pm-gpio.c +++ b/arch/arm/plat-samsung/pm-gpio.c @@ -14,11 +14,15 @@ */ #include <linux/kernel.h> -#include <linux/sysdev.h> +#include <linux/device.h> #include <linux/init.h> #include <linux/io.h> #include <linux/gpio.h> +#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX) +#include <mach/gpio-samsung.h> +#endif + #include <plat/gpio-core.h> #include <plat/pm.h> @@ -28,13 +32,13 @@ #define OFFS_DAT (0x04) #define OFFS_UP (0x08) -static void s3c_gpio_pm_1bit_save(struct s3c_gpio_chip *chip) +static void samsung_gpio_pm_1bit_save(struct samsung_gpio_chip *chip) { chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON); chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT); } -static void s3c_gpio_pm_1bit_resume(struct s3c_gpio_chip *chip) +static void samsung_gpio_pm_1bit_resume(struct samsung_gpio_chip *chip) { void __iomem *base = chip->base; u32 old_gpcon = __raw_readl(base + OFFS_CON); @@ -60,12 +64,12 @@ static void s3c_gpio_pm_1bit_resume(struct s3c_gpio_chip *chip) chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat); } -struct s3c_gpio_pm s3c_gpio_pm_1bit = { - .save = s3c_gpio_pm_1bit_save, - .resume = s3c_gpio_pm_1bit_resume, +struct samsung_gpio_pm samsung_gpio_pm_1bit = { + .save = samsung_gpio_pm_1bit_save, + .resume = samsung_gpio_pm_1bit_resume, }; -static void s3c_gpio_pm_2bit_save(struct s3c_gpio_chip *chip) +static void samsung_gpio_pm_2bit_save(struct samsung_gpio_chip *chip) { chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON); chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT); @@ -95,7 +99,7 @@ static inline int is_out(unsigned long con) } /** - * s3c_gpio_pm_2bit_resume() - restore the given GPIO bank + * samsung_gpio_pm_2bit_resume() - restore the given GPIO bank * @chip: The chip information to resume. * * Restore one of the GPIO banks that was saved during suspend. This is @@ -121,7 +125,7 @@ static inline int is_out(unsigned long con) * [1] this assumes that writing to a pin DAT whilst in SFN will set the * state for when it is next output. */ -static void s3c_gpio_pm_2bit_resume(struct s3c_gpio_chip *chip) +static void samsung_gpio_pm_2bit_resume(struct samsung_gpio_chip *chip) { void __iomem *base = chip->base; u32 old_gpcon = __raw_readl(base + OFFS_CON); @@ -187,13 +191,13 @@ static void s3c_gpio_pm_2bit_resume(struct s3c_gpio_chip *chip) chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat); } -struct s3c_gpio_pm s3c_gpio_pm_2bit = { - .save = s3c_gpio_pm_2bit_save, - .resume = s3c_gpio_pm_2bit_resume, +struct samsung_gpio_pm samsung_gpio_pm_2bit = { + .save = samsung_gpio_pm_2bit_save, + .resume = samsung_gpio_pm_2bit_resume, }; #if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P) -static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip) +static void samsung_gpio_pm_4bit_save(struct samsung_gpio_chip *chip) { chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON); chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT); @@ -203,7 +207,7 @@ static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip) chip->pm_save[0] = __raw_readl(chip->base - 4); } -static u32 s3c_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon) +static u32 samsung_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon) { u32 old, new, mask; u32 change_mask = 0x0; @@ -242,14 +246,14 @@ static u32 s3c_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon) return change_mask; } -static void s3c_gpio_pm_4bit_con(struct s3c_gpio_chip *chip, int index) +static void samsung_gpio_pm_4bit_con(struct samsung_gpio_chip *chip, int index) { void __iomem *con = chip->base + (index * 4); u32 old_gpcon = __raw_readl(con); u32 gps_gpcon = chip->pm_save[index + 1]; u32 gpcon, mask; - mask = s3c_gpio_pm_4bit_mask(old_gpcon, gps_gpcon); + mask = samsung_gpio_pm_4bit_mask(old_gpcon, gps_gpcon); gpcon = old_gpcon & ~mask; gpcon |= gps_gpcon & mask; @@ -257,7 +261,7 @@ static void s3c_gpio_pm_4bit_con(struct s3c_gpio_chip *chip, int index) __raw_writel(gpcon, con); } -static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip) +static void samsung_gpio_pm_4bit_resume(struct samsung_gpio_chip *chip) { void __iomem *base = chip->base; u32 old_gpcon[2]; @@ -269,10 +273,10 @@ static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip) old_gpcon[0] = 0; old_gpcon[1] = __raw_readl(base + OFFS_CON); - s3c_gpio_pm_4bit_con(chip, 0); + samsung_gpio_pm_4bit_con(chip, 0); if (chip->chip.ngpio > 8) { old_gpcon[0] = __raw_readl(base - 4); - s3c_gpio_pm_4bit_con(chip, -1); + samsung_gpio_pm_4bit_con(chip, -1); } /* Now change the configurations that require DAT,CON */ @@ -298,19 +302,19 @@ static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip) old_gpdat, gps_gpdat); } -struct s3c_gpio_pm s3c_gpio_pm_4bit = { - .save = s3c_gpio_pm_4bit_save, - .resume = s3c_gpio_pm_4bit_resume, +struct samsung_gpio_pm samsung_gpio_pm_4bit = { + .save = samsung_gpio_pm_4bit_save, + .resume = samsung_gpio_pm_4bit_resume, }; #endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P */ /** - * s3c_pm_save_gpio() - save gpio chip data for suspend + * samsung_pm_save_gpio() - save gpio chip data for suspend * @ourchip: The chip for suspend. */ -static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip) +static void samsung_pm_save_gpio(struct samsung_gpio_chip *ourchip) { - struct s3c_gpio_pm *pm = ourchip->pm; + struct samsung_gpio_pm *pm = ourchip->pm; if (pm == NULL || pm->save == NULL) S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label); @@ -319,24 +323,24 @@ static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip) } /** - * s3c_pm_save_gpios() - Save the state of the GPIO banks. + * samsung_pm_save_gpios() - Save the state of the GPIO banks. * * For all the GPIO banks, save the state of each one ready for going * into a suspend mode. */ -void s3c_pm_save_gpios(void) +void samsung_pm_save_gpios(void) { - struct s3c_gpio_chip *ourchip; + struct samsung_gpio_chip *ourchip; unsigned int gpio_nr; for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) { - ourchip = s3c_gpiolib_getchip(gpio_nr); + ourchip = samsung_gpiolib_getchip(gpio_nr); if (!ourchip) { gpio_nr++; continue; } - s3c_pm_save_gpio(ourchip); + samsung_pm_save_gpio(ourchip); S3C_PMDBG("%s: save %08x,%08x,%08x,%08x\n", ourchip->chip.label, @@ -351,12 +355,12 @@ void s3c_pm_save_gpios(void) } /** - * s3c_pm_resume_gpio() - restore gpio chip data after suspend + * samsung_pm_resume_gpio() - restore gpio chip data after suspend * @ourchip: The suspended chip. */ -static void s3c_pm_resume_gpio(struct s3c_gpio_chip *ourchip) +static void samsung_pm_resume_gpio(struct samsung_gpio_chip *ourchip) { - struct s3c_gpio_pm *pm = ourchip->pm; + struct samsung_gpio_pm *pm = ourchip->pm; if (pm == NULL || pm->resume == NULL) S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label); @@ -364,19 +368,19 @@ static void s3c_pm_resume_gpio(struct s3c_gpio_chip *ourchip) pm->resume(ourchip); } -void s3c_pm_restore_gpios(void) +void samsung_pm_restore_gpios(void) { - struct s3c_gpio_chip *ourchip; + struct samsung_gpio_chip *ourchip; unsigned int gpio_nr; for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) { - ourchip = s3c_gpiolib_getchip(gpio_nr); + ourchip = samsung_gpiolib_getchip(gpio_nr); if (!ourchip) { gpio_nr++; continue; } - s3c_pm_resume_gpio(ourchip); + samsung_pm_resume_gpio(ourchip); gpio_nr += ourchip->chip.ngpio; gpio_nr += CONFIG_S3C_GPIO_SPACE; diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c index d5b58d31903..f8c0f9797dc 100644 --- a/arch/arm/plat-samsung/pm.c +++ b/arch/arm/plat-samsung/pm.c @@ -16,16 +16,22 @@ #include <linux/suspend.h> #include <linux/errno.h> #include <linux/delay.h> -#include <linux/serial_core.h> +#include <linux/of.h> +#include <linux/serial_s3c.h> #include <linux/io.h> #include <asm/cacheflush.h> -#include <mach/hardware.h> -#include <mach/map.h> +#include <asm/suspend.h> -#include <plat/regs-serial.h> +#ifdef CONFIG_SAMSUNG_ATAGS +#include <mach/map.h> +#ifndef CONFIG_ARCH_EXYNOS #include <mach/regs-clock.h> #include <mach/regs-irq.h> +#endif +#include <mach/irqs.h> +#endif + #include <asm/irq.h> #include <plat/pm.h> @@ -35,101 +41,6 @@ unsigned long s3c_pm_flags; -/* Debug code: - * - * This code supports debug output to the low level UARTs for use on - * resume before the console layer is available. -*/ - -#ifdef CONFIG_SAMSUNG_PM_DEBUG -extern void printascii(const char *); - -void s3c_pm_dbg(const char *fmt, ...) -{ - va_list va; - char buff[256]; - - va_start(va, fmt); - vsprintf(buff, fmt, va); - va_end(va); - - printascii(buff); -} - -static inline void s3c_pm_debug_init(void) -{ - /* restart uart clocks so we can use them to output */ - s3c_pm_debug_init_uart(); -} - -#else -#define s3c_pm_debug_init() do { } while(0) - -#endif /* CONFIG_SAMSUNG_PM_DEBUG */ - -/* Save the UART configurations if we are configured for debug. */ - -unsigned char pm_uart_udivslot; - -#ifdef CONFIG_SAMSUNG_PM_DEBUG - -struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS]; - -static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save) -{ - void __iomem *regs = S3C_VA_UARTx(uart); - - save->ulcon = __raw_readl(regs + S3C2410_ULCON); - save->ucon = __raw_readl(regs + S3C2410_UCON); - save->ufcon = __raw_readl(regs + S3C2410_UFCON); - save->umcon = __raw_readl(regs + S3C2410_UMCON); - save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV); - - if (pm_uart_udivslot) - save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT); - - S3C_PMDBG("UART[%d]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n", - uart, save->ulcon, save->ucon, save->ufcon, save->ubrdiv); -} - -static void s3c_pm_save_uarts(void) -{ - struct pm_uart_save *save = uart_save; - unsigned int uart; - - for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++) - s3c_pm_save_uart(uart, save); -} - -static void s3c_pm_restore_uart(unsigned int uart, struct pm_uart_save *save) -{ - void __iomem *regs = S3C_VA_UARTx(uart); - - s3c_pm_arch_update_uart(regs, save); - - __raw_writel(save->ulcon, regs + S3C2410_ULCON); - __raw_writel(save->ucon, regs + S3C2410_UCON); - __raw_writel(save->ufcon, regs + S3C2410_UFCON); - __raw_writel(save->umcon, regs + S3C2410_UMCON); - __raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV); - - if (pm_uart_udivslot) - __raw_writel(save->udivslot, regs + S3C2443_DIVSLOT); -} - -static void s3c_pm_restore_uarts(void) -{ - struct pm_uart_save *save = uart_save; - unsigned int uart; - - for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++) - s3c_pm_restore_uart(uart, save); -} -#else -static void s3c_pm_save_uarts(void) { } -static void s3c_pm_restore_uarts(void) { } -#endif - /* The IRQ ext-int code goes here, it is too small to currently bother * with its own file. */ @@ -154,68 +65,13 @@ int s3c_irqext_wake(struct irq_data *data, unsigned int state) return 0; } -/* helper functions to save and restore register state */ - -/** - * s3c_pm_do_save() - save a set of registers for restoration on resume. - * @ptr: Pointer to an array of registers. - * @count: Size of the ptr array. - * - * Run through the list of registers given, saving their contents in the - * array for later restoration when we wakeup. - */ -void s3c_pm_do_save(struct sleep_save *ptr, int count) -{ - for (; count > 0; count--, ptr++) { - ptr->val = __raw_readl(ptr->reg); - S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val); - } -} - -/** - * s3c_pm_do_restore() - restore register values from the save list. - * @ptr: Pointer to an array of registers. - * @count: Size of the ptr array. - * - * Restore the register values saved from s3c_pm_do_save(). - * - * Note, we do not use S3C_PMDBG() in here, as the system may not have - * restore the UARTs state yet -*/ - -void s3c_pm_do_restore(struct sleep_save *ptr, int count) -{ - for (; count > 0; count--, ptr++) { - printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n", - ptr->reg, ptr->val, __raw_readl(ptr->reg)); - - __raw_writel(ptr->val, ptr->reg); - } -} - -/** - * s3c_pm_do_restore_core() - early restore register values from save list. - * - * This is similar to s3c_pm_do_restore() except we try and minimise the - * side effects of the function in case registers that hardware might need - * to work has been restored. - * - * WARNING: Do not put any debug in here that may effect memory or use - * peripherals, as things may be changing! -*/ - -void s3c_pm_do_restore_core(struct sleep_save *ptr, int count) -{ - for (; count > 0; count--, ptr++) - __raw_writel(ptr->val, ptr->reg); -} - /* s3c2410_pm_show_resume_irqs * * print any IRQs asserted at resume time (ie, we woke from) */ -static void s3c_pm_show_resume_irqs(int start, unsigned long which, - unsigned long mask) +static void __maybe_unused s3c_pm_show_resume_irqs(int start, + unsigned long which, + unsigned long mask) { int i; @@ -230,7 +86,7 @@ static void s3c_pm_show_resume_irqs(int start, unsigned long which, void (*pm_cpu_prep)(void); -void (*pm_cpu_sleep)(void); +int (*pm_cpu_sleep)(unsigned long); #define any_allowed(mask, allow) (((mask) & (allow)) != (allow)) @@ -241,6 +97,7 @@ void (*pm_cpu_sleep)(void); static int s3c_pm_enter(suspend_state_t state) { + int ret; /* ensure the debug is initialised (if enabled) */ s3c_pm_debug_init(); @@ -257,7 +114,8 @@ static int s3c_pm_enter(suspend_state_t state) * require a full power-cycle) */ - if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) && + if (!of_have_populated_dt() && + !any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) && !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) { printk(KERN_ERR "%s: No wake-up sources!\n", __func__); printk(KERN_ERR "%s: Aborting sleep\n", __func__); @@ -266,7 +124,11 @@ static int s3c_pm_enter(suspend_state_t state) /* save all necessary core registers not covered by the drivers */ - s3c_pm_save_gpios(); + if (!of_have_populated_dt()) { + samsung_pm_save_gpios(); + samsung_pm_saved_gpios(); + } + s3c_pm_save_uarts(); s3c_pm_save_core(); @@ -293,21 +155,23 @@ static int s3c_pm_enter(suspend_state_t state) s3c_pm_arch_stop_clocks(); - /* s3c_cpu_save will also act as our return point from when + /* this will also act as our return point from when * we resume as it saves its own register state and restores it * during the resume. */ - s3c_cpu_save(0, PLAT_PHYS_OFFSET - PAGE_OFFSET); - - /* restore the cpu state using the kernel's cpu init code. */ - - cpu_init(); + ret = cpu_suspend(0, pm_cpu_sleep); + if (ret) + return ret; /* restore the system state */ s3c_pm_restore_core(); s3c_pm_restore_uarts(); - s3c_pm_restore_gpios(); + + if (!of_have_populated_dt()) { + samsung_pm_restore_gpios(); + s3c_pm_restored_gpios(); + } s3c_pm_debug_init(); diff --git a/arch/arm/plat-samsung/pwm-clock.c b/arch/arm/plat-samsung/pwm-clock.c deleted file mode 100644 index 46c9381e083..00000000000 --- a/arch/arm/plat-samsung/pwm-clock.c +++ /dev/null @@ -1,455 +0,0 @@ -/* linux/arch/arm/plat-s3c24xx/pwm-clock.c - * - * Copyright (c) 2007 Simtec Electronics - * Copyright (c) 2007, 2008 Ben Dooks - * Ben Dooks <ben-linux@fluff.org> - * - * 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. -*/ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/list.h> -#include <linux/errno.h> -#include <linux/log2.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/io.h> - -#include <mach/hardware.h> -#include <mach/map.h> -#include <asm/irq.h> - -#include <plat/clock.h> -#include <plat/cpu.h> - -#include <plat/regs-timer.h> -#include <mach/pwm-clock.h> - -/* Each of the timers 0 through 5 go through the following - * clock tree, with the inputs depending on the timers. - * - * pclk ---- [ prescaler 0 ] -+---> timer 0 - * +---> timer 1 - * - * pclk ---- [ prescaler 1 ] -+---> timer 2 - * +---> timer 3 - * \---> timer 4 - * - * Which are fed into the timers as so: - * - * prescaled 0 ---- [ div 2,4,8,16 ] ---\ - * [mux] -> timer 0 - * tclk 0 ------------------------------/ - * - * prescaled 0 ---- [ div 2,4,8,16 ] ---\ - * [mux] -> timer 1 - * tclk 0 ------------------------------/ - * - * - * prescaled 1 ---- [ div 2,4,8,16 ] ---\ - * [mux] -> timer 2 - * tclk 1 ------------------------------/ - * - * prescaled 1 ---- [ div 2,4,8,16 ] ---\ - * [mux] -> timer 3 - * tclk 1 ------------------------------/ - * - * prescaled 1 ---- [ div 2,4,8, 16 ] --\ - * [mux] -> timer 4 - * tclk 1 ------------------------------/ - * - * Since the mux and the divider are tied together in the - * same register space, it is impossible to set the parent - * and the rate at the same time. To avoid this, we add an - * intermediate 'prescaled-and-divided' clock to select - * as the parent for the timer input clock called tdiv. - * - * prescaled clk --> pwm-tdiv ---\ - * [ mux ] --> timer X - * tclk -------------------------/ -*/ - -static struct clk clk_timer_scaler[]; - -static unsigned long clk_pwm_scaler_get_rate(struct clk *clk) -{ - unsigned long tcfg0 = __raw_readl(S3C2410_TCFG0); - - if (clk == &clk_timer_scaler[1]) { - tcfg0 &= S3C2410_TCFG_PRESCALER1_MASK; - tcfg0 >>= S3C2410_TCFG_PRESCALER1_SHIFT; - } else { - tcfg0 &= S3C2410_TCFG_PRESCALER0_MASK; - } - - return clk_get_rate(clk->parent) / (tcfg0 + 1); -} - -static unsigned long clk_pwm_scaler_round_rate(struct clk *clk, - unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long divisor = parent_rate / rate; - - if (divisor > 256) - divisor = 256; - else if (divisor < 2) - divisor = 2; - - return parent_rate / divisor; -} - -static int clk_pwm_scaler_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned long round = clk_pwm_scaler_round_rate(clk, rate); - unsigned long tcfg0; - unsigned long divisor; - unsigned long flags; - - divisor = clk_get_rate(clk->parent) / round; - divisor--; - - local_irq_save(flags); - tcfg0 = __raw_readl(S3C2410_TCFG0); - - if (clk == &clk_timer_scaler[1]) { - tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK; - tcfg0 |= divisor << S3C2410_TCFG_PRESCALER1_SHIFT; - } else { - tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK; - tcfg0 |= divisor; - } - - __raw_writel(tcfg0, S3C2410_TCFG0); - local_irq_restore(flags); - - return 0; -} - -static struct clk_ops clk_pwm_scaler_ops = { - .get_rate = clk_pwm_scaler_get_rate, - .set_rate = clk_pwm_scaler_set_rate, - .round_rate = clk_pwm_scaler_round_rate, -}; - -static struct clk clk_timer_scaler[] = { - [0] = { - .name = "pwm-scaler0", - .id = -1, - .ops = &clk_pwm_scaler_ops, - }, - [1] = { - .name = "pwm-scaler1", - .id = -1, - .ops = &clk_pwm_scaler_ops, - }, -}; - -static struct clk clk_timer_tclk[] = { - [0] = { - .name = "pwm-tclk0", - .id = -1, - }, - [1] = { - .name = "pwm-tclk1", - .id = -1, - }, -}; - -struct pwm_tdiv_clk { - struct clk clk; - unsigned int divisor; -}; - -static inline struct pwm_tdiv_clk *to_tdiv(struct clk *clk) -{ - return container_of(clk, struct pwm_tdiv_clk, clk); -} - -static unsigned long clk_pwm_tdiv_get_rate(struct clk *clk) -{ - unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1); - unsigned int divisor; - - tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id); - tcfg1 &= S3C2410_TCFG1_MUX_MASK; - - if (pwm_cfg_src_is_tclk(tcfg1)) - divisor = to_tdiv(clk)->divisor; - else - divisor = tcfg_to_divisor(tcfg1); - - return clk_get_rate(clk->parent) / divisor; -} - -static unsigned long clk_pwm_tdiv_round_rate(struct clk *clk, - unsigned long rate) -{ - unsigned long parent_rate; - unsigned long divisor; - - parent_rate = clk_get_rate(clk->parent); - divisor = parent_rate / rate; - - if (divisor <= 1 && pwm_tdiv_has_div1()) - divisor = 1; - else if (divisor <= 2) - divisor = 2; - else if (divisor <= 4) - divisor = 4; - else if (divisor <= 8) - divisor = 8; - else - divisor = 16; - - return parent_rate / divisor; -} - -static unsigned long clk_pwm_tdiv_bits(struct pwm_tdiv_clk *divclk) -{ - return pwm_tdiv_div_bits(divclk->divisor); -} - -static void clk_pwm_tdiv_update(struct pwm_tdiv_clk *divclk) -{ - unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1); - unsigned long bits = clk_pwm_tdiv_bits(divclk); - unsigned long flags; - unsigned long shift = S3C2410_TCFG1_SHIFT(divclk->clk.id); - - local_irq_save(flags); - - tcfg1 = __raw_readl(S3C2410_TCFG1); - tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift); - tcfg1 |= bits << shift; - __raw_writel(tcfg1, S3C2410_TCFG1); - - local_irq_restore(flags); -} - -static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate) -{ - struct pwm_tdiv_clk *divclk = to_tdiv(clk); - unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1); - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long divisor; - - tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id); - tcfg1 &= S3C2410_TCFG1_MUX_MASK; - - rate = clk_round_rate(clk, rate); - divisor = parent_rate / rate; - - if (divisor > 16) - return -EINVAL; - - divclk->divisor = divisor; - - /* Update the current MUX settings if we are currently - * selected as the clock source for this clock. */ - - if (!pwm_cfg_src_is_tclk(tcfg1)) - clk_pwm_tdiv_update(divclk); - - return 0; -} - -static struct clk_ops clk_tdiv_ops = { - .get_rate = clk_pwm_tdiv_get_rate, - .set_rate = clk_pwm_tdiv_set_rate, - .round_rate = clk_pwm_tdiv_round_rate, -}; - -static struct pwm_tdiv_clk clk_timer_tdiv[] = { - [0] = { - .clk = { - .name = "pwm-tdiv", - .ops = &clk_tdiv_ops, - .parent = &clk_timer_scaler[0], - }, - }, - [1] = { - .clk = { - .name = "pwm-tdiv", - .ops = &clk_tdiv_ops, - .parent = &clk_timer_scaler[0], - } - }, - [2] = { - .clk = { - .name = "pwm-tdiv", - .ops = &clk_tdiv_ops, - .parent = &clk_timer_scaler[1], - }, - }, - [3] = { - .clk = { - .name = "pwm-tdiv", - .ops = &clk_tdiv_ops, - .parent = &clk_timer_scaler[1], - }, - }, - [4] = { - .clk = { - .name = "pwm-tdiv", - .ops = &clk_tdiv_ops, - .parent = &clk_timer_scaler[1], - }, - }, -}; - -static int __init clk_pwm_tdiv_register(unsigned int id) -{ - struct pwm_tdiv_clk *divclk = &clk_timer_tdiv[id]; - unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1); - - tcfg1 >>= S3C2410_TCFG1_SHIFT(id); - tcfg1 &= S3C2410_TCFG1_MUX_MASK; - - divclk->clk.id = id; - divclk->divisor = tcfg_to_divisor(tcfg1); - - return s3c24xx_register_clock(&divclk->clk); -} - -static inline struct clk *s3c24xx_pwmclk_tclk(unsigned int id) -{ - return (id >= 2) ? &clk_timer_tclk[1] : &clk_timer_tclk[0]; -} - -static inline struct clk *s3c24xx_pwmclk_tdiv(unsigned int id) -{ - return &clk_timer_tdiv[id].clk; -} - -static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent) -{ - unsigned int id = clk->id; - unsigned long tcfg1; - unsigned long flags; - unsigned long bits; - unsigned long shift = S3C2410_TCFG1_SHIFT(id); - - if (parent == s3c24xx_pwmclk_tclk(id)) - bits = S3C_TCFG1_MUX_TCLK << shift; - else if (parent == s3c24xx_pwmclk_tdiv(id)) - bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift; - else - return -EINVAL; - - clk->parent = parent; - - local_irq_save(flags); - - tcfg1 = __raw_readl(S3C2410_TCFG1); - tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift); - __raw_writel(tcfg1 | bits, S3C2410_TCFG1); - - local_irq_restore(flags); - - return 0; -} - -static struct clk_ops clk_tin_ops = { - .set_parent = clk_pwm_tin_set_parent, -}; - -static struct clk clk_tin[] = { - [0] = { - .name = "pwm-tin", - .id = 0, - .ops = &clk_tin_ops, - }, - [1] = { - .name = "pwm-tin", - .id = 1, - .ops = &clk_tin_ops, - }, - [2] = { - .name = "pwm-tin", - .id = 2, - .ops = &clk_tin_ops, - }, - [3] = { - .name = "pwm-tin", - .id = 3, - .ops = &clk_tin_ops, - }, - [4] = { - .name = "pwm-tin", - .id = 4, - .ops = &clk_tin_ops, - }, -}; - -static __init int clk_pwm_tin_register(struct clk *pwm) -{ - unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1); - unsigned int id = pwm->id; - - struct clk *parent; - int ret; - - ret = s3c24xx_register_clock(pwm); - if (ret < 0) - return ret; - - tcfg1 >>= S3C2410_TCFG1_SHIFT(id); - tcfg1 &= S3C2410_TCFG1_MUX_MASK; - - if (pwm_cfg_src_is_tclk(tcfg1)) - parent = s3c24xx_pwmclk_tclk(id); - else - parent = s3c24xx_pwmclk_tdiv(id); - - return clk_set_parent(pwm, parent); -} - -/** - * s3c_pwmclk_init() - initialise pwm clocks - * - * Initialise and register the clocks which provide the inputs for the - * pwm timer blocks. - * - * Note, this call is required by the time core, so must be called after - * the base clocks are added and before any of the initcalls are run. - */ -__init void s3c_pwmclk_init(void) -{ - struct clk *clk_timers; - unsigned int clk; - int ret; - - clk_timers = clk_get(NULL, "timers"); - if (IS_ERR(clk_timers)) { - printk(KERN_ERR "%s: no parent clock\n", __func__); - return; - } - - for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++) - clk_timer_scaler[clk].parent = clk_timers; - - s3c_register_clocks(clk_timer_scaler, ARRAY_SIZE(clk_timer_scaler)); - s3c_register_clocks(clk_timer_tclk, ARRAY_SIZE(clk_timer_tclk)); - - for (clk = 0; clk < ARRAY_SIZE(clk_timer_tdiv); clk++) { - ret = clk_pwm_tdiv_register(clk); - - if (ret < 0) { - printk(KERN_ERR "error adding pwm%d tdiv clock\n", clk); - return; - } - } - - for (clk = 0; clk < ARRAY_SIZE(clk_tin); clk++) { - ret = clk_pwm_tin_register(&clk_tin[clk]); - if (ret < 0) { - printk(KERN_ERR "error adding pwm%d tin clock\n", clk); - return; - } - } -} diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c deleted file mode 100644 index f37457c5206..00000000000 --- a/arch/arm/plat-samsung/pwm.c +++ /dev/null @@ -1,413 +0,0 @@ -/* arch/arm/plat-s3c/pwm.c - * - * Copyright (c) 2007 Ben Dooks - * Copyright (c) 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org> - * - * S3C series PWM device core - * - * 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. -*/ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/pwm.h> - -#include <mach/map.h> - -#include <plat/regs-timer.h> - -struct pwm_device { - struct list_head list; - struct platform_device *pdev; - - struct clk *clk_div; - struct clk *clk; - const char *label; - - unsigned int period_ns; - unsigned int duty_ns; - - unsigned char tcon_base; - unsigned char running; - unsigned char use_count; - unsigned char pwm_id; -}; - -#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg) - -static struct clk *clk_scaler[2]; - -static inline int pwm_is_tdiv(struct pwm_device *pwm) -{ - return clk_get_parent(pwm->clk) == pwm->clk_div; -} - -static DEFINE_MUTEX(pwm_lock); -static LIST_HEAD(pwm_list); - -struct pwm_device *pwm_request(int pwm_id, const char *label) -{ - struct pwm_device *pwm; - int found = 0; - - mutex_lock(&pwm_lock); - - list_for_each_entry(pwm, &pwm_list, list) { - if (pwm->pwm_id == pwm_id) { - found = 1; - break; - } - } - - if (found) { - if (pwm->use_count == 0) { - pwm->use_count = 1; - pwm->label = label; - } else - pwm = ERR_PTR(-EBUSY); - } else - pwm = ERR_PTR(-ENOENT); - - mutex_unlock(&pwm_lock); - return pwm; -} - -EXPORT_SYMBOL(pwm_request); - - -void pwm_free(struct pwm_device *pwm) -{ - mutex_lock(&pwm_lock); - - if (pwm->use_count) { - pwm->use_count--; - pwm->label = NULL; - } else - printk(KERN_ERR "PWM%d device already freed\n", pwm->pwm_id); - - mutex_unlock(&pwm_lock); -} - -EXPORT_SYMBOL(pwm_free); - -#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0)) -#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2)) -#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3)) -#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1)) - -int pwm_enable(struct pwm_device *pwm) -{ - unsigned long flags; - unsigned long tcon; - - local_irq_save(flags); - - tcon = __raw_readl(S3C2410_TCON); - tcon |= pwm_tcon_start(pwm); - __raw_writel(tcon, S3C2410_TCON); - - local_irq_restore(flags); - - pwm->running = 1; - return 0; -} - -EXPORT_SYMBOL(pwm_enable); - -void pwm_disable(struct pwm_device *pwm) -{ - unsigned long flags; - unsigned long tcon; - - local_irq_save(flags); - - tcon = __raw_readl(S3C2410_TCON); - tcon &= ~pwm_tcon_start(pwm); - __raw_writel(tcon, S3C2410_TCON); - - local_irq_restore(flags); - - pwm->running = 0; -} - -EXPORT_SYMBOL(pwm_disable); - -static unsigned long pwm_calc_tin(struct pwm_device *pwm, unsigned long freq) -{ - unsigned long tin_parent_rate; - unsigned int div; - - tin_parent_rate = clk_get_rate(clk_get_parent(pwm->clk_div)); - pwm_dbg(pwm, "tin parent at %lu\n", tin_parent_rate); - - for (div = 2; div <= 16; div *= 2) { - if ((tin_parent_rate / (div << 16)) < freq) - return tin_parent_rate / div; - } - - return tin_parent_rate / 16; -} - -#define NS_IN_HZ (1000000000UL) - -int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) -{ - unsigned long tin_rate; - unsigned long tin_ns; - unsigned long period; - unsigned long flags; - unsigned long tcon; - unsigned long tcnt; - long tcmp; - - /* We currently avoid using 64bit arithmetic by using the - * fact that anything faster than 1Hz is easily representable - * by 32bits. */ - - if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ) - return -ERANGE; - - if (duty_ns > period_ns) - return -EINVAL; - - if (period_ns == pwm->period_ns && - duty_ns == pwm->duty_ns) - return 0; - - /* The TCMP and TCNT can be read without a lock, they're not - * shared between the timers. */ - - tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id)); - tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id)); - - period = NS_IN_HZ / period_ns; - - pwm_dbg(pwm, "duty_ns=%d, period_ns=%d (%lu)\n", - duty_ns, period_ns, period); - - /* Check to see if we are changing the clock rate of the PWM */ - - if (pwm->period_ns != period_ns) { - if (pwm_is_tdiv(pwm)) { - tin_rate = pwm_calc_tin(pwm, period); - clk_set_rate(pwm->clk_div, tin_rate); - } else - tin_rate = clk_get_rate(pwm->clk); - - pwm->period_ns = period_ns; - - pwm_dbg(pwm, "tin_rate=%lu\n", tin_rate); - - tin_ns = NS_IN_HZ / tin_rate; - tcnt = period_ns / tin_ns; - } else - tin_ns = NS_IN_HZ / clk_get_rate(pwm->clk); - - /* Note, counters count down */ - - tcmp = duty_ns / tin_ns; - tcmp = tcnt - tcmp; - /* the pwm hw only checks the compare register after a decrement, - so the pin never toggles if tcmp = tcnt */ - if (tcmp == tcnt) - tcmp--; - - pwm_dbg(pwm, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt); - - if (tcmp < 0) - tcmp = 0; - - /* Update the PWM register block. */ - - local_irq_save(flags); - - __raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id)); - __raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id)); - - tcon = __raw_readl(S3C2410_TCON); - tcon |= pwm_tcon_manulupdate(pwm); - tcon |= pwm_tcon_autoreload(pwm); - __raw_writel(tcon, S3C2410_TCON); - - tcon &= ~pwm_tcon_manulupdate(pwm); - __raw_writel(tcon, S3C2410_TCON); - - local_irq_restore(flags); - - return 0; -} - -EXPORT_SYMBOL(pwm_config); - -static int pwm_register(struct pwm_device *pwm) -{ - pwm->duty_ns = -1; - pwm->period_ns = -1; - - mutex_lock(&pwm_lock); - list_add_tail(&pwm->list, &pwm_list); - mutex_unlock(&pwm_lock); - - return 0; -} - -static int s3c_pwm_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct pwm_device *pwm; - unsigned long flags; - unsigned long tcon; - unsigned int id = pdev->id; - int ret; - - if (id == 4) { - dev_err(dev, "TIMER4 is currently not supported\n"); - return -ENXIO; - } - - pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); - if (pwm == NULL) { - dev_err(dev, "failed to allocate pwm_device\n"); - return -ENOMEM; - } - - pwm->pdev = pdev; - pwm->pwm_id = id; - - /* calculate base of control bits in TCON */ - pwm->tcon_base = id == 0 ? 0 : (id * 4) + 4; - - pwm->clk = clk_get(dev, "pwm-tin"); - if (IS_ERR(pwm->clk)) { - dev_err(dev, "failed to get pwm tin clk\n"); - ret = PTR_ERR(pwm->clk); - goto err_alloc; - } - - pwm->clk_div = clk_get(dev, "pwm-tdiv"); - if (IS_ERR(pwm->clk_div)) { - dev_err(dev, "failed to get pwm tdiv clk\n"); - ret = PTR_ERR(pwm->clk_div); - goto err_clk_tin; - } - - local_irq_save(flags); - - tcon = __raw_readl(S3C2410_TCON); - tcon |= pwm_tcon_invert(pwm); - __raw_writel(tcon, S3C2410_TCON); - - local_irq_restore(flags); - - - ret = pwm_register(pwm); - if (ret) { - dev_err(dev, "failed to register pwm\n"); - goto err_clk_tdiv; - } - - pwm_dbg(pwm, "config bits %02x\n", - (__raw_readl(S3C2410_TCON) >> pwm->tcon_base) & 0x0f); - - dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n", - clk_get_rate(pwm->clk), - clk_get_rate(pwm->clk_div), - pwm_is_tdiv(pwm) ? "div" : "ext", pwm->tcon_base); - - platform_set_drvdata(pdev, pwm); - return 0; - - err_clk_tdiv: - clk_put(pwm->clk_div); - - err_clk_tin: - clk_put(pwm->clk); - - err_alloc: - kfree(pwm); - return ret; -} - -static int __devexit s3c_pwm_remove(struct platform_device *pdev) -{ - struct pwm_device *pwm = platform_get_drvdata(pdev); - - clk_put(pwm->clk_div); - clk_put(pwm->clk); - kfree(pwm); - - return 0; -} - -#ifdef CONFIG_PM -static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct pwm_device *pwm = platform_get_drvdata(pdev); - - /* No one preserve these values during suspend so reset them - * Otherwise driver leaves PWM unconfigured if same values - * passed to pwm_config - */ - pwm->period_ns = 0; - pwm->duty_ns = 0; - - return 0; -} - -static int s3c_pwm_resume(struct platform_device *pdev) -{ - struct pwm_device *pwm = platform_get_drvdata(pdev); - unsigned long tcon; - - /* Restore invertion */ - tcon = __raw_readl(S3C2410_TCON); - tcon |= pwm_tcon_invert(pwm); - __raw_writel(tcon, S3C2410_TCON); - - return 0; -} - -#else -#define s3c_pwm_suspend NULL -#define s3c_pwm_resume NULL -#endif - -static struct platform_driver s3c_pwm_driver = { - .driver = { - .name = "s3c24xx-pwm", - .owner = THIS_MODULE, - }, - .probe = s3c_pwm_probe, - .remove = __devexit_p(s3c_pwm_remove), - .suspend = s3c_pwm_suspend, - .resume = s3c_pwm_resume, -}; - -static int __init pwm_init(void) -{ - int ret; - - clk_scaler[0] = clk_get(NULL, "pwm-scaler0"); - clk_scaler[1] = clk_get(NULL, "pwm-scaler1"); - - if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) { - printk(KERN_ERR "%s: failed to get scaler clocks\n", __func__); - return -EINVAL; - } - - ret = platform_driver_register(&s3c_pwm_driver); - if (ret) - printk(KERN_ERR "%s: failed to add pwm driver\n", __func__); - - return ret; -} - -arch_initcall(pwm_init); diff --git a/arch/arm/plat-samsung/s3c-dma-ops.c b/arch/arm/plat-samsung/s3c-dma-ops.c new file mode 100644 index 00000000000..98b10ba67dc --- /dev/null +++ b/arch/arm/plat-samsung/s3c-dma-ops.c @@ -0,0 +1,146 @@ +/* linux/arch/arm/plat-samsung/s3c-dma-ops.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Samsung S3C-DMA Operations + * + * 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/errno.h> +#include <linux/slab.h> +#include <linux/types.h> +#include <linux/export.h> + +#include <mach/dma.h> + +struct cb_data { + void (*fp) (void *); + void *fp_param; + unsigned ch; + struct list_head node; +}; + +static LIST_HEAD(dma_list); + +static void s3c_dma_cb(struct s3c2410_dma_chan *channel, void *param, + int size, enum s3c2410_dma_buffresult res) +{ + struct cb_data *data = param; + + data->fp(data->fp_param); +} + +static unsigned s3c_dma_request(enum dma_ch dma_ch, + struct samsung_dma_req *param, + struct device *dev, char *ch_name) +{ + struct cb_data *data; + + if (s3c2410_dma_request(dma_ch, param->client, NULL) < 0) { + s3c2410_dma_free(dma_ch, param->client); + return 0; + } + + if (param->cap == DMA_CYCLIC) + s3c2410_dma_setflags(dma_ch, S3C2410_DMAF_CIRCULAR); + + data = kzalloc(sizeof(struct cb_data), GFP_KERNEL); + data->ch = dma_ch; + list_add_tail(&data->node, &dma_list); + + return (unsigned)dma_ch; +} + +static int s3c_dma_release(unsigned ch, void *param) +{ + struct cb_data *data; + + list_for_each_entry(data, &dma_list, node) + if (data->ch == ch) + break; + list_del(&data->node); + + s3c2410_dma_free(ch, param); + kfree(data); + + return 0; +} + +static int s3c_dma_config(unsigned ch, struct samsung_dma_config *param) +{ + s3c2410_dma_devconfig(ch, param->direction, param->fifo); + s3c2410_dma_config(ch, param->width); + + return 0; +} + +static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep *param) +{ + struct cb_data *data; + dma_addr_t pos = param->buf; + dma_addr_t end = param->buf + param->len; + + list_for_each_entry(data, &dma_list, node) + if (data->ch == ch) + break; + + if (!data->fp) { + s3c2410_dma_set_buffdone_fn(ch, s3c_dma_cb); + data->fp = param->fp; + data->fp_param = param->fp_param; + } + + if (param->cap != DMA_CYCLIC) { + s3c2410_dma_enqueue(ch, (void *)data, param->buf, param->len); + return 0; + } + + while (pos < end) { + s3c2410_dma_enqueue(ch, (void *)data, pos, param->period); + pos += param->period; + } + + return 0; +} + +static inline int s3c_dma_trigger(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_START); +} + +static inline int s3c_dma_started(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STARTED); +} + +static inline int s3c_dma_flush(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_FLUSH); +} + +static inline int s3c_dma_stop(unsigned ch) +{ + return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STOP); +} + +static struct samsung_dma_ops s3c_dma_ops = { + .request = s3c_dma_request, + .release = s3c_dma_release, + .config = s3c_dma_config, + .prepare = s3c_dma_prepare, + .trigger = s3c_dma_trigger, + .started = s3c_dma_started, + .flush = s3c_dma_flush, + .stop = s3c_dma_stop, +}; + +void *s3c_dma_get_ops(void) +{ + return &s3c_dma_ops; +} +EXPORT_SYMBOL(s3c_dma_get_ops); diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c deleted file mode 100644 index b4ff8d74ac4..00000000000 --- a/arch/arm/plat-samsung/s3c-pl330.c +++ /dev/null @@ -1,1244 +0,0 @@ -/* linux/arch/arm/plat-samsung/s3c-pl330.c - * - * Copyright (C) 2010 Samsung Electronics Co. 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 as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/io.h> -#include <linux/slab.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/err.h> - -#include <asm/hardware/pl330.h> - -#include <plat/s3c-pl330-pdata.h> - -/** - * struct s3c_pl330_dmac - Logical representation of a PL330 DMAC. - * @busy_chan: Number of channels currently busy. - * @peri: List of IDs of peripherals this DMAC can work with. - * @node: To attach to the global list of DMACs. - * @pi: PL330 configuration info for the DMAC. - * @kmcache: Pool to quickly allocate xfers for all channels in the dmac. - * @clk: Pointer of DMAC operation clock. - */ -struct s3c_pl330_dmac { - unsigned busy_chan; - enum dma_ch *peri; - struct list_head node; - struct pl330_info *pi; - struct kmem_cache *kmcache; - struct clk *clk; -}; - -/** - * struct s3c_pl330_xfer - A request submitted by S3C DMA clients. - * @token: Xfer ID provided by the client. - * @node: To attach to the list of xfers on a channel. - * @px: Xfer for PL330 core. - * @chan: Owner channel of this xfer. - */ -struct s3c_pl330_xfer { - void *token; - struct list_head node; - struct pl330_xfer px; - struct s3c_pl330_chan *chan; -}; - -/** - * struct s3c_pl330_chan - Logical channel to communicate with - * a Physical peripheral. - * @pl330_chan_id: Token of a hardware channel thread of PL330 DMAC. - * NULL if the channel is available to be acquired. - * @id: ID of the peripheral that this channel can communicate with. - * @options: Options specified by the client. - * @sdaddr: Address provided via s3c2410_dma_devconfig. - * @node: To attach to the global list of channels. - * @lrq: Pointer to the last submitted pl330_req to PL330 core. - * @xfer_list: To manage list of xfers enqueued. - * @req: Two requests to communicate with the PL330 engine. - * @callback_fn: Callback function to the client. - * @rqcfg: Channel configuration for the xfers. - * @xfer_head: Pointer to the xfer to be next excecuted. - * @dmac: Pointer to the DMAC that manages this channel, NULL if the - * channel is available to be acquired. - * @client: Client of this channel. NULL if the - * channel is available to be acquired. - */ -struct s3c_pl330_chan { - void *pl330_chan_id; - enum dma_ch id; - unsigned int options; - unsigned long sdaddr; - struct list_head node; - struct pl330_req *lrq; - struct list_head xfer_list; - struct pl330_req req[2]; - s3c2410_dma_cbfn_t callback_fn; - struct pl330_reqcfg rqcfg; - struct s3c_pl330_xfer *xfer_head; - struct s3c_pl330_dmac *dmac; - struct s3c2410_dma_client *client; -}; - -/* All DMACs in the platform */ -static LIST_HEAD(dmac_list); - -/* All channels to peripherals in the platform */ -static LIST_HEAD(chan_list); - -/* - * Since we add resources(DMACs and Channels) to the global pool, - * we need to guard access to the resources using a global lock - */ -static DEFINE_SPINLOCK(res_lock); - -/* Returns the channel with ID 'id' in the chan_list */ -static struct s3c_pl330_chan *id_to_chan(const enum dma_ch id) -{ - struct s3c_pl330_chan *ch; - - list_for_each_entry(ch, &chan_list, node) - if (ch->id == id) - return ch; - - return NULL; -} - -/* Allocate a new channel with ID 'id' and add to chan_list */ -static void chan_add(const enum dma_ch id) -{ - struct s3c_pl330_chan *ch = id_to_chan(id); - - /* Return if the channel already exists */ - if (ch) - return; - - ch = kmalloc(sizeof(*ch), GFP_KERNEL); - /* Return silently to work with other channels */ - if (!ch) - return; - - ch->id = id; - ch->dmac = NULL; - - list_add_tail(&ch->node, &chan_list); -} - -/* If the channel is not yet acquired by any client */ -static bool chan_free(struct s3c_pl330_chan *ch) -{ - if (!ch) - return false; - - /* Channel points to some DMAC only when it's acquired */ - return ch->dmac ? false : true; -} - -/* - * Returns 0 is peripheral i/f is invalid or not present on the dmac. - * Index + 1, otherwise. - */ -static unsigned iface_of_dmac(struct s3c_pl330_dmac *dmac, enum dma_ch ch_id) -{ - enum dma_ch *id = dmac->peri; - int i; - - /* Discount invalid markers */ - if (ch_id == DMACH_MAX) - return 0; - - for (i = 0; i < PL330_MAX_PERI; i++) - if (id[i] == ch_id) - return i + 1; - - return 0; -} - -/* If all channel threads of the DMAC are busy */ -static inline bool dmac_busy(struct s3c_pl330_dmac *dmac) -{ - struct pl330_info *pi = dmac->pi; - - return (dmac->busy_chan < pi->pcfg.num_chan) ? false : true; -} - -/* - * Returns the number of free channels that - * can be handled by this dmac only. - */ -static unsigned ch_onlyby_dmac(struct s3c_pl330_dmac *dmac) -{ - enum dma_ch *id = dmac->peri; - struct s3c_pl330_dmac *d; - struct s3c_pl330_chan *ch; - unsigned found, count = 0; - enum dma_ch p; - int i; - - for (i = 0; i < PL330_MAX_PERI; i++) { - p = id[i]; - ch = id_to_chan(p); - - if (p == DMACH_MAX || !chan_free(ch)) - continue; - - found = 0; - list_for_each_entry(d, &dmac_list, node) { - if (d != dmac && iface_of_dmac(d, ch->id)) { - found = 1; - break; - } - } - if (!found) - count++; - } - - return count; -} - -/* - * Measure of suitability of 'dmac' handling 'ch' - * - * 0 indicates 'dmac' can not handle 'ch' either - * because it is not supported by the hardware or - * because all dmac channels are currently busy. - * - * >0 vlaue indicates 'dmac' has the capability. - * The bigger the value the more suitable the dmac. - */ -#define MAX_SUIT UINT_MAX -#define MIN_SUIT 0 - -static unsigned suitablility(struct s3c_pl330_dmac *dmac, - struct s3c_pl330_chan *ch) -{ - struct pl330_info *pi = dmac->pi; - enum dma_ch *id = dmac->peri; - struct s3c_pl330_dmac *d; - unsigned s; - int i; - - s = MIN_SUIT; - /* If all the DMAC channel threads are busy */ - if (dmac_busy(dmac)) - return s; - - for (i = 0; i < PL330_MAX_PERI; i++) - if (id[i] == ch->id) - break; - - /* If the 'dmac' can't talk to 'ch' */ - if (i == PL330_MAX_PERI) - return s; - - s = MAX_SUIT; - list_for_each_entry(d, &dmac_list, node) { - /* - * If some other dmac can talk to this - * peri and has some channel free. - */ - if (d != dmac && iface_of_dmac(d, ch->id) && !dmac_busy(d)) { - s = 0; - break; - } - } - if (s) - return s; - - s = 100; - - /* Good if free chans are more, bad otherwise */ - s += (pi->pcfg.num_chan - dmac->busy_chan) - ch_onlyby_dmac(dmac); - - return s; -} - -/* More than one DMAC may have capability to transfer data with the - * peripheral. This function assigns most suitable DMAC to manage the - * channel and hence communicate with the peripheral. - */ -static struct s3c_pl330_dmac *map_chan_to_dmac(struct s3c_pl330_chan *ch) -{ - struct s3c_pl330_dmac *d, *dmac = NULL; - unsigned sn, sl = MIN_SUIT; - - list_for_each_entry(d, &dmac_list, node) { - sn = suitablility(d, ch); - - if (sn == MAX_SUIT) - return d; - - if (sn > sl) - dmac = d; - } - - return dmac; -} - -/* Acquire the channel for peripheral 'id' */ -static struct s3c_pl330_chan *chan_acquire(const enum dma_ch id) -{ - struct s3c_pl330_chan *ch = id_to_chan(id); - struct s3c_pl330_dmac *dmac; - - /* If the channel doesn't exist or is already acquired */ - if (!ch || !chan_free(ch)) { - ch = NULL; - goto acq_exit; - } - - dmac = map_chan_to_dmac(ch); - /* If couldn't map */ - if (!dmac) { - ch = NULL; - goto acq_exit; - } - - dmac->busy_chan++; - ch->dmac = dmac; - -acq_exit: - return ch; -} - -/* Delete xfer from the queue */ -static inline void del_from_queue(struct s3c_pl330_xfer *xfer) -{ - struct s3c_pl330_xfer *t; - struct s3c_pl330_chan *ch; - int found; - - if (!xfer) - return; - - ch = xfer->chan; - - /* Make sure xfer is in the queue */ - found = 0; - list_for_each_entry(t, &ch->xfer_list, node) - if (t == xfer) { - found = 1; - break; - } - - if (!found) - return; - - /* If xfer is last entry in the queue */ - if (xfer->node.next == &ch->xfer_list) - t = list_entry(ch->xfer_list.next, - struct s3c_pl330_xfer, node); - else - t = list_entry(xfer->node.next, - struct s3c_pl330_xfer, node); - - /* If there was only one node left */ - if (t == xfer) - ch->xfer_head = NULL; - else if (ch->xfer_head == xfer) - ch->xfer_head = t; - - list_del(&xfer->node); -} - -/* Provides pointer to the next xfer in the queue. - * If CIRCULAR option is set, the list is left intact, - * otherwise the xfer is removed from the list. - * Forced delete 'pluck' can be set to override the CIRCULAR option. - */ -static struct s3c_pl330_xfer *get_from_queue(struct s3c_pl330_chan *ch, - int pluck) -{ - struct s3c_pl330_xfer *xfer = ch->xfer_head; - - if (!xfer) - return NULL; - - /* If xfer is last entry in the queue */ - if (xfer->node.next == &ch->xfer_list) - ch->xfer_head = list_entry(ch->xfer_list.next, - struct s3c_pl330_xfer, node); - else - ch->xfer_head = list_entry(xfer->node.next, - struct s3c_pl330_xfer, node); - - if (pluck || !(ch->options & S3C2410_DMAF_CIRCULAR)) - del_from_queue(xfer); - - return xfer; -} - -static inline void add_to_queue(struct s3c_pl330_chan *ch, - struct s3c_pl330_xfer *xfer, int front) -{ - struct pl330_xfer *xt; - - /* If queue empty */ - if (ch->xfer_head == NULL) - ch->xfer_head = xfer; - - xt = &ch->xfer_head->px; - /* If the head already submitted (CIRCULAR head) */ - if (ch->options & S3C2410_DMAF_CIRCULAR && - (xt == ch->req[0].x || xt == ch->req[1].x)) - ch->xfer_head = xfer; - - /* If this is a resubmission, it should go at the head */ - if (front) { - ch->xfer_head = xfer; - list_add(&xfer->node, &ch->xfer_list); - } else { - list_add_tail(&xfer->node, &ch->xfer_list); - } -} - -static inline void _finish_off(struct s3c_pl330_xfer *xfer, - enum s3c2410_dma_buffresult res, int ffree) -{ - struct s3c_pl330_chan *ch; - - if (!xfer) - return; - - ch = xfer->chan; - - /* Do callback */ - if (ch->callback_fn) - ch->callback_fn(NULL, xfer->token, xfer->px.bytes, res); - - /* Force Free or if buffer is not needed anymore */ - if (ffree || !(ch->options & S3C2410_DMAF_CIRCULAR)) - kmem_cache_free(ch->dmac->kmcache, xfer); -} - -static inline int s3c_pl330_submit(struct s3c_pl330_chan *ch, - struct pl330_req *r) -{ - struct s3c_pl330_xfer *xfer; - int ret = 0; - - /* If already submitted */ - if (r->x) - return 0; - - xfer = get_from_queue(ch, 0); - if (xfer) { - r->x = &xfer->px; - - /* Use max bandwidth for M<->M xfers */ - if (r->rqtype == MEMTOMEM) { - struct pl330_info *pi = xfer->chan->dmac->pi; - int burst = 1 << ch->rqcfg.brst_size; - u32 bytes = r->x->bytes; - int bl; - - bl = pi->pcfg.data_bus_width / 8; - bl *= pi->pcfg.data_buf_dep; - bl /= burst; - - /* src/dst_burst_len can't be more than 16 */ - if (bl > 16) - bl = 16; - - while (bl > 1) { - if (!(bytes % (bl * burst))) - break; - bl--; - } - - ch->rqcfg.brst_len = bl; - } else { - ch->rqcfg.brst_len = 1; - } - - ret = pl330_submit_req(ch->pl330_chan_id, r); - - /* If submission was successful */ - if (!ret) { - ch->lrq = r; /* latest submitted req */ - return 0; - } - - r->x = NULL; - - /* If both of the PL330 ping-pong buffers filled */ - if (ret == -EAGAIN) { - dev_err(ch->dmac->pi->dev, "%s:%d!\n", - __func__, __LINE__); - /* Queue back again */ - add_to_queue(ch, xfer, 1); - ret = 0; - } else { - dev_err(ch->dmac->pi->dev, "%s:%d!\n", - __func__, __LINE__); - _finish_off(xfer, S3C2410_RES_ERR, 0); - } - } - - return ret; -} - -static void s3c_pl330_rq(struct s3c_pl330_chan *ch, - struct pl330_req *r, enum pl330_op_err err) -{ - unsigned long flags; - struct s3c_pl330_xfer *xfer; - struct pl330_xfer *xl = r->x; - enum s3c2410_dma_buffresult res; - - spin_lock_irqsave(&res_lock, flags); - - r->x = NULL; - - s3c_pl330_submit(ch, r); - - spin_unlock_irqrestore(&res_lock, flags); - - /* Map result to S3C DMA API */ - if (err == PL330_ERR_NONE) - res = S3C2410_RES_OK; - else if (err == PL330_ERR_ABORT) - res = S3C2410_RES_ABORT; - else - res = S3C2410_RES_ERR; - - /* If last request had some xfer */ - if (xl) { - xfer = container_of(xl, struct s3c_pl330_xfer, px); - _finish_off(xfer, res, 0); - } else { - dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n", - __func__, __LINE__); - } -} - -static void s3c_pl330_rq0(void *token, enum pl330_op_err err) -{ - struct pl330_req *r = token; - struct s3c_pl330_chan *ch = container_of(r, - struct s3c_pl330_chan, req[0]); - s3c_pl330_rq(ch, r, err); -} - -static void s3c_pl330_rq1(void *token, enum pl330_op_err err) -{ - struct pl330_req *r = token; - struct s3c_pl330_chan *ch = container_of(r, - struct s3c_pl330_chan, req[1]); - s3c_pl330_rq(ch, r, err); -} - -/* Release an acquired channel */ -static void chan_release(struct s3c_pl330_chan *ch) -{ - struct s3c_pl330_dmac *dmac; - - if (chan_free(ch)) - return; - - dmac = ch->dmac; - ch->dmac = NULL; - dmac->busy_chan--; -} - -int s3c2410_dma_ctrl(enum dma_ch id, enum s3c2410_chan_op op) -{ - struct s3c_pl330_xfer *xfer; - enum pl330_chan_op pl330op; - struct s3c_pl330_chan *ch; - unsigned long flags; - int idx, ret; - - spin_lock_irqsave(&res_lock, flags); - - ch = id_to_chan(id); - - if (!ch || chan_free(ch)) { - ret = -EINVAL; - goto ctrl_exit; - } - - switch (op) { - case S3C2410_DMAOP_START: - /* Make sure both reqs are enqueued */ - idx = (ch->lrq == &ch->req[0]) ? 1 : 0; - s3c_pl330_submit(ch, &ch->req[idx]); - s3c_pl330_submit(ch, &ch->req[1 - idx]); - pl330op = PL330_OP_START; - break; - - case S3C2410_DMAOP_STOP: - pl330op = PL330_OP_ABORT; - break; - - case S3C2410_DMAOP_FLUSH: - pl330op = PL330_OP_FLUSH; - break; - - case S3C2410_DMAOP_PAUSE: - case S3C2410_DMAOP_RESUME: - case S3C2410_DMAOP_TIMEOUT: - case S3C2410_DMAOP_STARTED: - spin_unlock_irqrestore(&res_lock, flags); - return 0; - - default: - spin_unlock_irqrestore(&res_lock, flags); - return -EINVAL; - } - - ret = pl330_chan_ctrl(ch->pl330_chan_id, pl330op); - - if (pl330op == PL330_OP_START) { - spin_unlock_irqrestore(&res_lock, flags); - return ret; - } - - idx = (ch->lrq == &ch->req[0]) ? 1 : 0; - - /* Abort the current xfer */ - if (ch->req[idx].x) { - xfer = container_of(ch->req[idx].x, - struct s3c_pl330_xfer, px); - - /* Drop xfer during FLUSH */ - if (pl330op == PL330_OP_FLUSH) - del_from_queue(xfer); - - ch->req[idx].x = NULL; - - spin_unlock_irqrestore(&res_lock, flags); - _finish_off(xfer, S3C2410_RES_ABORT, - pl330op == PL330_OP_FLUSH ? 1 : 0); - spin_lock_irqsave(&res_lock, flags); - } - - /* Flush the whole queue */ - if (pl330op == PL330_OP_FLUSH) { - - if (ch->req[1 - idx].x) { - xfer = container_of(ch->req[1 - idx].x, - struct s3c_pl330_xfer, px); - - del_from_queue(xfer); - - ch->req[1 - idx].x = NULL; - - spin_unlock_irqrestore(&res_lock, flags); - _finish_off(xfer, S3C2410_RES_ABORT, 1); - spin_lock_irqsave(&res_lock, flags); - } - - /* Finish off the remaining in the queue */ - xfer = ch->xfer_head; - while (xfer) { - - del_from_queue(xfer); - - spin_unlock_irqrestore(&res_lock, flags); - _finish_off(xfer, S3C2410_RES_ABORT, 1); - spin_lock_irqsave(&res_lock, flags); - - xfer = ch->xfer_head; - } - } - -ctrl_exit: - spin_unlock_irqrestore(&res_lock, flags); - - return ret; -} -EXPORT_SYMBOL(s3c2410_dma_ctrl); - -int s3c2410_dma_enqueue(enum dma_ch id, void *token, - dma_addr_t addr, int size) -{ - struct s3c_pl330_chan *ch; - struct s3c_pl330_xfer *xfer; - unsigned long flags; - int idx, ret = 0; - - spin_lock_irqsave(&res_lock, flags); - - ch = id_to_chan(id); - - /* Error if invalid or free channel */ - if (!ch || chan_free(ch)) { - ret = -EINVAL; - goto enq_exit; - } - - /* Error if size is unaligned */ - if (ch->rqcfg.brst_size && size % (1 << ch->rqcfg.brst_size)) { - ret = -EINVAL; - goto enq_exit; - } - - xfer = kmem_cache_alloc(ch->dmac->kmcache, GFP_ATOMIC); - if (!xfer) { - ret = -ENOMEM; - goto enq_exit; - } - - xfer->token = token; - xfer->chan = ch; - xfer->px.bytes = size; - xfer->px.next = NULL; /* Single request */ - - /* For S3C DMA API, direction is always fixed for all xfers */ - if (ch->req[0].rqtype == MEMTODEV) { - xfer->px.src_addr = addr; - xfer->px.dst_addr = ch->sdaddr; - } else { - xfer->px.src_addr = ch->sdaddr; - xfer->px.dst_addr = addr; - } - - add_to_queue(ch, xfer, 0); - - /* Try submitting on either request */ - idx = (ch->lrq == &ch->req[0]) ? 1 : 0; - - if (!ch->req[idx].x) - s3c_pl330_submit(ch, &ch->req[idx]); - else - s3c_pl330_submit(ch, &ch->req[1 - idx]); - - spin_unlock_irqrestore(&res_lock, flags); - - if (ch->options & S3C2410_DMAF_AUTOSTART) - s3c2410_dma_ctrl(id, S3C2410_DMAOP_START); - - return 0; - -enq_exit: - spin_unlock_irqrestore(&res_lock, flags); - - return ret; -} -EXPORT_SYMBOL(s3c2410_dma_enqueue); - -int s3c2410_dma_request(enum dma_ch id, - struct s3c2410_dma_client *client, - void *dev) -{ - struct s3c_pl330_dmac *dmac; - struct s3c_pl330_chan *ch; - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&res_lock, flags); - - ch = chan_acquire(id); - if (!ch) { - ret = -EBUSY; - goto req_exit; - } - - dmac = ch->dmac; - - ch->pl330_chan_id = pl330_request_channel(dmac->pi); - if (!ch->pl330_chan_id) { - chan_release(ch); - ret = -EBUSY; - goto req_exit; - } - - ch->client = client; - ch->options = 0; /* Clear any option */ - ch->callback_fn = NULL; /* Clear any callback */ - ch->lrq = NULL; - - ch->rqcfg.brst_size = 2; /* Default word size */ - ch->rqcfg.swap = SWAP_NO; - ch->rqcfg.scctl = SCCTRL0; /* Noncacheable and nonbufferable */ - ch->rqcfg.dcctl = DCCTRL0; /* Noncacheable and nonbufferable */ - ch->rqcfg.privileged = 0; - ch->rqcfg.insnaccess = 0; - - /* Set invalid direction */ - ch->req[0].rqtype = DEVTODEV; - ch->req[1].rqtype = ch->req[0].rqtype; - - ch->req[0].cfg = &ch->rqcfg; - ch->req[1].cfg = ch->req[0].cfg; - - ch->req[0].peri = iface_of_dmac(dmac, id) - 1; /* Original index */ - ch->req[1].peri = ch->req[0].peri; - - ch->req[0].token = &ch->req[0]; - ch->req[0].xfer_cb = s3c_pl330_rq0; - ch->req[1].token = &ch->req[1]; - ch->req[1].xfer_cb = s3c_pl330_rq1; - - ch->req[0].x = NULL; - ch->req[1].x = NULL; - - /* Reset xfer list */ - INIT_LIST_HEAD(&ch->xfer_list); - ch->xfer_head = NULL; - -req_exit: - spin_unlock_irqrestore(&res_lock, flags); - - return ret; -} -EXPORT_SYMBOL(s3c2410_dma_request); - -int s3c2410_dma_free(enum dma_ch id, struct s3c2410_dma_client *client) -{ - struct s3c_pl330_chan *ch; - struct s3c_pl330_xfer *xfer; - unsigned long flags; - int ret = 0; - unsigned idx; - - spin_lock_irqsave(&res_lock, flags); - - ch = id_to_chan(id); - - if (!ch || chan_free(ch)) - goto free_exit; - - /* Refuse if someone else wanted to free the channel */ - if (ch->client != client) { - ret = -EBUSY; - goto free_exit; - } - - /* Stop any active xfer, Flushe the queue and do callbacks */ - pl330_chan_ctrl(ch->pl330_chan_id, PL330_OP_FLUSH); - - /* Abort the submitted requests */ - idx = (ch->lrq == &ch->req[0]) ? 1 : 0; - - if (ch->req[idx].x) { - xfer = container_of(ch->req[idx].x, - struct s3c_pl330_xfer, px); - - ch->req[idx].x = NULL; - del_from_queue(xfer); - - spin_unlock_irqrestore(&res_lock, flags); - _finish_off(xfer, S3C2410_RES_ABORT, 1); - spin_lock_irqsave(&res_lock, flags); - } - - if (ch->req[1 - idx].x) { - xfer = container_of(ch->req[1 - idx].x, - struct s3c_pl330_xfer, px); - - ch->req[1 - idx].x = NULL; - del_from_queue(xfer); - - spin_unlock_irqrestore(&res_lock, flags); - _finish_off(xfer, S3C2410_RES_ABORT, 1); - spin_lock_irqsave(&res_lock, flags); - } - - /* Pluck and Abort the queued requests in order */ - do { - xfer = get_from_queue(ch, 1); - - spin_unlock_irqrestore(&res_lock, flags); - _finish_off(xfer, S3C2410_RES_ABORT, 1); - spin_lock_irqsave(&res_lock, flags); - } while (xfer); - - ch->client = NULL; - - pl330_release_channel(ch->pl330_chan_id); - - ch->pl330_chan_id = NULL; - - chan_release(ch); - -free_exit: - spin_unlock_irqrestore(&res_lock, flags); - - return ret; -} -EXPORT_SYMBOL(s3c2410_dma_free); - -int s3c2410_dma_config(enum dma_ch id, int xferunit) -{ - struct s3c_pl330_chan *ch; - struct pl330_info *pi; - unsigned long flags; - int i, dbwidth, ret = 0; - - spin_lock_irqsave(&res_lock, flags); - - ch = id_to_chan(id); - - if (!ch || chan_free(ch)) { - ret = -EINVAL; - goto cfg_exit; - } - - pi = ch->dmac->pi; - dbwidth = pi->pcfg.data_bus_width / 8; - - /* Max size of xfer can be pcfg.data_bus_width */ - if (xferunit > dbwidth) { - ret = -EINVAL; - goto cfg_exit; - } - - i = 0; - while (xferunit != (1 << i)) - i++; - - /* If valid value */ - if (xferunit == (1 << i)) - ch->rqcfg.brst_size = i; - else - ret = -EINVAL; - -cfg_exit: - spin_unlock_irqrestore(&res_lock, flags); - - return ret; -} -EXPORT_SYMBOL(s3c2410_dma_config); - -/* Options that are supported by this driver */ -#define S3C_PL330_FLAGS (S3C2410_DMAF_CIRCULAR | S3C2410_DMAF_AUTOSTART) - -int s3c2410_dma_setflags(enum dma_ch id, unsigned int options) -{ - struct s3c_pl330_chan *ch; - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&res_lock, flags); - - ch = id_to_chan(id); - - if (!ch || chan_free(ch) || options & ~(S3C_PL330_FLAGS)) - ret = -EINVAL; - else - ch->options = options; - - spin_unlock_irqrestore(&res_lock, flags); - - return 0; -} -EXPORT_SYMBOL(s3c2410_dma_setflags); - -int s3c2410_dma_set_buffdone_fn(enum dma_ch id, s3c2410_dma_cbfn_t rtn) -{ - struct s3c_pl330_chan *ch; - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&res_lock, flags); - - ch = id_to_chan(id); - - if (!ch || chan_free(ch)) - ret = -EINVAL; - else - ch->callback_fn = rtn; - - spin_unlock_irqrestore(&res_lock, flags); - - return ret; -} -EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn); - -int s3c2410_dma_devconfig(enum dma_ch id, enum s3c2410_dmasrc source, - unsigned long address) -{ - struct s3c_pl330_chan *ch; - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&res_lock, flags); - - ch = id_to_chan(id); - - if (!ch || chan_free(ch)) { - ret = -EINVAL; - goto devcfg_exit; - } - - switch (source) { - case S3C2410_DMASRC_HW: /* P->M */ - ch->req[0].rqtype = DEVTOMEM; - ch->req[1].rqtype = DEVTOMEM; - ch->rqcfg.src_inc = 0; - ch->rqcfg.dst_inc = 1; - break; - case S3C2410_DMASRC_MEM: /* M->P */ - ch->req[0].rqtype = MEMTODEV; - ch->req[1].rqtype = MEMTODEV; - ch->rqcfg.src_inc = 1; - ch->rqcfg.dst_inc = 0; - break; - default: - ret = -EINVAL; - goto devcfg_exit; - } - - ch->sdaddr = address; - -devcfg_exit: - spin_unlock_irqrestore(&res_lock, flags); - - return ret; -} -EXPORT_SYMBOL(s3c2410_dma_devconfig); - -int s3c2410_dma_getposition(enum dma_ch id, dma_addr_t *src, dma_addr_t *dst) -{ - struct s3c_pl330_chan *ch = id_to_chan(id); - struct pl330_chanstatus status; - int ret; - - if (!ch || chan_free(ch)) - return -EINVAL; - - ret = pl330_chan_status(ch->pl330_chan_id, &status); - if (ret < 0) - return ret; - - *src = status.src_addr; - *dst = status.dst_addr; - - return 0; -} -EXPORT_SYMBOL(s3c2410_dma_getposition); - -static irqreturn_t pl330_irq_handler(int irq, void *data) -{ - if (pl330_update(data)) - return IRQ_HANDLED; - else - return IRQ_NONE; -} - -static int pl330_probe(struct platform_device *pdev) -{ - struct s3c_pl330_dmac *s3c_pl330_dmac; - struct s3c_pl330_platdata *pl330pd; - struct pl330_info *pl330_info; - struct resource *res; - int i, ret, irq; - - pl330pd = pdev->dev.platform_data; - - /* Can't do without the list of _32_ peripherals */ - if (!pl330pd || !pl330pd->peri) { - dev_err(&pdev->dev, "platform data missing!\n"); - return -ENODEV; - } - - pl330_info = kzalloc(sizeof(*pl330_info), GFP_KERNEL); - if (!pl330_info) - return -ENOMEM; - - pl330_info->pl330_data = NULL; - pl330_info->dev = &pdev->dev; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - ret = -ENODEV; - goto probe_err1; - } - - request_mem_region(res->start, resource_size(res), pdev->name); - - pl330_info->base = ioremap(res->start, resource_size(res)); - if (!pl330_info->base) { - ret = -ENXIO; - goto probe_err2; - } - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - ret = irq; - goto probe_err3; - } - - ret = request_irq(irq, pl330_irq_handler, 0, - dev_name(&pdev->dev), pl330_info); - if (ret) - goto probe_err4; - - /* Allocate a new DMAC */ - s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL); - if (!s3c_pl330_dmac) { - ret = -ENOMEM; - goto probe_err5; - } - - /* Get operation clock and enable it */ - s3c_pl330_dmac->clk = clk_get(&pdev->dev, "pdma"); - if (IS_ERR(s3c_pl330_dmac->clk)) { - dev_err(&pdev->dev, "Cannot get operation clock.\n"); - ret = -EINVAL; - goto probe_err6; - } - clk_enable(s3c_pl330_dmac->clk); - - ret = pl330_add(pl330_info); - if (ret) - goto probe_err7; - - /* Hook the info */ - s3c_pl330_dmac->pi = pl330_info; - - /* No busy channels */ - s3c_pl330_dmac->busy_chan = 0; - - s3c_pl330_dmac->kmcache = kmem_cache_create(dev_name(&pdev->dev), - sizeof(struct s3c_pl330_xfer), 0, 0, NULL); - - if (!s3c_pl330_dmac->kmcache) { - ret = -ENOMEM; - goto probe_err8; - } - - /* Get the list of peripherals */ - s3c_pl330_dmac->peri = pl330pd->peri; - - /* Attach to the list of DMACs */ - list_add_tail(&s3c_pl330_dmac->node, &dmac_list); - - /* Create a channel for each peripheral in the DMAC - * that is, if it doesn't already exist - */ - for (i = 0; i < PL330_MAX_PERI; i++) - if (s3c_pl330_dmac->peri[i] != DMACH_MAX) - chan_add(s3c_pl330_dmac->peri[i]); - - printk(KERN_INFO - "Loaded driver for PL330 DMAC-%d %s\n", pdev->id, pdev->name); - printk(KERN_INFO - "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n", - pl330_info->pcfg.data_buf_dep, - pl330_info->pcfg.data_bus_width / 8, pl330_info->pcfg.num_chan, - pl330_info->pcfg.num_peri, pl330_info->pcfg.num_events); - - return 0; - -probe_err8: - pl330_del(pl330_info); -probe_err7: - clk_disable(s3c_pl330_dmac->clk); - clk_put(s3c_pl330_dmac->clk); -probe_err6: - kfree(s3c_pl330_dmac); -probe_err5: - free_irq(irq, pl330_info); -probe_err4: -probe_err3: - iounmap(pl330_info->base); -probe_err2: - release_mem_region(res->start, resource_size(res)); -probe_err1: - kfree(pl330_info); - - return ret; -} - -static int pl330_remove(struct platform_device *pdev) -{ - struct s3c_pl330_dmac *dmac, *d; - struct s3c_pl330_chan *ch; - unsigned long flags; - int del, found; - - if (!pdev->dev.platform_data) - return -EINVAL; - - spin_lock_irqsave(&res_lock, flags); - - found = 0; - list_for_each_entry(d, &dmac_list, node) - if (d->pi->dev == &pdev->dev) { - found = 1; - break; - } - - if (!found) { - spin_unlock_irqrestore(&res_lock, flags); - return 0; - } - - dmac = d; - - /* Remove all Channels that are managed only by this DMAC */ - list_for_each_entry(ch, &chan_list, node) { - - /* Only channels that are handled by this DMAC */ - if (iface_of_dmac(dmac, ch->id)) - del = 1; - else - continue; - - /* Don't remove if some other DMAC has it too */ - list_for_each_entry(d, &dmac_list, node) - if (d != dmac && iface_of_dmac(d, ch->id)) { - del = 0; - break; - } - - if (del) { - spin_unlock_irqrestore(&res_lock, flags); - s3c2410_dma_free(ch->id, ch->client); - spin_lock_irqsave(&res_lock, flags); - list_del(&ch->node); - kfree(ch); - } - } - - /* Disable operation clock */ - clk_disable(dmac->clk); - clk_put(dmac->clk); - - /* Remove the DMAC */ - list_del(&dmac->node); - kfree(dmac); - - spin_unlock_irqrestore(&res_lock, flags); - - return 0; -} - -static struct platform_driver pl330_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "s3c-pl330", - }, - .probe = pl330_probe, - .remove = pl330_remove, -}; - -static int __init pl330_init(void) -{ - return platform_driver_register(&pl330_driver); -} -module_init(pl330_init); - -static void __exit pl330_exit(void) -{ - platform_driver_unregister(&pl330_driver); - return; -} -module_exit(pl330_exit); - -MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>"); -MODULE_DESCRIPTION("Driver for PL330 DMA Controller"); -MODULE_LICENSE("GPL"); diff --git a/arch/arm/plat-samsung/s5p-clock.c b/arch/arm/plat-samsung/s5p-clock.c new file mode 100644 index 00000000000..48a15991103 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-clock.c @@ -0,0 +1,294 @@ +/* + * Copyright 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P - Common 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/kernel.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/device.h> +#include <linux/io.h> +#include <asm/div64.h> + +#include <mach/regs-clock.h> + +#include <plat/clock.h> +#include <plat/clock-clksrc.h> +#include <plat/s5p-clock.h> + +/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call + * clk_ext_xtal_mux. +*/ +struct clk clk_ext_xtal_mux = { + .name = "ext_xtal", + .id = -1, +}; + +struct clk clk_xusbxti = { + .name = "xusbxti", + .id = -1, + .rate = 24000000, +}; + +struct clk s5p_clk_27m = { + .name = "clk_27m", + .id = -1, + .rate = 27000000, +}; + +/* 48MHz USB Phy clock output */ +struct clk clk_48m = { + .name = "clk_48m", + .id = -1, + .rate = 48000000, +}; + +/* APLL clock output + * No need .ctrlbit, this is always on +*/ +struct clk clk_fout_apll = { + .name = "fout_apll", + .id = -1, +}; + +/* BPLL clock output */ + +struct clk clk_fout_bpll = { + .name = "fout_bpll", + .id = -1, +}; + +struct clk clk_fout_bpll_div2 = { + .name = "fout_bpll_div2", + .id = -1, +}; + +/* CPLL clock output */ + +struct clk clk_fout_cpll = { + .name = "fout_cpll", + .id = -1, +}; + +/* MPLL clock output + * No need .ctrlbit, this is always on +*/ +struct clk clk_fout_mpll = { + .name = "fout_mpll", + .id = -1, +}; + +struct clk clk_fout_mpll_div2 = { + .name = "fout_mpll_div2", + .id = -1, +}; + +/* EPLL clock output */ +struct clk clk_fout_epll = { + .name = "fout_epll", + .id = -1, + .ctrlbit = (1 << 31), +}; + +/* DPLL clock output */ +struct clk clk_fout_dpll = { + .name = "fout_dpll", + .id = -1, + .ctrlbit = (1 << 31), +}; + +/* VPLL clock output */ +struct clk clk_fout_vpll = { + .name = "fout_vpll", + .id = -1, + .ctrlbit = (1 << 31), +}; + +/* Possible clock sources for APLL Mux */ +static struct clk *clk_src_apll_list[] = { + [0] = &clk_fin_apll, + [1] = &clk_fout_apll, +}; + +struct clksrc_sources clk_src_apll = { + .sources = clk_src_apll_list, + .nr_sources = ARRAY_SIZE(clk_src_apll_list), +}; + +/* Possible clock sources for BPLL Mux */ +static struct clk *clk_src_bpll_list[] = { + [0] = &clk_fin_bpll, + [1] = &clk_fout_bpll, +}; + +struct clksrc_sources clk_src_bpll = { + .sources = clk_src_bpll_list, + .nr_sources = ARRAY_SIZE(clk_src_bpll_list), +}; + +static struct clk *clk_src_bpll_fout_list[] = { + [0] = &clk_fout_bpll_div2, + [1] = &clk_fout_bpll, +}; + +struct clksrc_sources clk_src_bpll_fout = { + .sources = clk_src_bpll_fout_list, + .nr_sources = ARRAY_SIZE(clk_src_bpll_fout_list), +}; + +/* Possible clock sources for CPLL Mux */ +static struct clk *clk_src_cpll_list[] = { + [0] = &clk_fin_cpll, + [1] = &clk_fout_cpll, +}; + +struct clksrc_sources clk_src_cpll = { + .sources = clk_src_cpll_list, + .nr_sources = ARRAY_SIZE(clk_src_cpll_list), +}; + +/* Possible clock sources for MPLL Mux */ +static struct clk *clk_src_mpll_list[] = { + [0] = &clk_fin_mpll, + [1] = &clk_fout_mpll, +}; + +struct clksrc_sources clk_src_mpll = { + .sources = clk_src_mpll_list, + .nr_sources = ARRAY_SIZE(clk_src_mpll_list), +}; + +static struct clk *clk_src_mpll_fout_list[] = { + [0] = &clk_fout_mpll_div2, + [1] = &clk_fout_mpll, +}; + +struct clksrc_sources clk_src_mpll_fout = { + .sources = clk_src_mpll_fout_list, + .nr_sources = ARRAY_SIZE(clk_src_mpll_fout_list), +}; + +/* Possible clock sources for EPLL Mux */ +static struct clk *clk_src_epll_list[] = { + [0] = &clk_fin_epll, + [1] = &clk_fout_epll, +}; + +struct clksrc_sources clk_src_epll = { + .sources = clk_src_epll_list, + .nr_sources = ARRAY_SIZE(clk_src_epll_list), +}; + +/* Possible clock sources for DPLL Mux */ +static struct clk *clk_src_dpll_list[] = { + [0] = &clk_fin_dpll, + [1] = &clk_fout_dpll, +}; + +struct clksrc_sources clk_src_dpll = { + .sources = clk_src_dpll_list, + .nr_sources = ARRAY_SIZE(clk_src_dpll_list), +}; + +struct clk clk_vpll = { + .name = "vpll", + .id = -1, +}; + +int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable) +{ + unsigned int ctrlbit = clk->ctrlbit; + u32 con; + + con = __raw_readl(reg); + con = enable ? (con | ctrlbit) : (con & ~ctrlbit); + __raw_writel(con, reg); + return 0; +} + +int s5p_epll_enable(struct clk *clk, int enable) +{ + unsigned int ctrlbit = clk->ctrlbit; + unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit; + + if (enable) + __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON); + else + __raw_writel(epll_con, S5P_EPLL_CON); + + return 0; +} + +unsigned long s5p_epll_get_rate(struct clk *clk) +{ + return clk->rate; +} + +int s5p_spdif_set_rate(struct clk *clk, unsigned long rate) +{ + struct clk *pclk; + int ret; + + pclk = clk_get_parent(clk); + if (IS_ERR(pclk)) + return -EINVAL; + + ret = pclk->ops->set_rate(pclk, rate); + clk_put(pclk); + + return ret; +} + +unsigned long s5p_spdif_get_rate(struct clk *clk) +{ + struct clk *pclk; + int rate; + + pclk = clk_get_parent(clk); + if (IS_ERR(pclk)) + return -EINVAL; + + rate = pclk->ops->get_rate(pclk); + clk_put(pclk); + + return rate; +} + +struct clk_ops s5p_sclk_spdif_ops = { + .set_rate = s5p_spdif_set_rate, + .get_rate = s5p_spdif_get_rate, +}; + +static struct clk *s5p_clks[] __initdata = { + &clk_ext_xtal_mux, + &clk_48m, + &s5p_clk_27m, + &clk_fout_apll, + &clk_fout_mpll, + &clk_fout_epll, + &clk_fout_dpll, + &clk_fout_vpll, + &clk_vpll, + &clk_xusbxti, +}; + +void __init s5p_register_clocks(unsigned long xtal_freq) +{ + int ret; + + clk_ext_xtal_mux.rate = xtal_freq; + + ret = s3c24xx_register_clocks(s5p_clks, ARRAY_SIZE(s5p_clks)); + if (ret > 0) + printk(KERN_ERR "Failed to register s5p clocks\n"); +} diff --git a/arch/arm/plat-samsung/s5p-dev-mfc.c b/arch/arm/plat-samsung/s5p-dev-mfc.c new file mode 100644 index 00000000000..469b86260fe --- /dev/null +++ b/arch/arm/plat-samsung/s5p-dev-mfc.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2010-2011 Samsung Electronics Co.Ltd + * + * Base S5P MFC resource and device 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. + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/memblock.h> +#include <linux/ioport.h> +#include <linux/of_fdt.h> +#include <linux/of.h> + +#include <plat/mfc.h> + +#ifdef CONFIG_SAMSUNG_ATAGS +#include <mach/map.h> +#include <mach/irqs.h> +#include <plat/devs.h> + +static struct resource s5p_mfc_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_MFC, SZ_64K), + [1] = DEFINE_RES_IRQ(IRQ_MFC), +}; + +struct platform_device s5p_device_mfc = { + .name = "s5p-mfc", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_mfc_resource), + .resource = s5p_mfc_resource, +}; + +/* + * MFC hardware has 2 memory interfaces which are modelled as two separate + * platform devices to let dma-mapping distinguish between them. + * + * MFC parent device (s5p_device_mfc) must be registered before memory + * interface specific devices (s5p_device_mfc_l and s5p_device_mfc_r). + */ + +struct platform_device s5p_device_mfc_l = { + .name = "s5p-mfc-l", + .id = -1, + .dev = { + .parent = &s5p_device_mfc.dev, + .dma_mask = &s5p_device_mfc_l.dev.coherent_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +struct platform_device s5p_device_mfc_r = { + .name = "s5p-mfc-r", + .id = -1, + .dev = { + .parent = &s5p_device_mfc.dev, + .dma_mask = &s5p_device_mfc_r.dev.coherent_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; +#else +static struct platform_device s5p_device_mfc_l; +static struct platform_device s5p_device_mfc_r; +#endif + +struct s5p_mfc_reserved_mem { + phys_addr_t base; + unsigned long size; + struct device *dev; +}; + +static struct s5p_mfc_reserved_mem s5p_mfc_mem[2] __initdata; + + +void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize, + phys_addr_t lbase, unsigned int lsize) +{ + int i; + + s5p_mfc_mem[0].dev = &s5p_device_mfc_r.dev; + s5p_mfc_mem[0].base = rbase; + s5p_mfc_mem[0].size = rsize; + + s5p_mfc_mem[1].dev = &s5p_device_mfc_l.dev; + s5p_mfc_mem[1].base = lbase; + s5p_mfc_mem[1].size = lsize; + + for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) { + struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i]; + if (memblock_remove(area->base, area->size)) { + printk(KERN_ERR "Failed to reserve memory for MFC device (%ld bytes at 0x%08lx)\n", + area->size, (unsigned long) area->base); + area->base = 0; + } + } +} + +#ifdef CONFIG_SAMSUNG_ATAGS +static int __init s5p_mfc_memory_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) { + struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i]; + if (!area->base) + continue; + + if (dma_declare_coherent_memory(area->dev, area->base, + area->base, area->size, + DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) + printk(KERN_ERR "Failed to declare coherent memory for MFC device (%ld bytes at 0x%08lx)\n", + area->size, (unsigned long) area->base); + } + return 0; +} +device_initcall(s5p_mfc_memory_init); +#endif + +#ifdef CONFIG_OF +int __init s5p_fdt_alloc_mfc_mem(unsigned long node, const char *uname, + int depth, void *data) +{ + const __be32 *prop; + int len; + struct s5p_mfc_dt_meminfo mfc_mem; + + if (!data) + return 0; + + if (!of_flat_dt_is_compatible(node, data)) + return 0; + + prop = of_get_flat_dt_prop(node, "samsung,mfc-l", &len); + if (!prop || (len != 2 * sizeof(unsigned long))) + return 0; + + mfc_mem.loff = be32_to_cpu(prop[0]); + mfc_mem.lsize = be32_to_cpu(prop[1]); + + prop = of_get_flat_dt_prop(node, "samsung,mfc-r", &len); + if (!prop || (len != 2 * sizeof(unsigned long))) + return 0; + + mfc_mem.roff = be32_to_cpu(prop[0]); + mfc_mem.rsize = be32_to_cpu(prop[1]); + + s5p_mfc_reserve_mem(mfc_mem.roff, mfc_mem.rsize, + mfc_mem.loff, mfc_mem.lsize); + + return 1; +} +#endif diff --git a/arch/arm/plat-samsung/s5p-dev-uart.c b/arch/arm/plat-samsung/s5p-dev-uart.c new file mode 100644 index 00000000000..8c4487af98c --- /dev/null +++ b/arch/arm/plat-samsung/s5p-dev-uart.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2009,2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Base S5P UART resource and device 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. +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/ioport.h> +#include <linux/platform_device.h> + +#include <asm/mach/arch.h> +#include <asm/mach/irq.h> +#include <mach/map.h> + +#include <plat/devs.h> + + /* Serial port registrations */ + +static struct resource s5p_uart0_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_UART0, S5P_SZ_UART), + [1] = DEFINE_RES_IRQ(IRQ_UART0), +}; + +static struct resource s5p_uart1_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_UART1, S5P_SZ_UART), + [1] = DEFINE_RES_IRQ(IRQ_UART1), +}; + +static struct resource s5p_uart2_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_UART2, S5P_SZ_UART), + [1] = DEFINE_RES_IRQ(IRQ_UART2), +}; + +static struct resource s5p_uart3_resource[] = { +#if CONFIG_SERIAL_SAMSUNG_UARTS > 3 + [0] = DEFINE_RES_MEM(S5P_PA_UART3, S5P_SZ_UART), + [1] = DEFINE_RES_IRQ(IRQ_UART3), +#endif +}; + +static struct resource s5p_uart4_resource[] = { +#if CONFIG_SERIAL_SAMSUNG_UARTS > 4 + [0] = DEFINE_RES_MEM(S5P_PA_UART4, S5P_SZ_UART), + [1] = DEFINE_RES_IRQ(IRQ_UART4), +#endif +}; + +static struct resource s5p_uart5_resource[] = { +#if CONFIG_SERIAL_SAMSUNG_UARTS > 5 + [0] = DEFINE_RES_MEM(S5P_PA_UART5, S5P_SZ_UART), + [1] = DEFINE_RES_IRQ(IRQ_UART5), +#endif +}; + +struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = { + [0] = { + .resources = s5p_uart0_resource, + .nr_resources = ARRAY_SIZE(s5p_uart0_resource), + }, + [1] = { + .resources = s5p_uart1_resource, + .nr_resources = ARRAY_SIZE(s5p_uart1_resource), + }, + [2] = { + .resources = s5p_uart2_resource, + .nr_resources = ARRAY_SIZE(s5p_uart2_resource), + }, + [3] = { + .resources = s5p_uart3_resource, + .nr_resources = ARRAY_SIZE(s5p_uart3_resource), + }, + [4] = { + .resources = s5p_uart4_resource, + .nr_resources = ARRAY_SIZE(s5p_uart4_resource), + }, + [5] = { + .resources = s5p_uart5_resource, + .nr_resources = ARRAY_SIZE(s5p_uart5_resource), + }, +}; diff --git a/arch/arm/plat-samsung/s5p-irq-eint.c b/arch/arm/plat-samsung/s5p-irq-eint.c new file mode 100644 index 00000000000..ebee4dc11a9 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-irq-eint.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P - IRQ EINT 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/kernel.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <linux/device.h> +#include <linux/gpio.h> +#include <linux/irqchip/arm-vic.h> +#include <linux/of.h> + +#include <plat/regs-irqtype.h> + +#include <mach/map.h> +#include <plat/cpu.h> +#include <plat/pm.h> + +#include <plat/gpio-cfg.h> +#include <mach/regs-gpio.h> + +static inline void s5p_irq_eint_mask(struct irq_data *data) +{ + u32 mask; + + mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); + mask |= eint_irq_to_bit(data->irq); + __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); +} + +static void s5p_irq_eint_unmask(struct irq_data *data) +{ + u32 mask; + + mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); + mask &= ~(eint_irq_to_bit(data->irq)); + __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); +} + +static inline void s5p_irq_eint_ack(struct irq_data *data) +{ + __raw_writel(eint_irq_to_bit(data->irq), + S5P_EINT_PEND(EINT_REG_NR(data->irq))); +} + +static void s5p_irq_eint_maskack(struct irq_data *data) +{ + /* compiler should in-line these */ + s5p_irq_eint_mask(data); + s5p_irq_eint_ack(data); +} + +static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type) +{ + int offs = EINT_OFFSET(data->irq); + int shift; + u32 ctrl, mask; + u32 newvalue = 0; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + newvalue = S5P_IRQ_TYPE_EDGE_RISING; + break; + + case IRQ_TYPE_EDGE_FALLING: + newvalue = S5P_IRQ_TYPE_EDGE_FALLING; + break; + + case IRQ_TYPE_EDGE_BOTH: + newvalue = S5P_IRQ_TYPE_EDGE_BOTH; + break; + + case IRQ_TYPE_LEVEL_LOW: + newvalue = S5P_IRQ_TYPE_LEVEL_LOW; + break; + + case IRQ_TYPE_LEVEL_HIGH: + newvalue = S5P_IRQ_TYPE_LEVEL_HIGH; + break; + + default: + printk(KERN_ERR "No such irq type %d", type); + return -EINVAL; + } + + shift = (offs & 0x7) * 4; + mask = 0x7 << shift; + + ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq))); + ctrl &= ~mask; + ctrl |= newvalue << shift; + __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq))); + + if ((0 <= offs) && (offs < 8)) + s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE); + + else if ((8 <= offs) && (offs < 16)) + s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE); + + else if ((16 <= offs) && (offs < 24)) + s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE); + + else if ((24 <= offs) && (offs < 32)) + s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE); + + else + printk(KERN_ERR "No such irq number %d", offs); + + return 0; +} + +static struct irq_chip s5p_irq_eint = { + .name = "s5p-eint", + .irq_mask = s5p_irq_eint_mask, + .irq_unmask = s5p_irq_eint_unmask, + .irq_mask_ack = s5p_irq_eint_maskack, + .irq_ack = s5p_irq_eint_ack, + .irq_set_type = s5p_irq_eint_set_type, +#ifdef CONFIG_PM + .irq_set_wake = s3c_irqext_wake, +#endif +}; + +/* s5p_irq_demux_eint + * + * This function demuxes the IRQ from the group0 external interrupts, + * from EINTs 16 to 31. It is designed to be inlined into the specific + * handler s5p_irq_demux_eintX_Y. + * + * Each EINT pend/mask registers handle eight of them. + */ +static inline void s5p_irq_demux_eint(unsigned int start) +{ + u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); + u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); + unsigned int irq; + + status &= ~mask; + status &= 0xff; + + while (status) { + irq = fls(status) - 1; + generic_handle_irq(irq + start); + status &= ~(1 << irq); + } +} + +static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) +{ + s5p_irq_demux_eint(IRQ_EINT(16)); + s5p_irq_demux_eint(IRQ_EINT(24)); +} + +static inline void s5p_irq_vic_eint_mask(struct irq_data *data) +{ + void __iomem *base = irq_data_get_irq_chip_data(data); + + s5p_irq_eint_mask(data); + writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE_CLEAR); +} + +static void s5p_irq_vic_eint_unmask(struct irq_data *data) +{ + void __iomem *base = irq_data_get_irq_chip_data(data); + + s5p_irq_eint_unmask(data); + writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE); +} + +static inline void s5p_irq_vic_eint_ack(struct irq_data *data) +{ + __raw_writel(eint_irq_to_bit(data->irq), + S5P_EINT_PEND(EINT_REG_NR(data->irq))); +} + +static void s5p_irq_vic_eint_maskack(struct irq_data *data) +{ + s5p_irq_vic_eint_mask(data); + s5p_irq_vic_eint_ack(data); +} + +static struct irq_chip s5p_irq_vic_eint = { + .name = "s5p_vic_eint", + .irq_mask = s5p_irq_vic_eint_mask, + .irq_unmask = s5p_irq_vic_eint_unmask, + .irq_mask_ack = s5p_irq_vic_eint_maskack, + .irq_ack = s5p_irq_vic_eint_ack, + .irq_set_type = s5p_irq_eint_set_type, +#ifdef CONFIG_PM + .irq_set_wake = s3c_irqext_wake, +#endif +}; + +static int __init s5p_init_irq_eint(void) +{ + int irq; + + if (of_have_populated_dt()) + return -ENODEV; + + for (irq = IRQ_EINT(0); irq <= IRQ_EINT(15); irq++) + irq_set_chip(irq, &s5p_irq_vic_eint); + + for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) { + irq_set_chip_and_handler(irq, &s5p_irq_eint, handle_level_irq); + set_irq_flags(irq, IRQF_VALID); + } + + irq_set_chained_handler(IRQ_EINT16_31, s5p_irq_demux_eint16_31); + return 0; +} + +arch_initcall(s5p_init_irq_eint); diff --git a/arch/arm/plat-samsung/s5p-irq-gpioint.c b/arch/arm/plat-samsung/s5p-irq-gpioint.c new file mode 100644 index 00000000000..fafdb059043 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-irq-gpioint.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * Author: Kyungmin Park <kyungmin.park@samsung.com> + * Author: Joonyoung Shim <jy0922.shim@samsung.com> + * Author: Marek Szyprowski <m.szyprowski@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/kernel.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/irqchip/chained_irq.h> +#include <linux/io.h> +#include <linux/gpio.h> +#include <linux/slab.h> + +#include <mach/map.h> +#include <plat/gpio-core.h> +#include <plat/gpio-cfg.h> + +#define GPIO_BASE(chip) ((void __iomem *)((unsigned long)((chip)->base) & 0xFFFFF000u)) + +#define CON_OFFSET 0x700 +#define MASK_OFFSET 0x900 +#define PEND_OFFSET 0xA00 +#define REG_OFFSET(x) ((x) << 2) + +struct s5p_gpioint_bank { + struct list_head list; + int start; + int nr_groups; + int irq; + struct samsung_gpio_chip **chips; + void (*handler)(unsigned int, struct irq_desc *); +}; + +static LIST_HEAD(banks); + +static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + struct irq_chip_type *ct = gc->chip_types; + unsigned int shift = (d->irq - gc->irq_base) << 2; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + type = S5P_IRQ_TYPE_EDGE_RISING; + break; + case IRQ_TYPE_EDGE_FALLING: + type = S5P_IRQ_TYPE_EDGE_FALLING; + break; + case IRQ_TYPE_EDGE_BOTH: + type = S5P_IRQ_TYPE_EDGE_BOTH; + break; + case IRQ_TYPE_LEVEL_HIGH: + type = S5P_IRQ_TYPE_LEVEL_HIGH; + break; + case IRQ_TYPE_LEVEL_LOW: + type = S5P_IRQ_TYPE_LEVEL_LOW; + break; + case IRQ_TYPE_NONE: + default: + printk(KERN_WARNING "No irq type\n"); + return -EINVAL; + } + + gc->type_cache &= ~(0x7 << shift); + gc->type_cache |= type << shift; + writel(gc->type_cache, gc->reg_base + ct->regs.type); + return 0; +} + +static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) +{ + struct s5p_gpioint_bank *bank = irq_get_handler_data(irq); + int group, pend_offset, mask_offset; + unsigned int pend, mask; + + struct irq_chip *chip = irq_get_chip(irq); + chained_irq_enter(chip, desc); + + for (group = 0; group < bank->nr_groups; group++) { + struct samsung_gpio_chip *chip = bank->chips[group]; + if (!chip) + continue; + + pend_offset = REG_OFFSET(group); + pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset); + if (!pend) + continue; + + mask_offset = REG_OFFSET(group); + mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset); + pend &= ~mask; + + while (pend) { + int offset = fls(pend) - 1; + int real_irq = chip->irq_base + offset; + generic_handle_irq(real_irq); + pend &= ~BIT(offset); + } + } + chained_irq_exit(chip, desc); +} + +static __init int s5p_gpioint_add(struct samsung_gpio_chip *chip) +{ + static int used_gpioint_groups = 0; + int group = chip->group; + struct s5p_gpioint_bank *b, *bank = NULL; + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + + if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT) + return -ENOMEM; + + list_for_each_entry(b, &banks, list) { + if (group >= b->start && group < b->start + b->nr_groups) { + bank = b; + break; + } + } + if (!bank) + return -EINVAL; + + if (!bank->handler) { + bank->chips = kzalloc(sizeof(struct samsung_gpio_chip *) * + bank->nr_groups, GFP_KERNEL); + if (!bank->chips) + return -ENOMEM; + + irq_set_chained_handler(bank->irq, s5p_gpioint_handler); + irq_set_handler_data(bank->irq, bank); + bank->handler = s5p_gpioint_handler; + printk(KERN_INFO "Registered chained gpio int handler for interrupt %d.\n", + bank->irq); + } + + /* + * chained GPIO irq has been successfully registered, allocate new gpio + * int group and assign irq nubmers + */ + chip->irq_base = S5P_GPIOINT_BASE + + used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE; + used_gpioint_groups++; + + bank->chips[group - bank->start] = chip; + + gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base, + GPIO_BASE(chip), + handle_level_irq); + if (!gc) + return -ENOMEM; + ct = gc->chip_types; + ct->chip.irq_ack = irq_gc_ack_set_bit; + ct->chip.irq_mask = irq_gc_mask_set_bit; + ct->chip.irq_unmask = irq_gc_mask_clr_bit; + ct->chip.irq_set_type = s5p_gpioint_set_type, + ct->regs.ack = PEND_OFFSET + REG_OFFSET(group - bank->start); + ct->regs.mask = MASK_OFFSET + REG_OFFSET(group - bank->start); + ct->regs.type = CON_OFFSET + REG_OFFSET(group - bank->start); + irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio), + IRQ_GC_INIT_MASK_CACHE, + IRQ_NOREQUEST | IRQ_NOPROBE, 0); + return 0; +} + +int __init s5p_register_gpio_interrupt(int pin) +{ + struct samsung_gpio_chip *my_chip = samsung_gpiolib_getchip(pin); + int offset, group; + int ret; + + if (!my_chip) + return -EINVAL; + + offset = pin - my_chip->chip.base; + group = my_chip->group; + + /* check if the group has been already registered */ + if (my_chip->irq_base) + goto success; + + /* register gpio group */ + ret = s5p_gpioint_add(my_chip); + if (ret == 0) { + my_chip->chip.to_irq = samsung_gpiolib_to_irq; + printk(KERN_INFO "Registered interrupt support for gpio group %d.\n", + group); + goto success; + } + return ret; +success: + my_chip->bitmap_gpio_int |= BIT(offset); + + return my_chip->irq_base + offset; +} + +int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups) +{ + struct s5p_gpioint_bank *bank; + + bank = kzalloc(sizeof(*bank), GFP_KERNEL); + if (!bank) + return -ENOMEM; + + bank->start = start; + bank->nr_groups = nr_groups; + bank->irq = chain_irq; + + list_add_tail(&bank->list, &banks); + return 0; +} diff --git a/arch/arm/plat-samsung/s5p-irq-pm.c b/arch/arm/plat-samsung/s5p-irq-pm.c new file mode 100644 index 00000000000..52b16943617 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-irq-pm.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Based on arch/arm/plat-s3c24xx/irq-pm.c, + * Copyright (c) 2003,2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * http://armlinux.simtec.co.uk/ + * + * 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 <plat/cpu.h> +#include <plat/irqs.h> +#include <plat/pm.h> +#include <mach/map.h> + +#include <mach/regs-gpio.h> +#include <mach/regs-irq.h> + +/* state for IRQs over sleep */ + +/* default is to allow for EINT0..EINT31, and IRQ_RTC_TIC, IRQ_RTC_ALARM, + * as wakeup sources + * + * set bit to 1 in allow bitfield to enable the wakeup settings on it +*/ + +unsigned long s3c_irqwake_intallow = 0x00000006L; +unsigned long s3c_irqwake_eintallow = 0xffffffffL; + +int s3c_irq_wake(struct irq_data *data, unsigned int state) +{ + unsigned long irqbit; + unsigned int irq_rtc_tic, irq_rtc_alarm; + + irq_rtc_tic = IRQ_RTC_TIC; + irq_rtc_alarm = IRQ_RTC_ALARM; + + if (data->irq == irq_rtc_tic || data->irq == irq_rtc_alarm) { + irqbit = 1 << (data->irq + 1 - irq_rtc_alarm); + + if (!state) + s3c_irqwake_intmask |= irqbit; + else + s3c_irqwake_intmask &= ~irqbit; + } else { + return -ENOENT; + } + + return 0; +} + +static struct sleep_save eint_save[] = { + SAVE_ITEM(S5P_EINT_CON(0)), + SAVE_ITEM(S5P_EINT_CON(1)), + SAVE_ITEM(S5P_EINT_CON(2)), + SAVE_ITEM(S5P_EINT_CON(3)), + + SAVE_ITEM(S5P_EINT_FLTCON(0)), + SAVE_ITEM(S5P_EINT_FLTCON(1)), + SAVE_ITEM(S5P_EINT_FLTCON(2)), + SAVE_ITEM(S5P_EINT_FLTCON(3)), + SAVE_ITEM(S5P_EINT_FLTCON(4)), + SAVE_ITEM(S5P_EINT_FLTCON(5)), + SAVE_ITEM(S5P_EINT_FLTCON(6)), + SAVE_ITEM(S5P_EINT_FLTCON(7)), + + SAVE_ITEM(S5P_EINT_MASK(0)), + SAVE_ITEM(S5P_EINT_MASK(1)), + SAVE_ITEM(S5P_EINT_MASK(2)), + SAVE_ITEM(S5P_EINT_MASK(3)), +}; + +int s3c24xx_irq_suspend(void) +{ + s3c_pm_do_save(eint_save, ARRAY_SIZE(eint_save)); + + return 0; +} + +void s3c24xx_irq_resume(void) +{ + s3c_pm_do_restore(eint_save, ARRAY_SIZE(eint_save)); +} + diff --git a/arch/arm/plat-samsung/s5p-irq.c b/arch/arm/plat-samsung/s5p-irq.c new file mode 100644 index 00000000000..ddfaca9c79d --- /dev/null +++ b/arch/arm/plat-samsung/s5p-irq.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P - Interrupt handling + * + * 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/interrupt.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <linux/irqchip/arm-vic.h> + +#include <mach/irqs.h> +#include <mach/map.h> +#include <plat/cpu.h> + +void __init s5p_init_irq(u32 *vic, u32 num_vic) +{ +#ifdef CONFIG_ARM_VIC + int irq; + + /* initialize the VICs */ + for (irq = 0; irq < num_vic; irq++) + vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0); +#endif +} diff --git a/arch/arm/plat-samsung/s5p-pm.c b/arch/arm/plat-samsung/s5p-pm.c new file mode 100644 index 00000000000..0747468f093 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-pm.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P Power Manager (Suspend-To-RAM) support + * + * Based on arch/arm/plat-s3c24xx/pm.c + * Copyright (c) 2004,2006 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * 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/suspend.h> +#include <plat/pm.h> + +#define PFX "s5p pm: " + +/* s3c_pm_configure_extint + * + * configure all external interrupt pins +*/ + +void s3c_pm_configure_extint(void) +{ + /* nothing here yet */ +} + +void s3c_pm_restore_core(void) +{ + /* nothing here yet */ +} + +void s3c_pm_save_core(void) +{ + /* nothing here yet */ +} + diff --git a/arch/arm/plat-samsung/s5p-sleep.S b/arch/arm/plat-samsung/s5p-sleep.S new file mode 100644 index 00000000000..25c68ceb9e2 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-sleep.S @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Common S5P Sleep Code + * Based on S3C64XX sleep code by: + * Ben Dooks, (c) 2008 Simtec Electronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include <linux/linkage.h> + + .data + .align + + /* + * sleep magic, to allow the bootloader to check for an valid + * image to resume to. Must be the first word before the + * s3c_cpu_resume entry. + */ + + .word 0x2bedf00d + + /* + * s3c_cpu_resume + * + * resume code entry for bootloader to call + */ + +ENTRY(s3c_cpu_resume) + b cpu_resume +ENDPROC(s3c_cpu_resume) diff --git a/arch/arm/plat-samsung/setup-camif.c b/arch/arm/plat-samsung/setup-camif.c new file mode 100644 index 00000000000..72d8edb8927 --- /dev/null +++ b/arch/arm/plat-samsung/setup-camif.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2012 Sylwester Nawrocki <sylvester.nawrocki@gmail.com> + * + * Helper functions for S3C24XX/S3C64XX SoC series CAMIF driver + * + * 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/gpio.h> +#include <plat/gpio-cfg.h> +#include <mach/gpio-samsung.h> + +/* Number of camera port pins, without FIELD */ +#define S3C_CAMIF_NUM_GPIOS 13 + +/* Default camera port configuration helpers. */ + +static void camif_get_gpios(int *gpio_start, int *gpio_reset) +{ +#ifdef CONFIG_ARCH_S3C24XX + *gpio_start = S3C2410_GPJ(0); + *gpio_reset = S3C2410_GPJ(12); +#else + /* s3c64xx */ + *gpio_start = S3C64XX_GPF(0); + *gpio_reset = S3C64XX_GPF(3); +#endif +} + +int s3c_camif_gpio_get(void) +{ + int gpio_start, gpio_reset; + int ret, i; + + camif_get_gpios(&gpio_start, &gpio_reset); + + for (i = 0; i < S3C_CAMIF_NUM_GPIOS; i++) { + int gpio = gpio_start + i; + + if (gpio == gpio_reset) + continue; + + ret = gpio_request(gpio, "camif"); + if (!ret) + ret = s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); + if (ret) { + pr_err("failed to configure GPIO %d\n", gpio); + for (--i; i >= 0; i--) + gpio_free(gpio--); + return ret; + } + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); + } + + return 0; +} + +void s3c_camif_gpio_put(void) +{ + int i, gpio_start, gpio_reset; + + camif_get_gpios(&gpio_start, &gpio_reset); + + for (i = 0; i < S3C_CAMIF_NUM_GPIOS; i++) { + int gpio = gpio_start + i; + if (gpio != gpio_reset) + gpio_free(gpio); + } +} diff --git a/arch/arm/plat-samsung/time.c b/arch/arm/plat-samsung/time.c deleted file mode 100644 index 2231d80ad81..00000000000 --- a/arch/arm/plat-samsung/time.c +++ /dev/null @@ -1,285 +0,0 @@ -/* linux/arch/arm/plat-samsung/time.c - * - * Copyright (C) 2003-2005 Simtec Electronics - * Ben Dooks, <ben@simtec.co.uk> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/platform_device.h> - -#include <asm/system.h> -#include <asm/leds.h> -#include <asm/mach-types.h> - -#include <asm/irq.h> -#include <mach/map.h> -#include <plat/regs-timer.h> -#include <mach/regs-irq.h> -#include <asm/mach/time.h> -#include <mach/tick.h> - -#include <plat/clock.h> -#include <plat/cpu.h> - -static unsigned long timer_startval; -static unsigned long timer_usec_ticks; - -#ifndef TICK_MAX -#define TICK_MAX (0xffff) -#endif - -#define TIMER_USEC_SHIFT 16 - -/* we use the shifted arithmetic to work out the ratio of timer ticks - * to usecs, as often the peripheral clock is not a nice even multiple - * of 1MHz. - * - * shift of 14 and 15 are too low for the 12MHz, 16 seems to be ok - * for the current HZ value of 200 without producing overflows. - * - * Original patch by Dimitry Andric, updated by Ben Dooks -*/ - - -/* timer_mask_usec_ticks - * - * given a clock and divisor, make the value to pass into timer_ticks_to_usec - * to scale the ticks into usecs -*/ - -static inline unsigned long -timer_mask_usec_ticks(unsigned long scaler, unsigned long pclk) -{ - unsigned long den = pclk / 1000; - - return ((1000 << TIMER_USEC_SHIFT) * scaler + (den >> 1)) / den; -} - -/* timer_ticks_to_usec - * - * convert timer ticks to usec. -*/ - -static inline unsigned long timer_ticks_to_usec(unsigned long ticks) -{ - unsigned long res; - - res = ticks * timer_usec_ticks; - res += 1 << (TIMER_USEC_SHIFT - 4); /* round up slightly */ - - return res >> TIMER_USEC_SHIFT; -} - -/*** - * Returns microsecond since last clock interrupt. Note that interrupts - * will have been disabled by do_gettimeoffset() - * IRQs are disabled before entering here from do_gettimeofday() - */ - -static unsigned long s3c2410_gettimeoffset (void) -{ - unsigned long tdone; - unsigned long tval; - - /* work out how many ticks have gone since last timer interrupt */ - - tval = __raw_readl(S3C2410_TCNTO(4)); - tdone = timer_startval - tval; - - /* check to see if there is an interrupt pending */ - - if (s3c24xx_ostimer_pending()) { - /* re-read the timer, and try and fix up for the missed - * interrupt. Note, the interrupt may go off before the - * timer has re-loaded from wrapping. - */ - - tval = __raw_readl(S3C2410_TCNTO(4)); - tdone = timer_startval - tval; - - if (tval != 0) - tdone += timer_startval; - } - - return timer_ticks_to_usec(tdone); -} - - -/* - * IRQ handler for the timer - */ -static irqreturn_t -s3c2410_timer_interrupt(int irq, void *dev_id) -{ - timer_tick(); - return IRQ_HANDLED; -} - -static struct irqaction s3c2410_timer_irq = { - .name = "S3C2410 Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = s3c2410_timer_interrupt, -}; - -#define use_tclk1_12() ( \ - machine_is_bast() || \ - machine_is_vr1000() || \ - machine_is_anubis() || \ - machine_is_osiris()) - -static struct clk *tin; -static struct clk *tdiv; -static struct clk *timerclk; - -/* - * Set up timer interrupt, and return the current time in seconds. - * - * Currently we only use timer4, as it is the only timer which has no - * other function that can be exploited externally - */ -static void s3c2410_timer_setup (void) -{ - unsigned long tcon; - unsigned long tcnt; - unsigned long tcfg1; - unsigned long tcfg0; - - tcnt = TICK_MAX; /* default value for tcnt */ - - /* configure the system for whichever machine is in use */ - - if (use_tclk1_12()) { - /* timer is at 12MHz, scaler is 1 */ - timer_usec_ticks = timer_mask_usec_ticks(1, 12000000); - tcnt = 12000000 / HZ; - - tcfg1 = __raw_readl(S3C2410_TCFG1); - tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK; - tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1; - __raw_writel(tcfg1, S3C2410_TCFG1); - } else { - unsigned long pclk; - struct clk *tscaler; - - /* for the h1940 (and others), we use the pclk from the core - * to generate the timer values. since values around 50 to - * 70MHz are not values we can directly generate the timer - * value from, we need to pre-scale and divide before using it. - * - * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz - * (8.45 ticks per usec) - */ - - pclk = clk_get_rate(timerclk); - - /* configure clock tick */ - - timer_usec_ticks = timer_mask_usec_ticks(6, pclk); - - tscaler = clk_get_parent(tdiv); - - clk_set_rate(tscaler, pclk / 3); - clk_set_rate(tdiv, pclk / 6); - clk_set_parent(tin, tdiv); - - tcnt = clk_get_rate(tin) / HZ; - } - - tcon = __raw_readl(S3C2410_TCON); - tcfg0 = __raw_readl(S3C2410_TCFG0); - tcfg1 = __raw_readl(S3C2410_TCFG1); - - /* timers reload after counting zero, so reduce the count by 1 */ - - tcnt--; - - printk(KERN_DEBUG "timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx, usec %08lx\n", - tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks); - - /* check to see if timer is within 16bit range... */ - if (tcnt > TICK_MAX) { - panic("setup_timer: HZ is too small, cannot configure timer!"); - return; - } - - __raw_writel(tcfg1, S3C2410_TCFG1); - __raw_writel(tcfg0, S3C2410_TCFG0); - - timer_startval = tcnt; - __raw_writel(tcnt, S3C2410_TCNTB(4)); - - /* ensure timer is stopped... */ - - tcon &= ~(7<<20); - tcon |= S3C2410_TCON_T4RELOAD; - tcon |= S3C2410_TCON_T4MANUALUPD; - - __raw_writel(tcon, S3C2410_TCON); - __raw_writel(tcnt, S3C2410_TCNTB(4)); - __raw_writel(tcnt, S3C2410_TCMPB(4)); - - /* start the timer running */ - tcon |= S3C2410_TCON_T4START; - tcon &= ~S3C2410_TCON_T4MANUALUPD; - __raw_writel(tcon, S3C2410_TCON); -} - -static void __init s3c2410_timer_resources(void) -{ - struct platform_device tmpdev; - - tmpdev.dev.bus = &platform_bus_type; - tmpdev.id = 4; - - timerclk = clk_get(NULL, "timers"); - if (IS_ERR(timerclk)) - panic("failed to get clock for system timer"); - - clk_enable(timerclk); - - if (!use_tclk1_12()) { - tin = clk_get(&tmpdev.dev, "pwm-tin"); - if (IS_ERR(tin)) - panic("failed to get pwm-tin clock for system timer"); - - tdiv = clk_get(&tmpdev.dev, "pwm-tdiv"); - if (IS_ERR(tdiv)) - panic("failed to get pwm-tdiv clock for system timer"); - } - - clk_enable(tin); -} - -static void __init s3c2410_timer_init(void) -{ - s3c2410_timer_resources(); - s3c2410_timer_setup(); - setup_irq(IRQ_TIMER4, &s3c2410_timer_irq); -} - -struct sys_timer s3c24xx_timer = { - .init = s3c2410_timer_init, - .offset = s3c2410_gettimeoffset, - .resume = s3c2410_timer_setup -}; diff --git a/arch/arm/plat-samsung/wakeup-mask.c b/arch/arm/plat-samsung/wakeup-mask.c index 2e09b6ad84c..20c3d9117cc 100644 --- a/arch/arm/plat-samsung/wakeup-mask.c +++ b/arch/arm/plat-samsung/wakeup-mask.c @@ -11,7 +11,7 @@ #include <linux/kernel.h> #include <linux/spinlock.h> -#include <linux/sysdev.h> +#include <linux/device.h> #include <linux/types.h> #include <linux/irq.h> #include <linux/io.h> @@ -22,7 +22,7 @@ void samsung_sync_wakemask(void __iomem *reg, struct samsung_wakeup_mask *mask, int nr_mask) { - struct irq_desc *desc; + struct irq_data *data; u32 val; val = __raw_readl(reg); @@ -33,10 +33,10 @@ void samsung_sync_wakemask(void __iomem *reg, continue; } - desc = irq_to_desc(mask->irq); + data = irq_get_irq_data(mask->irq); - /* bit of a liberty to read this directly from irq_desc. */ - if (desc->wake_depth > 0) + /* bit of a liberty to read this directly from irq_data. */ + if (irqd_is_wakeup_set(data)) val &= ~mask->bit; else val |= mask->bit; diff --git a/arch/arm/plat-samsung/watchdog-reset.c b/arch/arm/plat-samsung/watchdog-reset.c new file mode 100644 index 00000000000..2ecb50bea04 --- /dev/null +++ b/arch/arm/plat-samsung/watchdog-reset.c @@ -0,0 +1,97 @@ +/* arch/arm/plat-samsung/watchdog-reset.c + * + * Copyright (c) 2008 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * Coyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com> + * + * Watchdog reset support for Samsung SoCs. + * + * 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/clk.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/of.h> +#include <linux/of_address.h> + +#define S3C2410_WTCON 0x00 +#define S3C2410_WTDAT 0x04 +#define S3C2410_WTCNT 0x08 + +#define S3C2410_WTCON_ENABLE (1 << 5) +#define S3C2410_WTCON_DIV16 (0 << 3) +#define S3C2410_WTCON_RSTEN (1 << 0) +#define S3C2410_WTCON_PRESCALE(x) ((x) << 8) + +static void __iomem *wdt_base; +static struct clk *wdt_clock; + +void samsung_wdt_reset(void) +{ + if (!wdt_base) { + pr_err("%s: wdt reset not initialized\n", __func__); + /* delay to allow the serial port to show the message */ + mdelay(50); + return; + } + + if (!IS_ERR(wdt_clock)) + clk_prepare_enable(wdt_clock); + + /* disable watchdog, to be safe */ + __raw_writel(0, wdt_base + S3C2410_WTCON); + + /* put initial values into count and data */ + __raw_writel(0x80, wdt_base + S3C2410_WTCNT); + __raw_writel(0x80, wdt_base + S3C2410_WTDAT); + + /* set the watchdog to go and reset... */ + __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV16 | + S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x20), + wdt_base + S3C2410_WTCON); + + /* wait for reset to assert... */ + mdelay(500); + + pr_err("Watchdog reset failed to assert reset\n"); + + /* delay to allow the serial port to show the message */ + mdelay(50); +} + +#ifdef CONFIG_OF +static const struct of_device_id s3c2410_wdt_match[] = { + { .compatible = "samsung,s3c2410-wdt" }, + {}, +}; + +void __init samsung_wdt_reset_of_init(void) +{ + struct device_node *np; + + np = of_find_matching_node(NULL, s3c2410_wdt_match); + if (!np) { + pr_err("%s: failed to find watchdog node\n", __func__); + return; + } + + wdt_base = of_iomap(np, 0); + if (!wdt_base) { + pr_err("%s: failed to map watchdog registers\n", __func__); + return; + } + + wdt_clock = of_clk_get(np, 0); +} +#endif + +void __init samsung_wdt_reset_init(void __iomem *base) +{ + wdt_base = base; + wdt_clock = clk_get(NULL, "watchdog"); +} |
