diff options
Diffstat (limited to 'arch/arm/mach-s3c64xx')
41 files changed, 535 insertions, 2196 deletions
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index 041da517242..26ca2427e53 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -3,16 +3,7 @@  #  # Licensed under GPLv2 -# temporary until we can eliminate all drivers using it. -config PLAT_S3C64XX -	bool -	depends on ARCH_S3C64XX -	default y -	select PM_GENERIC_DOMAINS -	select SAMSUNG_WAKEMASK -	help -	  Base platform code for any Samsung S3C64XX device - +if ARCH_S3C64XX  # Configuration options for the S3C6410 CPU @@ -26,9 +17,10 @@ config CPU_S3C6410  	help  	  Enable S3C6410 CPU support -config S3C64XX_DMA -	bool "S3C64XX DMA" -	select S3C_DMA +config S3C64XX_PL080 +	def_bool DMADEVICES +	select ARM_AMBA +	select AMBA_PL08X  config S3C64XX_SETUP_SDHCI  	bool @@ -94,8 +86,7 @@ config MACH_SMDK6400         bool "SMDK6400"  	select CPU_S3C6400  	select S3C64XX_SETUP_SDHCI -	select S3C_DEV_HSMMC -	select S3C_DEV_NAND +	select S3C_DEV_HSMMC1  	help  	  Machine support for the Samsung SMDK6400 @@ -201,7 +192,6 @@ config SMDK6410_WM1190_EV1  	select MFD_WM8350_I2C  	select REGULATOR  	select REGULATOR_WM8350 -	select SAMSUNG_GPIO_EXTRA64  	help  	  The Wolfson Microelectronics 1190-EV1 is a WM835x based PMIC  	  and audio daughtercard for the Samsung SMDK6410 reference @@ -217,7 +207,6 @@ config SMDK6410_WM1192_EV1  	select MFD_WM831X_I2C  	select REGULATOR  	select REGULATOR_WM831X -	select SAMSUNG_GPIO_EXTRA64  	help  	  The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC  	  daughtercard for the Samsung SMDK6410 reference platform. @@ -303,6 +292,23 @@ config MACH_WLF_CRAGG_6410  	select SAMSUNG_DEV_ADC  	select SAMSUNG_DEV_KEYPAD  	select SAMSUNG_DEV_PWM -	select SAMSUNG_GPIO_EXTRA128  	help  	  Machine support for the Wolfson Cragganmore S3C6410 variant. + +config MACH_S3C64XX_DT +	bool "Samsung S3C6400/S3C6410 machine using Device Tree" +	select CLKSRC_OF +	select CPU_S3C6400 +	select CPU_S3C6410 +	select PINCTRL +	select PINCTRL_S3C64XX +	select USE_OF +	help +	  Machine support for Samsung S3C6400/S3C6410 machines with Device Tree +	  enabled. +	  Select this if a fdt blob is available for your S3C64XX SoC based +	  board. +	  Note: This is under development and not all peripherals can be +	  supported with this machine file. + +endif diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index 31d0c910127..58069a702a4 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -12,7 +12,7 @@ obj-				:=  # Core -obj-y				+= common.o clock.o +obj-y				+= common.o  # Core support @@ -26,7 +26,7 @@ obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o  # DMA support -obj-$(CONFIG_S3C64XX_DMA)	+= dma.o +obj-$(CONFIG_S3C64XX_PL080)	+= pl080.o  # Device support @@ -57,3 +57,4 @@ obj-$(CONFIG_MACH_SMARTQ7)		+= mach-smartq7.o  obj-$(CONFIG_MACH_SMDK6400)		+= mach-smdk6400.o  obj-$(CONFIG_MACH_SMDK6410)		+= mach-smdk6410.o  obj-$(CONFIG_MACH_WLF_CRAGG_6410)	+= mach-crag6410.o mach-crag6410-module.o +obj-$(CONFIG_MACH_S3C64XX_DT)		+= mach-s3c64xx-dt.o diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c deleted file mode 100644 index c1bcc4a6d3a..00000000000 --- a/arch/arm/mach-s3c64xx/clock.c +++ /dev/null @@ -1,1007 +0,0 @@ -/* linux/arch/arm/plat-s3c64xx/clock.c - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - *	Ben Dooks <ben@simtec.co.uk> - *	http://armlinux.simtec.co.uk/ - * - * S3C64XX Base clock support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/io.h> - -#include <mach/hardware.h> -#include <mach/map.h> - -#include <mach/regs-clock.h> - -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/cpu-freq.h> -#include <plat/clock.h> -#include <plat/clock-clksrc.h> -#include <plat/pll.h> - -#include "regs-sys.h" - -/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call - * ext_xtal_mux for want of an actual name from the manual. -*/ - -static struct clk clk_ext_xtal_mux = { -	.name		= "ext_xtal", -}; - -#define clk_fin_apll clk_ext_xtal_mux -#define clk_fin_mpll clk_ext_xtal_mux -#define clk_fin_epll clk_ext_xtal_mux - -#define clk_fout_mpll	clk_mpll -#define clk_fout_epll	clk_epll - -struct clk clk_h2 = { -	.name		= "hclk2", -	.rate		= 0, -}; - -struct clk clk_27m = { -	.name		= "clk_27m", -	.rate		= 27000000, -}; - -static int clk_48m_ctrl(struct clk *clk, int enable) -{ -	unsigned long flags; -	u32 val; - -	/* can't rely on clock lock, this register has other usages */ -	local_irq_save(flags); - -	val = __raw_readl(S3C64XX_OTHERS); -	if (enable) -		val |= S3C64XX_OTHERS_USBMASK; -	else -		val &= ~S3C64XX_OTHERS_USBMASK; - -	__raw_writel(val, S3C64XX_OTHERS); -	local_irq_restore(flags); - -	return 0; -} - -struct clk clk_48m = { -	.name		= "clk_48m", -	.rate		= 48000000, -	.enable		= clk_48m_ctrl, -}; - -struct clk clk_xusbxti = { -	.name		= "xusbxti", -	.rate		= 48000000, -}; - -static int inline s3c64xx_gate(void __iomem *reg, -				struct clk *clk, -				int enable) -{ -	unsigned int ctrlbit = clk->ctrlbit; -	u32 con; - -	con = __raw_readl(reg); - -	if (enable) -		con |= ctrlbit; -	else -		con &= ~ctrlbit; - -	__raw_writel(con, reg); -	return 0; -} - -static int s3c64xx_pclk_ctrl(struct clk *clk, int enable) -{ -	return s3c64xx_gate(S3C_PCLK_GATE, clk, enable); -} - -static int s3c64xx_hclk_ctrl(struct clk *clk, int enable) -{ -	return s3c64xx_gate(S3C_HCLK_GATE, clk, enable); -} - -int s3c64xx_sclk_ctrl(struct clk *clk, int enable) -{ -	return s3c64xx_gate(S3C_SCLK_GATE, clk, enable); -} - -static struct clk init_clocks_off[] = { -	{ -		.name		= "nand", -		.parent		= &clk_h, -	}, { -		.name		= "rtc", -		.parent		= &clk_p, -		.enable		= s3c64xx_pclk_ctrl, -		.ctrlbit	= S3C_CLKCON_PCLK_RTC, -	}, { -		.name		= "adc", -		.parent		= &clk_p, -		.enable		= s3c64xx_pclk_ctrl, -		.ctrlbit	= S3C_CLKCON_PCLK_TSADC, -	}, { -		.name		= "i2c", -		.devname        = "s3c2440-i2c.0", -		.parent		= &clk_p, -		.enable		= s3c64xx_pclk_ctrl, -		.ctrlbit	= S3C_CLKCON_PCLK_IIC, -	}, { -		.name		= "i2c", -		.devname	= "s3c2440-i2c.1", -		.parent		= &clk_p, -		.enable		= s3c64xx_pclk_ctrl, -		.ctrlbit	= S3C6410_CLKCON_PCLK_I2C1, -	}, { -		.name		= "keypad", -		.parent		= &clk_p, -		.enable		= s3c64xx_pclk_ctrl, -		.ctrlbit	= S3C_CLKCON_PCLK_KEYPAD, -	}, { -		.name		= "spi", -		.devname	= "s3c6410-spi.0", -		.parent		= &clk_p, -		.enable		= s3c64xx_pclk_ctrl, -		.ctrlbit	= S3C_CLKCON_PCLK_SPI0, -	}, { -		.name		= "spi", -		.devname	= "s3c6410-spi.1", -		.parent		= &clk_p, -		.enable		= s3c64xx_pclk_ctrl, -		.ctrlbit	= S3C_CLKCON_PCLK_SPI1, -	}, { -		.name		= "48m", -		.devname	= "s3c-sdhci.0", -		.parent		= &clk_48m, -		.enable		= s3c64xx_sclk_ctrl, -		.ctrlbit	= S3C_CLKCON_SCLK_MMC0_48, -	}, { -		.name		= "48m", -		.devname	= "s3c-sdhci.1", -		.parent		= &clk_48m, -		.enable		= s3c64xx_sclk_ctrl, -		.ctrlbit	= S3C_CLKCON_SCLK_MMC1_48, -	}, { -		.name		= "48m", -		.devname	= "s3c-sdhci.2", -		.parent		= &clk_48m, -		.enable		= s3c64xx_sclk_ctrl, -		.ctrlbit	= S3C_CLKCON_SCLK_MMC2_48, -	}, { -		.name		= "ac97", -		.parent		= &clk_p, -		.ctrlbit	= S3C_CLKCON_PCLK_AC97, -	}, { -		.name		= "cfcon", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_IHOST, -	}, { -		.name		= "dma0", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_DMA0, -	}, { -		.name		= "dma1", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_DMA1, -	}, { -		.name		= "3dse", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_3DSE, -	}, { -		.name		= "hclk_secur", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_SECUR, -	}, { -		.name		= "sdma1", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_SDMA1, -	}, { -		.name		= "sdma0", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_SDMA0, -	}, { -		.name		= "hclk_jpeg", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_JPEG, -	}, { -		.name		= "camif", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_CAMIF, -	}, { -		.name		= "hclk_scaler", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_SCALER, -	}, { -		.name		= "2d", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_2D, -	}, { -		.name		= "tv", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_TV, -	}, { -		.name		= "post0", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_POST0, -	}, { -		.name		= "rot", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_ROT, -	}, { -		.name		= "hclk_mfc", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_MFC, -	}, { -		.name		= "pclk_mfc", -		.parent		= &clk_p, -		.enable		= s3c64xx_pclk_ctrl, -		.ctrlbit	= S3C_CLKCON_PCLK_MFC, -	}, { -		.name		= "dac27", -		.enable		= s3c64xx_sclk_ctrl, -		.ctrlbit	= S3C_CLKCON_SCLK_DAC27, -	}, { -		.name		= "tv27", -		.enable		= s3c64xx_sclk_ctrl, -		.ctrlbit	= S3C_CLKCON_SCLK_TV27, -	}, { -		.name		= "scaler27", -		.enable		= s3c64xx_sclk_ctrl, -		.ctrlbit	= S3C_CLKCON_SCLK_SCALER27, -	}, { -		.name		= "sclk_scaler", -		.enable		= s3c64xx_sclk_ctrl, -		.ctrlbit	= S3C_CLKCON_SCLK_SCALER, -	}, { -		.name		= "post0_27", -		.enable		= s3c64xx_sclk_ctrl, -		.ctrlbit	= S3C_CLKCON_SCLK_POST0_27, -	}, { -		.name		= "secur", -		.enable		= s3c64xx_sclk_ctrl, -		.ctrlbit	= S3C_CLKCON_SCLK_SECUR, -	}, { -		.name		= "sclk_mfc", -		.enable		= s3c64xx_sclk_ctrl, -		.ctrlbit	= S3C_CLKCON_SCLK_MFC, -	}, { -		.name		= "sclk_jpeg", -		.enable		= s3c64xx_sclk_ctrl, -		.ctrlbit	= S3C_CLKCON_SCLK_JPEG, -	}, -}; - -static struct clk clk_48m_spi0 = { -	.name		= "spi_48m", -	.devname	= "s3c6410-spi.0", -	.parent		= &clk_48m, -	.enable		= s3c64xx_sclk_ctrl, -	.ctrlbit	= S3C_CLKCON_SCLK_SPI0_48, -}; - -static struct clk clk_48m_spi1 = { -	.name		= "spi_48m", -	.devname	= "s3c6410-spi.1", -	.parent		= &clk_48m, -	.enable		= s3c64xx_sclk_ctrl, -	.ctrlbit	= S3C_CLKCON_SCLK_SPI1_48, -}; - -static struct clk clk_i2s0 = { -	.name		= "iis", -	.devname	= "samsung-i2s.0", -	.parent		= &clk_p, -	.enable		= s3c64xx_pclk_ctrl, -	.ctrlbit	= S3C_CLKCON_PCLK_IIS0, -}; - -static struct clk clk_i2s1 = { -	.name		= "iis", -	.devname	= "samsung-i2s.1", -	.parent		= &clk_p, -	.enable		= s3c64xx_pclk_ctrl, -	.ctrlbit	= S3C_CLKCON_PCLK_IIS1, -}; - -#ifdef CONFIG_CPU_S3C6410 -static struct clk clk_i2s2 = { -	.name		= "iis", -	.devname	= "samsung-i2s.2", -	.parent		= &clk_p, -	.enable		= s3c64xx_pclk_ctrl, -	.ctrlbit	= S3C6410_CLKCON_PCLK_IIS2, -}; -#endif - -static struct clk init_clocks[] = { -	{ -		.name		= "lcd", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_LCD, -	}, { -		.name		= "gpio", -		.parent		= &clk_p, -		.enable		= s3c64xx_pclk_ctrl, -		.ctrlbit	= S3C_CLKCON_PCLK_GPIO, -	}, { -		.name		= "usb-host", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_UHOST, -	}, { -		.name		= "otg", -		.parent		= &clk_h, -		.enable		= s3c64xx_hclk_ctrl, -		.ctrlbit	= S3C_CLKCON_HCLK_USB, -	}, { -		.name		= "timers", -		.parent		= &clk_p, -		.enable		= s3c64xx_pclk_ctrl, -		.ctrlbit	= S3C_CLKCON_PCLK_PWM, -	}, { -		.name		= "uart", -		.devname	= "s3c6400-uart.0", -		.parent		= &clk_p, -		.enable		= s3c64xx_pclk_ctrl, -		.ctrlbit	= S3C_CLKCON_PCLK_UART0, -	}, { -		.name		= "uart", -		.devname	= "s3c6400-uart.1", -		.parent		= &clk_p, -		.enable		= s3c64xx_pclk_ctrl, -		.ctrlbit	= S3C_CLKCON_PCLK_UART1, -	}, { -		.name		= "uart", -		.devname	= "s3c6400-uart.2", -		.parent		= &clk_p, -		.enable		= s3c64xx_pclk_ctrl, -		.ctrlbit	= S3C_CLKCON_PCLK_UART2, -	}, { -		.name		= "uart", -		.devname	= "s3c6400-uart.3", -		.parent		= &clk_p, -		.enable		= s3c64xx_pclk_ctrl, -		.ctrlbit	= S3C_CLKCON_PCLK_UART3, -	}, { -		.name		= "watchdog", -		.parent		= &clk_p, -		.ctrlbit	= S3C_CLKCON_PCLK_WDT, -	}, -}; - -static struct clk clk_hsmmc0 = { -	.name		= "hsmmc", -	.devname	= "s3c-sdhci.0", -	.parent		= &clk_h, -	.enable		= s3c64xx_hclk_ctrl, -	.ctrlbit	= S3C_CLKCON_HCLK_HSMMC0, -}; - -static struct clk clk_hsmmc1 = { -	.name		= "hsmmc", -	.devname	= "s3c-sdhci.1", -	.parent		= &clk_h, -	.enable		= s3c64xx_hclk_ctrl, -	.ctrlbit	= S3C_CLKCON_HCLK_HSMMC1, -}; - -static struct clk clk_hsmmc2 = { -	.name		= "hsmmc", -	.devname	= "s3c-sdhci.2", -	.parent		= &clk_h, -	.enable		= s3c64xx_hclk_ctrl, -	.ctrlbit	= S3C_CLKCON_HCLK_HSMMC2, -}; - -static struct clk clk_fout_apll = { -	.name		= "fout_apll", -}; - -static struct clk *clk_src_apll_list[] = { -	[0] = &clk_fin_apll, -	[1] = &clk_fout_apll, -}; - -static struct clksrc_sources clk_src_apll = { -	.sources	= clk_src_apll_list, -	.nr_sources	= ARRAY_SIZE(clk_src_apll_list), -}; - -static struct clksrc_clk clk_mout_apll = { -	.clk	= { -		.name		= "mout_apll", -	}, -	.reg_src	= { .reg = S3C_CLK_SRC, .shift = 0, .size = 1  }, -	.sources	= &clk_src_apll, -}; - -static struct clk *clk_src_epll_list[] = { -	[0] = &clk_fin_epll, -	[1] = &clk_fout_epll, -}; - -static struct clksrc_sources clk_src_epll = { -	.sources	= clk_src_epll_list, -	.nr_sources	= ARRAY_SIZE(clk_src_epll_list), -}; - -static struct clksrc_clk clk_mout_epll = { -	.clk	= { -		.name		= "mout_epll", -	}, -	.reg_src	= { .reg = S3C_CLK_SRC, .shift = 2, .size = 1  }, -	.sources	= &clk_src_epll, -}; - -static struct clk *clk_src_mpll_list[] = { -	[0] = &clk_fin_mpll, -	[1] = &clk_fout_mpll, -}; - -static struct clksrc_sources clk_src_mpll = { -	.sources	= clk_src_mpll_list, -	.nr_sources	= ARRAY_SIZE(clk_src_mpll_list), -}; - -static struct clksrc_clk clk_mout_mpll = { -	.clk = { -		.name		= "mout_mpll", -	}, -	.reg_src	= { .reg = S3C_CLK_SRC, .shift = 1, .size = 1  }, -	.sources	= &clk_src_mpll, -}; - -static unsigned int armclk_mask; - -static unsigned long s3c64xx_clk_arm_get_rate(struct clk *clk) -{ -	unsigned long rate = clk_get_rate(clk->parent); -	u32 clkdiv; - -	/* divisor mask starts at bit0, so no need to shift */ -	clkdiv = __raw_readl(S3C_CLK_DIV0) & armclk_mask; - -	return rate / (clkdiv + 1); -} - -static unsigned long s3c64xx_clk_arm_round_rate(struct clk *clk, -						unsigned long rate) -{ -	unsigned long parent = clk_get_rate(clk->parent); -	u32 div; - -	if (parent < rate) -		return parent; - -	div = (parent / rate) - 1; -	if (div > armclk_mask) -		div = armclk_mask; - -	return parent / (div + 1); -} - -static int s3c64xx_clk_arm_set_rate(struct clk *clk, unsigned long rate) -{ -	unsigned long parent = clk_get_rate(clk->parent); -	u32 div; -	u32 val; - -	if (rate < parent / (armclk_mask + 1)) -		return -EINVAL; - -	rate = clk_round_rate(clk, rate); -	div = clk_get_rate(clk->parent) / rate; - -	val = __raw_readl(S3C_CLK_DIV0); -	val &= ~armclk_mask; -	val |= (div - 1); -	__raw_writel(val, S3C_CLK_DIV0); - -	return 0; - -} - -static struct clk clk_arm = { -	.name		= "armclk", -	.parent		= &clk_mout_apll.clk, -	.ops		= &(struct clk_ops) { -		.get_rate	= s3c64xx_clk_arm_get_rate, -		.set_rate	= s3c64xx_clk_arm_set_rate, -		.round_rate	= s3c64xx_clk_arm_round_rate, -	}, -}; - -static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk) -{ -	unsigned long rate = clk_get_rate(clk->parent); - -	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate); - -	if (__raw_readl(S3C_CLK_DIV0) & S3C6400_CLKDIV0_MPLL_MASK) -		rate /= 2; - -	return rate; -} - -static struct clk_ops clk_dout_ops = { -	.get_rate	= s3c64xx_clk_doutmpll_get_rate, -}; - -static struct clk clk_dout_mpll = { -	.name		= "dout_mpll", -	.parent		= &clk_mout_mpll.clk, -	.ops		= &clk_dout_ops, -}; - -static struct clk *clkset_spi_mmc_list[] = { -	&clk_mout_epll.clk, -	&clk_dout_mpll, -	&clk_fin_epll, -	&clk_27m, -}; - -static struct clksrc_sources clkset_spi_mmc = { -	.sources	= clkset_spi_mmc_list, -	.nr_sources	= ARRAY_SIZE(clkset_spi_mmc_list), -}; - -static struct clk *clkset_irda_list[] = { -	&clk_mout_epll.clk, -	&clk_dout_mpll, -	NULL, -	&clk_27m, -}; - -static struct clksrc_sources clkset_irda = { -	.sources	= clkset_irda_list, -	.nr_sources	= ARRAY_SIZE(clkset_irda_list), -}; - -static struct clk *clkset_uart_list[] = { -	&clk_mout_epll.clk, -	&clk_dout_mpll, -	NULL, -	NULL -}; - -static struct clksrc_sources clkset_uart = { -	.sources	= clkset_uart_list, -	.nr_sources	= ARRAY_SIZE(clkset_uart_list), -}; - -static struct clk *clkset_uhost_list[] = { -	&clk_48m, -	&clk_mout_epll.clk, -	&clk_dout_mpll, -	&clk_fin_epll, -}; - -static struct clksrc_sources clkset_uhost = { -	.sources	= clkset_uhost_list, -	.nr_sources	= ARRAY_SIZE(clkset_uhost_list), -}; - -/* The peripheral clocks are all controlled via clocksource followed - * by an optional divider and gate stage. We currently roll this into - * one clock which hides the intermediate clock from the mux. - * - * Note, the JPEG clock can only be an even divider... - * - * The scaler and LCD clocks depend on the S3C64XX version, and also - * have a common parent divisor so are not included here. - */ - -/* clocks that feed other parts of the clock source tree */ - -static struct clk clk_iis_cd0 = { -	.name		= "iis_cdclk0", -}; - -static struct clk clk_iis_cd1 = { -	.name		= "iis_cdclk1", -}; - -static struct clk clk_iisv4_cd = { -	.name		= "iis_cdclk_v4", -}; - -static struct clk clk_pcm_cd = { -	.name		= "pcm_cdclk", -}; - -static struct clk *clkset_audio0_list[] = { -	[0] = &clk_mout_epll.clk, -	[1] = &clk_dout_mpll, -	[2] = &clk_fin_epll, -	[3] = &clk_iis_cd0, -	[4] = &clk_pcm_cd, -}; - -static struct clksrc_sources clkset_audio0 = { -	.sources	= clkset_audio0_list, -	.nr_sources	= ARRAY_SIZE(clkset_audio0_list), -}; - -static struct clk *clkset_audio1_list[] = { -	[0] = &clk_mout_epll.clk, -	[1] = &clk_dout_mpll, -	[2] = &clk_fin_epll, -	[3] = &clk_iis_cd1, -	[4] = &clk_pcm_cd, -}; - -static struct clksrc_sources clkset_audio1 = { -	.sources	= clkset_audio1_list, -	.nr_sources	= ARRAY_SIZE(clkset_audio1_list), -}; - -#ifdef CONFIG_CPU_S3C6410 -static struct clk *clkset_audio2_list[] = { -	[0] = &clk_mout_epll.clk, -	[1] = &clk_dout_mpll, -	[2] = &clk_fin_epll, -	[3] = &clk_iisv4_cd, -	[4] = &clk_pcm_cd, -}; - -static struct clksrc_sources clkset_audio2 = { -	.sources	= clkset_audio2_list, -	.nr_sources	= ARRAY_SIZE(clkset_audio2_list), -}; -#endif - -static struct clksrc_clk clksrcs[] = { -	{ -		.clk	= { -			.name		= "usb-bus-host", -			.ctrlbit        = S3C_CLKCON_SCLK_UHOST, -			.enable		= s3c64xx_sclk_ctrl, -		}, -		.reg_src 	= { .reg = S3C_CLK_SRC, .shift = 5, .size = 2  }, -		.reg_div	= { .reg = S3C_CLK_DIV1, .shift = 20, .size = 4  }, -		.sources	= &clkset_uhost, -	}, { -		.clk	= { -			.name		= "irda-bus", -			.ctrlbit        = S3C_CLKCON_SCLK_IRDA, -			.enable		= s3c64xx_sclk_ctrl, -		}, -		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 24, .size = 2  }, -		.reg_div	= { .reg = S3C_CLK_DIV2, .shift = 20, .size = 4  }, -		.sources	= &clkset_irda, -	}, { -		.clk	= { -			.name		= "camera", -			.ctrlbit        = S3C_CLKCON_SCLK_CAM, -			.enable		= s3c64xx_sclk_ctrl, -			.parent		= &clk_h2, -		}, -		.reg_div	= { .reg = S3C_CLK_DIV0, .shift = 20, .size = 4  }, -	}, -}; - -/* Where does UCLK0 come from? */ -static struct clksrc_clk clk_sclk_uclk = { -	.clk	= { -		.name		= "uclk1", -		.ctrlbit        = S3C_CLKCON_SCLK_UART, -		.enable		= s3c64xx_sclk_ctrl, -	}, -	.reg_src	= { .reg = S3C_CLK_SRC, .shift = 13, .size = 1  }, -	.reg_div	= { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4  }, -	.sources	= &clkset_uart, -}; - -static struct clksrc_clk clk_sclk_mmc0 = { -	.clk	= { -		.name		= "mmc_bus", -		.devname	= "s3c-sdhci.0", -		.ctrlbit        = S3C_CLKCON_SCLK_MMC0, -		.enable		= s3c64xx_sclk_ctrl, -	}, -	.reg_src	= { .reg = S3C_CLK_SRC, .shift = 18, .size = 2  }, -	.reg_div	= { .reg = S3C_CLK_DIV1, .shift = 0, .size = 4  }, -	.sources	= &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_mmc1 = { -	.clk	= { -		.name		= "mmc_bus", -		.devname	= "s3c-sdhci.1", -		.ctrlbit        = S3C_CLKCON_SCLK_MMC1, -		.enable		= s3c64xx_sclk_ctrl, -	}, -	.reg_src	= { .reg = S3C_CLK_SRC, .shift = 20, .size = 2  }, -	.reg_div	= { .reg = S3C_CLK_DIV1, .shift = 4, .size = 4  }, -	.sources	= &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_mmc2 = { -	.clk	= { -		.name		= "mmc_bus", -		.devname	= "s3c-sdhci.2", -		.ctrlbit        = S3C_CLKCON_SCLK_MMC2, -		.enable		= s3c64xx_sclk_ctrl, -	}, -	.reg_src	= { .reg = S3C_CLK_SRC, .shift = 22, .size = 2  }, -	.reg_div	= { .reg = S3C_CLK_DIV1, .shift = 8, .size = 4  }, -	.sources	= &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_spi0 = { -	.clk	= { -		.name		= "spi-bus", -		.devname	= "s3c6410-spi.0", -		.ctrlbit	= S3C_CLKCON_SCLK_SPI0, -		.enable		= s3c64xx_sclk_ctrl, -	}, -	.reg_src = { .reg = S3C_CLK_SRC, .shift = 14, .size = 2 }, -	.reg_div = { .reg = S3C_CLK_DIV2, .shift = 0, .size = 4 }, -	.sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_spi1 = { -	.clk	= { -		.name		= "spi-bus", -		.devname	= "s3c6410-spi.1", -		.ctrlbit	= S3C_CLKCON_SCLK_SPI1, -		.enable		= s3c64xx_sclk_ctrl, -	}, -	.reg_src = { .reg = S3C_CLK_SRC, .shift = 16, .size = 2 }, -	.reg_div = { .reg = S3C_CLK_DIV2, .shift = 4, .size = 4 }, -	.sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_audio_bus0 = { -	.clk	= { -		.name		= "audio-bus", -		.devname	= "samsung-i2s.0", -		.ctrlbit	= S3C_CLKCON_SCLK_AUDIO0, -		.enable		= s3c64xx_sclk_ctrl, -	}, -	.reg_src	= { .reg = S3C_CLK_SRC, .shift = 7, .size = 3  }, -	.reg_div	= { .reg = S3C_CLK_DIV2, .shift = 8, .size = 4  }, -	.sources	= &clkset_audio0, -}; - -static struct clksrc_clk clk_audio_bus1 = { -	.clk	= { -		.name		= "audio-bus", -		.devname	= "samsung-i2s.1", -		.ctrlbit	= S3C_CLKCON_SCLK_AUDIO1, -		.enable		= s3c64xx_sclk_ctrl, -	}, -	.reg_src	= { .reg = S3C_CLK_SRC, .shift = 10, .size = 3  }, -	.reg_div	= { .reg = S3C_CLK_DIV2, .shift = 12, .size = 4  }, -	.sources	= &clkset_audio1, -}; - -#ifdef CONFIG_CPU_S3C6410 -static struct clksrc_clk clk_audio_bus2 = { -	.clk	= { -		.name		= "audio-bus", -		.devname	= "samsung-i2s.2", -		.ctrlbit	= S3C6410_CLKCON_SCLK_AUDIO2, -		.enable		= s3c64xx_sclk_ctrl, -	}, -	.reg_src	= { .reg = S3C6410_CLK_SRC2, .shift = 0, .size = 3  }, -	.reg_div	= { .reg = S3C_CLK_DIV2, .shift = 24, .size = 4  }, -	.sources	= &clkset_audio2, -}; -#endif -/* Clock initialisation code */ - -static struct clksrc_clk *init_parents[] = { -	&clk_mout_apll, -	&clk_mout_epll, -	&clk_mout_mpll, -}; - -static struct clksrc_clk *clksrc_cdev[] = { -	&clk_sclk_uclk, -	&clk_sclk_mmc0, -	&clk_sclk_mmc1, -	&clk_sclk_mmc2, -	&clk_sclk_spi0, -	&clk_sclk_spi1, -	&clk_audio_bus0, -	&clk_audio_bus1, -}; - -static struct clk *clk_cdev[] = { -	&clk_hsmmc0, -	&clk_hsmmc1, -	&clk_hsmmc2, -	&clk_48m_spi0, -	&clk_48m_spi1, -	&clk_i2s0, -	&clk_i2s1, -}; - -static struct clk_lookup s3c64xx_clk_lookup[] = { -	CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), -	CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk), -	CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0), -	CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1), -	CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2), -	CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk), -	CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), -	CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), -	CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), -	CLKDEV_INIT("s3c6410-spi.0", "spi_busclk1", &clk_sclk_spi0.clk), -	CLKDEV_INIT("s3c6410-spi.0", "spi_busclk2", &clk_48m_spi0), -	CLKDEV_INIT("s3c6410-spi.1", "spi_busclk1", &clk_sclk_spi1.clk), -	CLKDEV_INIT("s3c6410-spi.1", "spi_busclk2", &clk_48m_spi1), -	CLKDEV_INIT("samsung-i2s.0", "i2s_opclk0", &clk_i2s0), -	CLKDEV_INIT("samsung-i2s.0", "i2s_opclk1", &clk_audio_bus0.clk), -	CLKDEV_INIT("samsung-i2s.1", "i2s_opclk0", &clk_i2s1), -	CLKDEV_INIT("samsung-i2s.1", "i2s_opclk1", &clk_audio_bus1.clk), -#ifdef CONFIG_CPU_S3C6410 -	CLKDEV_INIT("samsung-i2s.2", "i2s_opclk0", &clk_i2s2), -	CLKDEV_INIT("samsung-i2s.2", "i2s_opclk1", &clk_audio_bus2.clk), -#endif -}; - -#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) - -void __init_or_cpufreq s3c64xx_setup_clocks(void) -{ -	struct clk *xtal_clk; -	unsigned long xtal; -	unsigned long fclk; -	unsigned long hclk; -	unsigned long hclk2; -	unsigned long pclk; -	unsigned long epll; -	unsigned long apll; -	unsigned long mpll; -	unsigned int ptr; -	u32 clkdiv0; - -	printk(KERN_DEBUG "%s: registering clocks\n", __func__); - -	clkdiv0 = __raw_readl(S3C_CLK_DIV0); -	printk(KERN_DEBUG "%s: clkdiv0 = %08x\n", __func__, clkdiv0); - -	xtal_clk = clk_get(NULL, "xtal"); -	BUG_ON(IS_ERR(xtal_clk)); - -	xtal = clk_get_rate(xtal_clk); -	clk_put(xtal_clk); - -	printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); - -	/* For now assume the mux always selects the crystal */ -	clk_ext_xtal_mux.parent = xtal_clk; - -	epll = s3c_get_pll6553x(xtal, __raw_readl(S3C_EPLL_CON0), -				__raw_readl(S3C_EPLL_CON1)); -	mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON)); -	apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON)); - -	fclk = mpll; - -	printk(KERN_INFO "S3C64XX: PLL settings, A=%ld, M=%ld, E=%ld\n", -	       apll, mpll, epll); - -	if(__raw_readl(S3C64XX_OTHERS) & S3C64XX_OTHERS_SYNCMUXSEL) -		/* Synchronous mode */ -		hclk2 = apll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2); -	else -		/* Asynchronous mode */ -		hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2); - -	hclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK); -	pclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK); - -	printk(KERN_INFO "S3C64XX: HCLK2=%ld, HCLK=%ld, PCLK=%ld\n", -	       hclk2, hclk, pclk); - -	clk_fout_mpll.rate = mpll; -	clk_fout_epll.rate = epll; -	clk_fout_apll.rate = apll; - -	clk_h2.rate = hclk2; -	clk_h.rate = hclk; -	clk_p.rate = pclk; -	clk_f.rate = fclk; - -	for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++) -		s3c_set_clksrc(init_parents[ptr], true); - -	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) -		s3c_set_clksrc(&clksrcs[ptr], true); -} - -static struct clk *clks1[] __initdata = { -	&clk_ext_xtal_mux, -	&clk_iis_cd0, -	&clk_iis_cd1, -	&clk_iisv4_cd, -	&clk_pcm_cd, -	&clk_mout_epll.clk, -	&clk_mout_mpll.clk, -	&clk_dout_mpll, -	&clk_arm, -}; - -static struct clk *clks[] __initdata = { -	&clk_ext, -	&clk_epll, -	&clk_27m, -	&clk_48m, -	&clk_h2, -	&clk_xusbxti, -}; - -/** - * s3c64xx_register_clocks - register clocks for s3c6400 and s3c6410 - * @xtal: The rate for the clock crystal feeding the PLLs. - * @armclk_divlimit: Divisor mask for ARMCLK. - * - * Register the clocks for the S3C6400 and S3C6410 SoC range, such - * as ARMCLK as well as the necessary parent clocks. - * - * This call does not setup the clocks, which is left to the - * s3c64xx_setup_clocks() call which may be needed by the cpufreq - * or resume code to re-set the clocks if the bootloader has changed - * them. - */ -void __init s3c64xx_register_clocks(unsigned long xtal,  -				    unsigned armclk_divlimit) -{ -	unsigned int cnt; - -	armclk_mask = armclk_divlimit; - -	s3c24xx_register_baseclocks(xtal); -	s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); - -	s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); - -	s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); -	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); - -	s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev)); -	for (cnt = 0; cnt < ARRAY_SIZE(clk_cdev); cnt++) -		s3c_disable_clocks(clk_cdev[cnt], 1); - -	s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1)); -	s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); -	for (cnt = 0; cnt < ARRAY_SIZE(clksrc_cdev); cnt++) -		s3c_register_clksrc(clksrc_cdev[cnt], 1); -	clkdev_add_table(s3c64xx_clk_lookup, ARRAY_SIZE(s3c64xx_clk_lookup)); -} diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c index 73d79cf5e14..5c45aae675b 100644 --- a/arch/arm/mach-s3c64xx/common.c +++ b/arch/arm/mach-s3c64xx/common.c @@ -14,12 +14,18 @@   * published by the Free Software Foundation.   */ +/* + * NOTE: Code in this file is not used when booting with Device Tree support. + */ +  #include <linux/kernel.h>  #include <linux/init.h>  #include <linux/module.h> +#include <linux/clk-provider.h>  #include <linux/interrupt.h>  #include <linux/ioport.h>  #include <linux/serial_core.h> +#include <linux/serial_s3c.h>  #include <linux/platform_device.h>  #include <linux/reboot.h>  #include <linux/io.h> @@ -36,20 +42,32 @@  #include <mach/map.h>  #include <mach/hardware.h>  #include <mach/regs-gpio.h> +#include <mach/gpio-samsung.h>  #include <plat/cpu.h> -#include <plat/clock.h>  #include <plat/devs.h>  #include <plat/pm.h>  #include <plat/gpio-cfg.h>  #include <plat/irq-uart.h>  #include <plat/pwm-core.h>  #include <plat/regs-irqtype.h> -#include <plat/regs-serial.h>  #include <plat/watchdog-reset.h>  #include "common.h" +/* External clock frequency */ +static unsigned long xtal_f = 12000000, xusbxti_f = 48000000; + +void __init s3c64xx_set_xtal_freq(unsigned long freq) +{ +	xtal_f = freq; +} + +void __init s3c64xx_set_xusbxti_freq(unsigned long freq) +{ +	xusbxti_f = freq; +} +  /* uart registration process */  static void __init s3c64xx_init_uarts(struct s3c2410_uartcfg *cfg, int no) @@ -67,7 +85,6 @@ static struct cpu_table cpu_ids[] __initdata = {  		.idcode		= S3C6400_CPU_ID,  		.idmask		= S3C64XX_CPU_MASK,  		.map_io		= s3c6400_map_io, -		.init_clocks	= s3c6400_init_clocks,  		.init_uarts	= s3c64xx_init_uarts,  		.init		= s3c6400_init,  		.name		= name_s3c6400, @@ -75,7 +92,6 @@ static struct cpu_table cpu_ids[] __initdata = {  		.idcode		= S3C6410_CPU_ID,  		.idmask		= S3C64XX_CPU_MASK,  		.map_io		= s3c6410_map_io, -		.init_clocks	= s3c6410_init_clocks,  		.init_uarts	= s3c64xx_init_uarts,  		.init		= s3c6410_init,  		.name		= name_s3c6410, @@ -192,6 +208,10 @@ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)  static __init int s3c64xx_dev_init(void)  { +	/* Not applicable when using DT. */ +	if (of_have_populated_dt()) +		return 0; +  	subsys_system_register(&s3c64xx_subsys, NULL);  	return device_register(&s3c64xx_dev);  } @@ -213,8 +233,10 @@ void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)  {  	/*  	 * FIXME: there is no better place to put this at the moment -	 * (samsung_wdt_reset_init needs clocks) +	 * (s3c64xx_clk_init needs ioremap and must happen before init_time +	 * samsung_wdt_reset_init needs clocks)  	 */ +	s3c64xx_clk_init(NULL, xtal_f, xusbxti_f, soc_is_s3c6400(), S3C_VA_SYS);  	samsung_wdt_reset_init(S3C_VA_WATCHDOG);  	printk(KERN_DEBUG "%s: initialising interrupts\n", __func__); @@ -391,6 +413,10 @@ static int __init s3c64xx_init_irq_eint(void)  {  	int irq; +	/* On DT-enabled systems EINTs are handled by pinctrl-s3c64xx driver. */ +	if (of_have_populated_dt()) +		return -ENODEV; +  	for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {  		irq_set_chip_and_handler(irq, &s3c_irq_eint, handle_level_irq);  		irq_set_chip_data(irq, (void *)eint_irq_to_bit(irq)); diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c64xx/common.h index e8f990b3766..7043e7a3a67 100644 --- a/arch/arm/mach-s3c64xx/common.h +++ b/arch/arm/mach-s3c64xx/common.h @@ -22,21 +22,21 @@  void s3c64xx_init_irq(u32 vic0, u32 vic1);  void s3c64xx_init_io(struct map_desc *mach_desc, int size); -void s3c64xx_register_clocks(unsigned long xtal, unsigned armclk_limit); -void s3c64xx_setup_clocks(void); -  void s3c64xx_restart(enum reboot_mode mode, const char *cmd);  void s3c64xx_init_late(void); +void s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, +	unsigned long xusbxti_f, bool is_s3c6400, void __iomem *reg_base); +void s3c64xx_set_xtal_freq(unsigned long freq); +void s3c64xx_set_xusbxti_freq(unsigned long freq); +  #ifdef CONFIG_CPU_S3C6400  extern  int s3c6400_init(void);  extern void s3c6400_init_irq(void);  extern void s3c6400_map_io(void); -extern void s3c6400_init_clocks(int xtal);  #else -#define s3c6400_init_clocks NULL  #define s3c6400_map_io NULL  #define s3c6400_init NULL  #endif @@ -46,10 +46,8 @@ extern void s3c6400_init_clocks(int xtal);  extern  int s3c6410_init(void);  extern void s3c6410_init_irq(void);  extern void s3c6410_map_io(void); -extern void s3c6410_init_clocks(int xtal);  #else -#define s3c6410_init_clocks NULL  #define s3c6410_map_io NULL  #define s3c6410_init NULL  #endif @@ -60,4 +58,9 @@ int __init s3c64xx_pm_late_initcall(void);  static inline int s3c64xx_pm_late_initcall(void) { return 0; }  #endif +#ifdef CONFIG_S3C64XX_PL080 +extern struct pl08x_platform_data s3c64xx_dma0_plat_data; +extern struct pl08x_platform_data s3c64xx_dma1_plat_data; +#endif +  #endif /* __ARCH_ARM_MACH_S3C64XX_COMMON_H */ diff --git a/arch/arm/mach-s3c64xx/crag6410.h b/arch/arm/mach-s3c64xx/crag6410.h index 4c3c9994fc2..7bc66682687 100644 --- a/arch/arm/mach-s3c64xx/crag6410.h +++ b/arch/arm/mach-s3c64xx/crag6410.h @@ -11,7 +11,7 @@  #ifndef MACH_CRAG6410_H  #define MACH_CRAG6410_H -#include <linux/gpio.h> +#include <mach/gpio-samsung.h>  #define GLENFARCLAS_PMIC_IRQ_BASE	IRQ_BOARD_START diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c index e367e87bbc2..ff780a8d836 100644 --- a/arch/arm/mach-s3c64xx/dev-audio.c +++ b/arch/arm/mach-s3c64xx/dev-audio.c @@ -22,6 +22,7 @@  #include <plat/devs.h>  #include <linux/platform_data/asoc-s3c.h>  #include <plat/gpio-cfg.h> +#include <mach/gpio-samsung.h>  static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev)  { diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c deleted file mode 100644 index 759846c28d1..00000000000 --- a/arch/arm/mach-s3c64xx/dma.c +++ /dev/null @@ -1,753 +0,0 @@ -/* linux/arch/arm/plat-s3c64xx/dma.c - * - * Copyright 2009 Openmoko, Inc. - * Copyright 2009 Simtec Electronics - *	Ben Dooks <ben@simtec.co.uk> - *	http://armlinux.simtec.co.uk/ - * - * S3C64XX DMA core - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/dmapool.h> -#include <linux/device.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/amba/pl080.h> - -#include <mach/dma.h> -#include <mach/map.h> -#include <mach/irqs.h> - -#include "regs-sys.h" - -/* dma channel state information */ - -struct s3c64xx_dmac { -	struct device		dev; -	struct clk		*clk; -	void __iomem		*regs; -	struct s3c2410_dma_chan *channels; -	enum dma_ch		 chanbase; -}; - -/* pool to provide LLI buffers */ -static struct dma_pool *dma_pool; - -/* Debug configuration and code */ - -static unsigned char debug_show_buffs = 0; - -static void dbg_showchan(struct s3c2410_dma_chan *chan) -{ -	pr_debug("DMA%d: %08x->%08x L %08x C %08x,%08x S %08x\n", -		 chan->number, -		 readl(chan->regs + PL080_CH_SRC_ADDR), -		 readl(chan->regs + PL080_CH_DST_ADDR), -		 readl(chan->regs + PL080_CH_LLI), -		 readl(chan->regs + PL080_CH_CONTROL), -		 readl(chan->regs + PL080S_CH_CONTROL2), -		 readl(chan->regs + PL080S_CH_CONFIG)); -} - -static void show_lli(struct pl080s_lli *lli) -{ -	pr_debug("LLI[%p] %08x->%08x, NL %08x C %08x,%08x\n", -		 lli, lli->src_addr, lli->dst_addr, lli->next_lli, -		 lli->control0, lli->control1); -} - -static void dbg_showbuffs(struct s3c2410_dma_chan *chan) -{ -	struct s3c64xx_dma_buff *ptr; -	struct s3c64xx_dma_buff *end; - -	pr_debug("DMA%d: buffs next %p, curr %p, end %p\n", -		 chan->number, chan->next, chan->curr, chan->end); - -	ptr = chan->next; -	end = chan->end; - -	if (debug_show_buffs) { -		for (; ptr != NULL; ptr = ptr->next) { -			pr_debug("DMA%d: %08x ", -				 chan->number, ptr->lli_dma); -			show_lli(ptr->lli); -		} -	} -} - -/* End of Debug */ - -static struct s3c2410_dma_chan *s3c64xx_dma_map_channel(unsigned int channel) -{ -	struct s3c2410_dma_chan *chan; -	unsigned int start, offs; - -	start = 0; - -	if (channel >= DMACH_PCM1_TX) -		start = 8; - -	for (offs = 0; offs < 8; offs++) { -		chan = &s3c2410_chans[start + offs]; -		if (!chan->in_use) -			goto found; -	} - -	return NULL; - -found: -	s3c_dma_chan_map[channel] = chan; -	return chan; -} - -int s3c2410_dma_config(enum dma_ch channel, int xferunit) -{ -	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); - -	if (chan == NULL) -		return -EINVAL; - -	switch (xferunit) { -	case 1: -		chan->hw_width = 0; -		break; -	case 2: -		chan->hw_width = 1; -		break; -	case 4: -		chan->hw_width = 2; -		break; -	default: -		printk(KERN_ERR "%s: illegal width %d\n", __func__, xferunit); -		return -EINVAL; -	} - -	return 0; -} -EXPORT_SYMBOL(s3c2410_dma_config); - -static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan, -				 struct pl080s_lli *lli, -				 dma_addr_t data, int size) -{ -	dma_addr_t src, dst; -	u32 control0, control1; - -	switch (chan->source) { -	case DMA_FROM_DEVICE: -		src = chan->dev_addr; -		dst = data; -		control0 = PL080_CONTROL_SRC_AHB2; -		control0 |= PL080_CONTROL_DST_INCR; -		break; - -	case DMA_TO_DEVICE: -		src = data; -		dst = chan->dev_addr; -		control0 = PL080_CONTROL_DST_AHB2; -		control0 |= PL080_CONTROL_SRC_INCR; -		break; -	default: -		BUG(); -	} - -	/* note, we do not currently setup any of the burst controls */ - -	control1 = size >> chan->hw_width;	/* size in no of xfers */ -	control0 |= PL080_CONTROL_PROT_SYS;	/* always in priv. mode */ -	control0 |= PL080_CONTROL_TC_IRQ_EN;	/* always fire IRQ */ -	control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT; -	control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT; - -	lli->src_addr = src; -	lli->dst_addr = dst; -	lli->next_lli = 0; -	lli->control0 = control0; -	lli->control1 = control1; -} - -static void s3c64xx_lli_to_regs(struct s3c2410_dma_chan *chan, -				struct pl080s_lli *lli) -{ -	void __iomem *regs = chan->regs; - -	pr_debug("%s: LLI %p => regs\n", __func__, lli); -	show_lli(lli); - -	writel(lli->src_addr, regs + PL080_CH_SRC_ADDR); -	writel(lli->dst_addr, regs + PL080_CH_DST_ADDR); -	writel(lli->next_lli, regs + PL080_CH_LLI); -	writel(lli->control0, regs + PL080_CH_CONTROL); -	writel(lli->control1, regs + PL080S_CH_CONTROL2); -} - -static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan) -{ -	struct s3c64xx_dmac *dmac = chan->dmac; -	u32 config; -	u32 bit = chan->bit; - -	dbg_showchan(chan); - -	pr_debug("%s: clearing interrupts\n", __func__); - -	/* clear interrupts */ -	writel(bit, dmac->regs + PL080_TC_CLEAR); -	writel(bit, dmac->regs + PL080_ERR_CLEAR); - -	pr_debug("%s: starting channel\n", __func__); - -	config = readl(chan->regs + PL080S_CH_CONFIG); -	config |= PL080_CONFIG_ENABLE; -	config &= ~PL080_CONFIG_HALT; - -	pr_debug("%s: writing config %08x\n", __func__, config); -	writel(config, chan->regs + PL080S_CH_CONFIG); - -	return 0; -} - -static int s3c64xx_dma_stop(struct s3c2410_dma_chan *chan) -{ -	u32 config; -	int timeout; - -	pr_debug("%s: stopping channel\n", __func__); - -	dbg_showchan(chan); - -	config = readl(chan->regs + PL080S_CH_CONFIG); -	config |= PL080_CONFIG_HALT; -	writel(config, chan->regs + PL080S_CH_CONFIG); - -	timeout = 1000; -	do { -		config = readl(chan->regs + PL080S_CH_CONFIG); -		pr_debug("%s: %d - config %08x\n", __func__, timeout, config); -		if (config & PL080_CONFIG_ACTIVE) -			udelay(10); -		else -			break; -		} while (--timeout > 0); - -	if (config & PL080_CONFIG_ACTIVE) { -		printk(KERN_ERR "%s: channel still active\n", __func__); -		return -EFAULT; -	} - -	config = readl(chan->regs + PL080S_CH_CONFIG); -	config &= ~PL080_CONFIG_ENABLE; -	writel(config, chan->regs + PL080S_CH_CONFIG); - -	return 0; -} - -static inline void s3c64xx_dma_bufffdone(struct s3c2410_dma_chan *chan, -					 struct s3c64xx_dma_buff *buf, -					 enum s3c2410_dma_buffresult result) -{ -	if (chan->callback_fn != NULL) -		(chan->callback_fn)(chan, buf->pw, 0, result); -} - -static void s3c64xx_dma_freebuff(struct s3c64xx_dma_buff *buff) -{ -	dma_pool_free(dma_pool, buff->lli, buff->lli_dma); -	kfree(buff); -} - -static int s3c64xx_dma_flush(struct s3c2410_dma_chan *chan) -{ -	struct s3c64xx_dma_buff *buff, *next; -	u32 config; - -	dbg_showchan(chan); - -	pr_debug("%s: flushing channel\n", __func__); - -	config = readl(chan->regs + PL080S_CH_CONFIG); -	config &= ~PL080_CONFIG_ENABLE; -	writel(config, chan->regs + PL080S_CH_CONFIG); - -	/* dump all the buffers associated with this channel */ - -	for (buff = chan->curr; buff != NULL; buff = next) { -		next = buff->next; -		pr_debug("%s: buff %p (next %p)\n", __func__, buff, buff->next); - -		s3c64xx_dma_bufffdone(chan, buff, S3C2410_RES_ABORT); -		s3c64xx_dma_freebuff(buff); -	} - -	chan->curr = chan->next = chan->end = NULL; - -	return 0; -} - -int s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op) -{ -	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); - -	WARN_ON(!chan); -	if (!chan) -		return -EINVAL; - -	switch (op) { -	case S3C2410_DMAOP_START: -		return s3c64xx_dma_start(chan); - -	case S3C2410_DMAOP_STOP: -		return s3c64xx_dma_stop(chan); - -	case S3C2410_DMAOP_FLUSH: -		return s3c64xx_dma_flush(chan); - -	/* believe PAUSE/RESUME are no-ops */ -	case S3C2410_DMAOP_PAUSE: -	case S3C2410_DMAOP_RESUME: -	case S3C2410_DMAOP_STARTED: -	case S3C2410_DMAOP_TIMEOUT: -		return 0; -	} - -	return -ENOENT; -} -EXPORT_SYMBOL(s3c2410_dma_ctrl); - -/* s3c2410_dma_enque - * - */ - -int s3c2410_dma_enqueue(enum dma_ch channel, void *id, -			dma_addr_t data, int size) -{ -	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); -	struct s3c64xx_dma_buff *next; -	struct s3c64xx_dma_buff *buff; -	struct pl080s_lli *lli; -	unsigned long flags; -	int ret; - -	WARN_ON(!chan); -	if (!chan) -		return -EINVAL; - -	buff = kzalloc(sizeof(struct s3c64xx_dma_buff), GFP_ATOMIC); -	if (!buff) { -		printk(KERN_ERR "%s: no memory for buffer\n", __func__); -		return -ENOMEM; -	} - -	lli = dma_pool_alloc(dma_pool, GFP_ATOMIC, &buff->lli_dma); -	if (!lli) { -		printk(KERN_ERR "%s: no memory for lli\n", __func__); -		ret = -ENOMEM; -		goto err_buff; -	} - -	pr_debug("%s: buff %p, dp %08x lli (%p, %08x) %d\n", -		 __func__, buff, data, lli, (u32)buff->lli_dma, size); - -	buff->lli = lli; -	buff->pw = id; - -	s3c64xx_dma_fill_lli(chan, lli, data, size); - -	local_irq_save(flags); - -	if ((next = chan->next) != NULL) { -		struct s3c64xx_dma_buff *end = chan->end; -		struct pl080s_lli *endlli = end->lli; - -		pr_debug("enquing onto channel\n"); - -		end->next = buff; -		endlli->next_lli = buff->lli_dma; - -		if (chan->flags & S3C2410_DMAF_CIRCULAR) { -			struct s3c64xx_dma_buff *curr = chan->curr; -			lli->next_lli = curr->lli_dma; -		} - -		if (next == chan->curr) { -			writel(buff->lli_dma, chan->regs + PL080_CH_LLI); -			chan->next = buff; -		} - -		show_lli(endlli); -		chan->end = buff; -	} else { -		pr_debug("enquing onto empty channel\n"); - -		chan->curr = buff; -		chan->next = buff; -		chan->end = buff; - -		s3c64xx_lli_to_regs(chan, lli); -	} - -	local_irq_restore(flags); - -	show_lli(lli); - -	dbg_showchan(chan); -	dbg_showbuffs(chan); -	return 0; - -err_buff: -	kfree(buff); -	return ret; -} - -EXPORT_SYMBOL(s3c2410_dma_enqueue); - - -int s3c2410_dma_devconfig(enum dma_ch channel, -			  enum dma_data_direction source, -			  unsigned long devaddr) -{ -	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); -	u32 peripheral; -	u32 config = 0; - -	pr_debug("%s: channel %d, source %d, dev %08lx, chan %p\n", -		 __func__, channel, source, devaddr, chan); - -	WARN_ON(!chan); -	if (!chan) -		return -EINVAL; - -	peripheral = (chan->peripheral & 0xf); -	chan->source = source; -	chan->dev_addr = devaddr; - -	pr_debug("%s: peripheral %d\n", __func__, peripheral); - -	switch (source) { -	case DMA_FROM_DEVICE: -		config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT; -		config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT; -		break; -	case DMA_TO_DEVICE: -		config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT; -		config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT; -		break; -	default: -		printk(KERN_ERR "%s: bad source\n", __func__); -		return -EINVAL; -	} - -	/* allow TC and ERR interrupts */ -	config |= PL080_CONFIG_TC_IRQ_MASK; -	config |= PL080_CONFIG_ERR_IRQ_MASK; - -	pr_debug("%s: config %08x\n", __func__, config); - -	writel(config, chan->regs + PL080S_CH_CONFIG); - -	return 0; -} -EXPORT_SYMBOL(s3c2410_dma_devconfig); - - -int s3c2410_dma_getposition(enum dma_ch channel, -			    dma_addr_t *src, dma_addr_t *dst) -{ -	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); - -	WARN_ON(!chan); -	if (!chan) -		return -EINVAL; - -	if (src != NULL) -		*src = readl(chan->regs + PL080_CH_SRC_ADDR); - -	if (dst != NULL) -		*dst = readl(chan->regs + PL080_CH_DST_ADDR); - -	return 0; -} -EXPORT_SYMBOL(s3c2410_dma_getposition); - -/* s3c2410_request_dma - * - * get control of an dma channel -*/ - -int s3c2410_dma_request(enum dma_ch channel, -			struct s3c2410_dma_client *client, -			void *dev) -{ -	struct s3c2410_dma_chan *chan; -	unsigned long flags; - -	pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n", -		 channel, client->name, dev); - -	local_irq_save(flags); - -	chan = s3c64xx_dma_map_channel(channel); -	if (chan == NULL) { -		local_irq_restore(flags); -		return -EBUSY; -	} - -	dbg_showchan(chan); - -	chan->client = client; -	chan->in_use = 1; -	chan->peripheral = channel; -	chan->flags = 0; - -	local_irq_restore(flags); - -	/* need to setup */ - -	pr_debug("%s: channel initialised, %p\n", __func__, chan); - -	return chan->number | DMACH_LOW_LEVEL; -} - -EXPORT_SYMBOL(s3c2410_dma_request); - -/* s3c2410_dma_free - * - * release the given channel back to the system, will stop and flush - * any outstanding transfers, and ensure the channel is ready for the - * next claimant. - * - * Note, although a warning is currently printed if the freeing client - * info is not the same as the registrant's client info, the free is still - * allowed to go through. -*/ - -int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *client) -{ -	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); -	unsigned long flags; - -	if (chan == NULL) -		return -EINVAL; - -	local_irq_save(flags); - -	if (chan->client != client) { -		printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n", -		       channel, chan->client, client); -	} - -	/* sort out stopping and freeing the channel */ - - -	chan->client = NULL; -	chan->in_use = 0; - -	if (!(channel & DMACH_LOW_LEVEL)) -		s3c_dma_chan_map[channel] = NULL; - -	local_irq_restore(flags); - -	return 0; -} - -EXPORT_SYMBOL(s3c2410_dma_free); - -static irqreturn_t s3c64xx_dma_irq(int irq, void *pw) -{ -	struct s3c64xx_dmac *dmac = pw; -	struct s3c2410_dma_chan *chan; -	enum s3c2410_dma_buffresult res; -	u32 tcstat, errstat; -	u32 bit; -	int offs; - -	tcstat = readl(dmac->regs + PL080_TC_STATUS); -	errstat = readl(dmac->regs + PL080_ERR_STATUS); - -	for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) { -		struct s3c64xx_dma_buff *buff; - -		if (!(errstat & bit) && !(tcstat & bit)) -			continue; - -		chan = dmac->channels + offs; -		res = S3C2410_RES_ERR; - -		if (tcstat & bit) { -			writel(bit, dmac->regs + PL080_TC_CLEAR); -			res = S3C2410_RES_OK; -		} - -		if (errstat & bit) -			writel(bit, dmac->regs + PL080_ERR_CLEAR); - -		/* 'next' points to the buffer that is next to the -		 * currently active buffer. -		 * For CIRCULAR queues, 'next' will be same as 'curr' -		 * when 'end' is the active buffer. -		 */ -		buff = chan->curr; -		while (buff && buff != chan->next -				&& buff->next != chan->next) -			buff = buff->next; - -		if (!buff) -			BUG(); - -		if (buff == chan->next) -			buff = chan->end; - -		s3c64xx_dma_bufffdone(chan, buff, res); - -		/* Free the node and update curr, if non-circular queue */ -		if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) { -			chan->curr = buff->next; -			s3c64xx_dma_freebuff(buff); -		} - -		/* Update 'next' */ -		buff = chan->next; -		if (chan->next == chan->end) { -			chan->next = chan->curr; -			if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) -				chan->end = NULL; -		} else { -			chan->next = buff->next; -		} -	} - -	return IRQ_HANDLED; -} - -static struct bus_type dma_subsys = { -	.name		= "s3c64xx-dma", -	.dev_name	= "s3c64xx-dma", -}; - -static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, -			     int irq, unsigned int base) -{ -	struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno]; -	struct s3c64xx_dmac *dmac; -	char clkname[16]; -	void __iomem *regs; -	void __iomem *regptr; -	int err, ch; - -	dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL); -	if (!dmac) { -		printk(KERN_ERR "%s: failed to alloc mem\n", __func__); -		return -ENOMEM; -	} - -	dmac->dev.id = chno / 8; -	dmac->dev.bus = &dma_subsys; - -	err = device_register(&dmac->dev); -	if (err) { -		printk(KERN_ERR "%s: failed to register device\n", __func__); -		goto err_alloc; -	} - -	regs = ioremap(base, 0x200); -	if (!regs) { -		printk(KERN_ERR "%s: failed to ioremap()\n", __func__); -		err = -ENXIO; -		goto err_dev; -	} - -	snprintf(clkname, sizeof(clkname), "dma%d", dmac->dev.id); - -	dmac->clk = clk_get(NULL, clkname); -	if (IS_ERR(dmac->clk)) { -		printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname); -		err = PTR_ERR(dmac->clk); -		goto err_map; -	} - -	clk_enable(dmac->clk); - -	dmac->regs = regs; -	dmac->chanbase = chbase; -	dmac->channels = chptr; - -	err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac); -	if (err < 0) { -		printk(KERN_ERR "%s: failed to get irq\n", __func__); -		goto err_clk; -	} - -	regptr = regs + PL080_Cx_BASE(0); - -	for (ch = 0; ch < 8; ch++, chptr++) { -		pr_debug("%s: registering DMA %d (%p)\n", -			 __func__, chno + ch, regptr); - -		chptr->bit = 1 << ch; -		chptr->number = chno + ch; -		chptr->dmac = dmac; -		chptr->regs = regptr; -		regptr += PL080_Cx_STRIDE; -	} - -	/* for the moment, permanently enable the controller */ -	writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG); - -	printk(KERN_INFO "PL080: IRQ %d, at %p, channels %d..%d\n", -	       irq, regs, chno, chno+8); - -	return 0; - -err_clk: -	clk_disable(dmac->clk); -	clk_put(dmac->clk); -err_map: -	iounmap(regs); -err_dev: -	device_unregister(&dmac->dev); -err_alloc: -	kfree(dmac); -	return err; -} - -static int __init s3c64xx_dma_init(void) -{ -	int ret; - -	printk(KERN_INFO "%s: Registering DMA channels\n", __func__); - -	dma_pool = dma_pool_create("DMA-LLI", NULL, sizeof(struct pl080s_lli), 16, 0); -	if (!dma_pool) { -		printk(KERN_ERR "%s: failed to create pool\n", __func__); -		return -ENOMEM; -	} - -	ret = subsys_system_register(&dma_subsys, NULL); -	if (ret) { -		printk(KERN_ERR "%s: failed to create subsys\n", __func__); -		return -ENOMEM; -	} - -	/* Set all DMA configuration to be DMA, not SDMA */ -	writel(0xffffff, S3C64XX_SDMA_SEL); - -	/* Register standard DMA controllers */ -	s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000); -	s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000); - -	return 0; -} - -arch_initcall(s3c64xx_dma_init); diff --git a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S index dd9ccca5de1..c9b95325b67 100644 --- a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S +++ b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S @@ -12,8 +12,8 @@  /* pull in the relevant register and map files. */ +#include <linux/serial_s3c.h>  #include <mach/map.h> -#include <plat/regs-serial.h>  	/* note, for the boot process to work we have to keep the UART  	 * virtual address aligned to an 1MiB boundary for the L1 diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h index fe1a98cf0e4..059b1fc8503 100644 --- a/arch/arm/mach-s3c64xx/include/mach/dma.h +++ b/arch/arm/mach-s3c64xx/include/mach/dma.h @@ -11,51 +11,48 @@  #ifndef __ASM_ARCH_DMA_H  #define __ASM_ARCH_DMA_H __FILE__ -#define S3C_DMA_CHANNELS	(16) +#define S3C64XX_DMA_CHAN(name)		((unsigned long)(name)) + +/* DMA0/SDMA0 */ +#define DMACH_UART0		S3C64XX_DMA_CHAN("uart0_tx") +#define DMACH_UART0_SRC2	S3C64XX_DMA_CHAN("uart0_rx") +#define DMACH_UART1		S3C64XX_DMA_CHAN("uart1_tx") +#define DMACH_UART1_SRC2	S3C64XX_DMA_CHAN("uart1_rx") +#define DMACH_UART2		S3C64XX_DMA_CHAN("uart2_tx") +#define DMACH_UART2_SRC2	S3C64XX_DMA_CHAN("uart2_rx") +#define DMACH_UART3		S3C64XX_DMA_CHAN("uart3_tx") +#define DMACH_UART3_SRC2	S3C64XX_DMA_CHAN("uart3_rx") +#define DMACH_PCM0_TX		S3C64XX_DMA_CHAN("pcm0_tx") +#define DMACH_PCM0_RX		S3C64XX_DMA_CHAN("pcm0_rx") +#define DMACH_I2S0_OUT		S3C64XX_DMA_CHAN("i2s0_tx") +#define DMACH_I2S0_IN		S3C64XX_DMA_CHAN("i2s0_rx") +#define DMACH_SPI0_TX		S3C64XX_DMA_CHAN("spi0_tx") +#define DMACH_SPI0_RX		S3C64XX_DMA_CHAN("spi0_rx") +#define DMACH_HSI_I2SV40_TX	S3C64XX_DMA_CHAN("i2s2_tx") +#define DMACH_HSI_I2SV40_RX	S3C64XX_DMA_CHAN("i2s2_rx") + +/* DMA1/SDMA1 */ +#define DMACH_PCM1_TX		S3C64XX_DMA_CHAN("pcm1_tx") +#define DMACH_PCM1_RX		S3C64XX_DMA_CHAN("pcm1_rx") +#define DMACH_I2S1_OUT		S3C64XX_DMA_CHAN("i2s1_tx") +#define DMACH_I2S1_IN		S3C64XX_DMA_CHAN("i2s1_rx") +#define DMACH_SPI1_TX		S3C64XX_DMA_CHAN("spi1_tx") +#define DMACH_SPI1_RX		S3C64XX_DMA_CHAN("spi1_rx") +#define DMACH_AC97_PCMOUT	S3C64XX_DMA_CHAN("ac97_out") +#define DMACH_AC97_PCMIN	S3C64XX_DMA_CHAN("ac97_in") +#define DMACH_AC97_MICIN	S3C64XX_DMA_CHAN("ac97_mic") +#define DMACH_PWM		S3C64XX_DMA_CHAN("pwm") +#define DMACH_IRDA		S3C64XX_DMA_CHAN("irda") +#define DMACH_EXTERNAL		S3C64XX_DMA_CHAN("external") +#define DMACH_SECURITY_RX	S3C64XX_DMA_CHAN("sec_rx") +#define DMACH_SECURITY_TX	S3C64XX_DMA_CHAN("sec_tx") -/* see mach-s3c2410/dma.h for notes on dma channel numbers */ - -/* Note, for the S3C64XX architecture we keep the DMACH_ - * defines in the order they are allocated to [S]DMA0/[S]DMA1 - * so that is easy to do DHACH_ -> DMA controller conversion - */  enum dma_ch { -	/* DMA0/SDMA0 */ -	DMACH_UART0 = 0, -	DMACH_UART0_SRC2, -	DMACH_UART1, -	DMACH_UART1_SRC2, -	DMACH_UART2, -	DMACH_UART2_SRC2, -	DMACH_UART3, -	DMACH_UART3_SRC2, -	DMACH_PCM0_TX, -	DMACH_PCM0_RX, -	DMACH_I2S0_OUT, -	DMACH_I2S0_IN, -	DMACH_SPI0_TX, -	DMACH_SPI0_RX, -	DMACH_HSI_I2SV40_TX, -	DMACH_HSI_I2SV40_RX, +	DMACH_MAX = 32 +}; -	/* DMA1/SDMA1 */ -	DMACH_PCM1_TX = 16, -	DMACH_PCM1_RX, -	DMACH_I2S1_OUT, -	DMACH_I2S1_IN, -	DMACH_SPI1_TX, -	DMACH_SPI1_RX, -	DMACH_AC97_PCMOUT, -	DMACH_AC97_PCMIN, -	DMACH_AC97_MICIN, -	DMACH_PWM, -	DMACH_IRDA, -	DMACH_EXTERNAL, -	DMACH_RES1, -	DMACH_RES2, -	DMACH_SECURITY_RX,	/* SDMA1 only */ -	DMACH_SECURITY_TX,	/* SDMA1 only */ -	DMACH_MAX		/* the end */ +struct s3c2410_dma_client { +	char	*name;  };  static inline bool samsung_dma_has_circular(void) @@ -65,67 +62,10 @@ static inline bool samsung_dma_has_circular(void)  static inline bool samsung_dma_is_dmadev(void)  { -	return false; +	return true;  } -#define S3C2410_DMAF_CIRCULAR		(1 << 0) - -#include <plat/dma.h> - -#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */ - -struct s3c64xx_dma_buff; - -/** s3c64xx_dma_buff - S3C64XX DMA buffer descriptor - * @next: Pointer to next buffer in queue or ring. - * @pw: Client provided identifier - * @lli: Pointer to hardware descriptor this buffer is associated with. - * @lli_dma: Hardare address of the descriptor. - */ -struct s3c64xx_dma_buff { -	struct s3c64xx_dma_buff *next; - -	void			*pw; -	struct pl080s_lli	*lli; -	dma_addr_t		 lli_dma; -}; - -struct s3c64xx_dmac; - -struct s3c2410_dma_chan { -	unsigned char		 number;      /* number of this dma channel */ -	unsigned char		 in_use;      /* channel allocated */ -	unsigned char		 bit;	      /* bit for enable/disable/etc */ -	unsigned char		 hw_width; -	unsigned char		 peripheral; - -	unsigned int		 flags; -	enum dma_data_direction	 source; - - -	dma_addr_t		dev_addr; - -	struct s3c2410_dma_client *client; -	struct s3c64xx_dmac	*dmac;		/* pointer to controller */ - -	void __iomem		*regs; - -	/* cdriver callbacks */ -	s3c2410_dma_cbfn_t	 callback_fn;	/* buffer done callback */ -	s3c2410_dma_opfn_t	 op_fn;		/* channel op callback */ - -	/* buffer list and information */ -	struct s3c64xx_dma_buff	*curr;		/* current dma buffer */ -	struct s3c64xx_dma_buff	*next;		/* next buffer to load */ -	struct s3c64xx_dma_buff	*end;		/* end of queue */ - -	/* note, when channel is running in circular mode, curr is the -	 * first buffer enqueued, end is the last and curr is where the -	 * last buffer-done event is set-at. The buffers are not freed -	 * and the last buffer hardware descriptor points back to the -	 * first. -	 */ -}; -#include <plat/dma-core.h> +#include <linux/amba/pl08x.h> +#include <plat/dma-ops.h>  #endif /* __ASM_ARCH_IRQ_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio.h b/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h index 8b540c42d5d..9c81fac3b2d 100644 --- a/arch/arm/mach-s3c64xx/include/mach/gpio.h +++ b/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h @@ -1,5 +1,4 @@ -/* arch/arm/mach-s3c6400/include/mach/gpio.h - * +/*   * Copyright 2008 Openmoko, Inc.   * Copyright 2008 Simtec Electronics   *	http://armlinux.simtec.co.uk/ @@ -12,6 +11,9 @@   * published by the Free Software Foundation.  */ +#ifndef GPIO_SAMSUNG_S3C64XX_H +#define GPIO_SAMSUNG_S3C64XX_H +  /* GPIO bank sizes */  #define S3C64XX_GPIO_A_NR	(8)  #define S3C64XX_GPIO_B_NR	(7) @@ -88,6 +90,5 @@ enum s3c_gpio_number {  /* define the number of gpios we need to the one after the GPQ() range */  #define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1) -#define BOARD_NR_GPIOS	(16 + CONFIG_SAMSUNG_GPIO_EXTRA) +#endif /* GPIO_SAMSUNG_S3C64XX_H */ -#define ARCH_NR_GPIOS	(GPIO_BOARD_START + BOARD_NR_GPIOS) diff --git a/arch/arm/mach-s3c64xx/include/mach/pm-core.h b/arch/arm/mach-s3c64xx/include/mach/pm-core.h index c0537f40a3d..a30a1e3ffc6 100644 --- a/arch/arm/mach-s3c64xx/include/mach/pm-core.h +++ b/arch/arm/mach-s3c64xx/include/mach/pm-core.h @@ -15,6 +15,8 @@  #ifndef __MACH_S3C64XX_PM_CORE_H  #define __MACH_S3C64XX_PM_CORE_H __FILE__ +#include <linux/serial_s3c.h> +  #include <mach/regs-gpio.h>  static inline void s3c_pm_debug_init_uart(void) diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h index 05332b998ec..4f44aac7709 100644 --- a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h +++ b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h @@ -15,145 +15,21 @@  #ifndef __PLAT_REGS_CLOCK_H  #define __PLAT_REGS_CLOCK_H __FILE__ +/* + * FIXME: Remove remaining definitions + */ +  #define S3C_CLKREG(x)		(S3C_VA_SYS + (x)) -#define S3C_APLL_LOCK		S3C_CLKREG(0x00) -#define S3C_MPLL_LOCK		S3C_CLKREG(0x04) -#define S3C_EPLL_LOCK		S3C_CLKREG(0x08) -#define S3C_APLL_CON		S3C_CLKREG(0x0C) -#define S3C_MPLL_CON		S3C_CLKREG(0x10) -#define S3C_EPLL_CON0		S3C_CLKREG(0x14) -#define S3C_EPLL_CON1		S3C_CLKREG(0x18) -#define S3C_CLK_SRC		S3C_CLKREG(0x1C) -#define S3C_CLK_DIV0		S3C_CLKREG(0x20) -#define S3C_CLK_DIV1		S3C_CLKREG(0x24) -#define S3C_CLK_DIV2		S3C_CLKREG(0x28) -#define S3C_CLK_OUT		S3C_CLKREG(0x2C) -#define S3C_HCLK_GATE		S3C_CLKREG(0x30)  #define S3C_PCLK_GATE		S3C_CLKREG(0x34) -#define S3C_SCLK_GATE		S3C_CLKREG(0x38) -#define S3C_MEM0_GATE		S3C_CLKREG(0x3C)  #define S3C6410_CLK_SRC2	S3C_CLKREG(0x10C)  #define S3C_MEM_SYS_CFG		S3C_CLKREG(0x120) -/* CLKDIV0 */ -#define S3C6400_CLKDIV0_PCLK_MASK	(0xf << 12) -#define S3C6400_CLKDIV0_PCLK_SHIFT	(12) -#define S3C6400_CLKDIV0_HCLK2_MASK	(0x7 << 9) -#define S3C6400_CLKDIV0_HCLK2_SHIFT	(9) -#define S3C6400_CLKDIV0_HCLK_MASK	(0x1 << 8) -#define S3C6400_CLKDIV0_HCLK_SHIFT	(8) -#define S3C6400_CLKDIV0_MPLL_MASK	(0x1 << 4) -#define S3C6400_CLKDIV0_MPLL_SHIFT	(4) - -#define S3C6400_CLKDIV0_ARM_MASK	(0x7 << 0) -#define S3C6410_CLKDIV0_ARM_MASK	(0xf << 0) -#define S3C6400_CLKDIV0_ARM_SHIFT	(0) - -/* HCLK GATE Registers */ -#define S3C_CLKCON_HCLK_3DSE	(1<<31) -#define S3C_CLKCON_HCLK_UHOST	(1<<29) -#define S3C_CLKCON_HCLK_SECUR	(1<<28) -#define S3C_CLKCON_HCLK_SDMA1	(1<<27) -#define S3C_CLKCON_HCLK_SDMA0	(1<<26) -#define S3C_CLKCON_HCLK_IROM	(1<<25) -#define S3C_CLKCON_HCLK_DDR1	(1<<24) -#define S3C_CLKCON_HCLK_DDR0	(1<<23) -#define S3C_CLKCON_HCLK_MEM1	(1<<22) -#define S3C_CLKCON_HCLK_MEM0	(1<<21) -#define S3C_CLKCON_HCLK_USB	(1<<20) -#define S3C_CLKCON_HCLK_HSMMC2	(1<<19) -#define S3C_CLKCON_HCLK_HSMMC1	(1<<18) -#define S3C_CLKCON_HCLK_HSMMC0	(1<<17) -#define S3C_CLKCON_HCLK_MDP	(1<<16) -#define S3C_CLKCON_HCLK_DHOST	(1<<15) -#define S3C_CLKCON_HCLK_IHOST	(1<<14) -#define S3C_CLKCON_HCLK_DMA1	(1<<13) -#define S3C_CLKCON_HCLK_DMA0	(1<<12) -#define S3C_CLKCON_HCLK_JPEG	(1<<11) -#define S3C_CLKCON_HCLK_CAMIF	(1<<10) -#define S3C_CLKCON_HCLK_SCALER	(1<<9) -#define S3C_CLKCON_HCLK_2D	(1<<8) -#define S3C_CLKCON_HCLK_TV	(1<<7) -#define S3C_CLKCON_HCLK_POST0	(1<<5) -#define S3C_CLKCON_HCLK_ROT	(1<<4) -#define S3C_CLKCON_HCLK_LCD	(1<<3) -#define S3C_CLKCON_HCLK_TZIC	(1<<2) -#define S3C_CLKCON_HCLK_INTC	(1<<1) -#define S3C_CLKCON_HCLK_MFC	(1<<0) -  /* PCLK GATE Registers */ -#define S3C6410_CLKCON_PCLK_I2C1	(1<<27) -#define S3C6410_CLKCON_PCLK_IIS2	(1<<26) -#define S3C_CLKCON_PCLK_SKEY		(1<<24) -#define S3C_CLKCON_PCLK_CHIPID		(1<<23) -#define S3C_CLKCON_PCLK_SPI1		(1<<22) -#define S3C_CLKCON_PCLK_SPI0		(1<<21) -#define S3C_CLKCON_PCLK_HSIRX		(1<<20) -#define S3C_CLKCON_PCLK_HSITX		(1<<19) -#define S3C_CLKCON_PCLK_GPIO		(1<<18) -#define S3C_CLKCON_PCLK_IIC		(1<<17) -#define S3C_CLKCON_PCLK_IIS1		(1<<16) -#define S3C_CLKCON_PCLK_IIS0		(1<<15) -#define S3C_CLKCON_PCLK_AC97		(1<<14) -#define S3C_CLKCON_PCLK_TZPC		(1<<13) -#define S3C_CLKCON_PCLK_TSADC		(1<<12) -#define S3C_CLKCON_PCLK_KEYPAD		(1<<11) -#define S3C_CLKCON_PCLK_IRDA		(1<<10) -#define S3C_CLKCON_PCLK_PCM1		(1<<9) -#define S3C_CLKCON_PCLK_PCM0		(1<<8) -#define S3C_CLKCON_PCLK_PWM		(1<<7) -#define S3C_CLKCON_PCLK_RTC		(1<<6) -#define S3C_CLKCON_PCLK_WDT		(1<<5)  #define S3C_CLKCON_PCLK_UART3		(1<<4)  #define S3C_CLKCON_PCLK_UART2		(1<<3)  #define S3C_CLKCON_PCLK_UART1		(1<<2)  #define S3C_CLKCON_PCLK_UART0		(1<<1) -#define S3C_CLKCON_PCLK_MFC		(1<<0) - -/* SCLK GATE Registers */ -#define S3C_CLKCON_SCLK_UHOST		(1<<30) -#define S3C_CLKCON_SCLK_MMC2_48		(1<<29) -#define S3C_CLKCON_SCLK_MMC1_48		(1<<28) -#define S3C_CLKCON_SCLK_MMC0_48		(1<<27) -#define S3C_CLKCON_SCLK_MMC2		(1<<26) -#define S3C_CLKCON_SCLK_MMC1		(1<<25) -#define S3C_CLKCON_SCLK_MMC0		(1<<24) -#define S3C_CLKCON_SCLK_SPI1_48 	(1<<23) -#define S3C_CLKCON_SCLK_SPI0_48 	(1<<22) -#define S3C_CLKCON_SCLK_SPI1		(1<<21) -#define S3C_CLKCON_SCLK_SPI0		(1<<20) -#define S3C_CLKCON_SCLK_DAC27		(1<<19) -#define S3C_CLKCON_SCLK_TV27		(1<<18) -#define S3C_CLKCON_SCLK_SCALER27	(1<<17) -#define S3C_CLKCON_SCLK_SCALER		(1<<16) -#define S3C_CLKCON_SCLK_LCD27		(1<<15) -#define S3C_CLKCON_SCLK_LCD		(1<<14) -#define S3C6400_CLKCON_SCLK_POST1_27	(1<<13) -#define S3C6410_CLKCON_FIMC		(1<<13) -#define S3C_CLKCON_SCLK_POST0_27	(1<<12) -#define S3C6400_CLKCON_SCLK_POST1	(1<<11) -#define S3C6410_CLKCON_SCLK_AUDIO2	(1<<11) -#define S3C_CLKCON_SCLK_POST0		(1<<10) -#define S3C_CLKCON_SCLK_AUDIO1		(1<<9) -#define S3C_CLKCON_SCLK_AUDIO0		(1<<8) -#define S3C_CLKCON_SCLK_SECUR		(1<<7) -#define S3C_CLKCON_SCLK_IRDA		(1<<6) -#define S3C_CLKCON_SCLK_UART		(1<<5) -#define S3C_CLKCON_SCLK_ONENAND 	(1<<4) -#define S3C_CLKCON_SCLK_MFC		(1<<3) -#define S3C_CLKCON_SCLK_CAM		(1<<2) -#define S3C_CLKCON_SCLK_JPEG		(1<<1) - -/* CLKSRC */ - -#define S3C6400_CLKSRC_APLL_MOUT	(1 << 0) -#define S3C6400_CLKSRC_MPLL_MOUT	(1 << 1) -#define S3C6400_CLKSRC_EPLL_MOUT	(1 << 2) -#define S3C6400_CLKSRC_APLL_MOUT_SHIFT	(0) -#define S3C6400_CLKSRC_MPLL_MOUT_SHIFT	(1) -#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT	(2) -#define S3C6400_CLKSRC_MFC		(1 << 4)  /* MEM_SYS_CFG */  #define MEM_SYS_CFG_INDEP_CF		0x4000 diff --git a/arch/arm/mach-s3c64xx/include/mach/tick.h b/arch/arm/mach-s3c64xx/include/mach/tick.h deleted file mode 100644 index db9c1b1d56a..00000000000 --- a/arch/arm/mach-s3c64xx/include/mach/tick.h +++ /dev/null @@ -1,31 +0,0 @@ -/* linux/arch/arm/mach-s3c6400/include/mach/tick.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - *	http://armlinux.simtec.co.uk/ - *	Ben Dooks <ben@simtec.co.uk> - * - * S3C64XX - Timer tick support definitions - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_TICK_H -#define __ASM_ARCH_TICK_H __FILE__ - -#include <linux/irqchip/arm-vic.h> - -/* note, the timer interrutps turn up in 2 places, the vic and then - * the timer block. We take the VIC as the base at the moment. - */ -static inline u32 s3c24xx_ostimer_pending(void) -{ -	u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS); -	return pend & 1 << (IRQ_TIMER4_VIC - S3C64XX_IRQ_VIC0(0)); -} - -#define TICK_MAX	(0xffffffff) - -#endif /* __ASM_ARCH_6400_TICK_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/timex.h b/arch/arm/mach-s3c64xx/include/mach/timex.h deleted file mode 100644 index fb2e8cd4082..00000000000 --- a/arch/arm/mach-s3c64xx/include/mach/timex.h +++ /dev/null @@ -1,24 +0,0 @@ -/* arch/arm/mach-s3c64xx/include/mach/timex.h - * - * Copyright (c) 2003-2005 Simtec Electronics - *	Ben Dooks <ben@simtec.co.uk> - * - * S3C6400 - time parameters - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_TIMEX_H -#define __ASM_ARCH_TIMEX_H - -/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it - * a variable is useless. It seems as long as we make our timers an - * exact multiple of HZ, any value that makes a 1->1 correspondence - * for the time conversion functions to/from jiffies is acceptable. -*/ - -#define CLOCK_TICK_RATE 12000000 - -#endif /* __ASM_ARCH_TIMEX_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/uncompress.h b/arch/arm/mach-s3c64xx/include/mach/uncompress.h deleted file mode 100644 index 1c956738b42..00000000000 --- a/arch/arm/mach-s3c64xx/include/mach/uncompress.h +++ /dev/null @@ -1,31 +0,0 @@ -/* arch/arm/mach-s3c6400/include/mach/uncompress.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - *	http://armlinux.simtec.co.uk/ - *	Ben Dooks <ben@simtec.co.uk> - * - * S3C6400 - uncompress code - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_UNCOMPRESS_H -#define __ASM_ARCH_UNCOMPRESS_H - -#include <mach/map.h> -#include <plat/uncompress.h> - -static void arch_detect_cpu(void) -{ -	/* we do not need to do any cpu detection here at the moment. */ -	fifo_mask = S3C2440_UFSTAT_TXMASK; -	fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT; - -	uart_base = (volatile u8 *)S3C_PA_UART + -		(S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT); -} - -#endif /* __ASM_ARCH_UNCOMPRESS_H */ diff --git a/arch/arm/mach-s3c64xx/irq-pm.c b/arch/arm/mach-s3c64xx/irq-pm.c index c3da1b68d03..ae4ea7601f6 100644 --- a/arch/arm/mach-s3c64xx/irq-pm.c +++ b/arch/arm/mach-s3c64xx/irq-pm.c @@ -12,16 +12,21 @@   * published by the Free Software Foundation.   */ +/* + * NOTE: Code in this file is not used when booting with Device Tree support. + */ +  #include <linux/kernel.h>  #include <linux/syscore_ops.h>  #include <linux/interrupt.h>  #include <linux/serial_core.h> +#include <linux/serial_s3c.h>  #include <linux/irq.h>  #include <linux/io.h> +#include <linux/of.h>  #include <mach/map.h> -#include <plat/regs-serial.h>  #include <mach/regs-gpio.h>  #include <plat/cpu.h>  #include <plat/pm.h> @@ -50,7 +55,13 @@ static struct irq_grp_save {  	u32	mask;  } eint_grp_save[5]; -static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS]; +#ifndef CONFIG_SERIAL_SAMSUNG_UARTS +#define SERIAL_SAMSUNG_UARTS 0 +#else +#define	SERIAL_SAMSUNG_UARTS CONFIG_SERIAL_SAMSUNG_UARTS +#endif + +static u32 irq_uart_mask[SERIAL_SAMSUNG_UARTS];  static int s3c64xx_irq_pm_suspend(void)  { @@ -61,7 +72,7 @@ static int s3c64xx_irq_pm_suspend(void)  	s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); -	for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++) +	for (i = 0; i < SERIAL_SAMSUNG_UARTS; i++)  		irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM);  	for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) { @@ -82,7 +93,7 @@ static void s3c64xx_irq_pm_resume(void)  	s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); -	for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++) +	for (i = 0; i < SERIAL_SAMSUNG_UARTS; i++)  		__raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM);  	for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) { @@ -101,6 +112,10 @@ static struct syscore_ops s3c64xx_irq_syscore_ops = {  static __init int s3c64xx_syscore_init(void)  { +	/* Appropriate drivers (pinctrl, uart) handle this when using DT. */ +	if (of_have_populated_dt()) +		return 0; +  	register_syscore_ops(&s3c64xx_irq_syscore_ops);  	return 0; diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c index 35e3f54574e..55eb6a69655 100644 --- a/arch/arm/mach-s3c64xx/mach-anw6410.c +++ b/arch/arm/mach-s3c64xx/mach-anw6410.c @@ -20,6 +20,7 @@  #include <linux/timer.h>  #include <linux/init.h>  #include <linux/serial_core.h> +#include <linux/serial_s3c.h>  #include <linux/platform_device.h>  #include <linux/io.h>  #include <linux/i2c.h> @@ -41,7 +42,6 @@  #include <asm/irq.h>  #include <asm/mach-types.h> -#include <plat/regs-serial.h>  #include <linux/platform_data/i2c-s3c2410.h>  #include <plat/fb.h> @@ -49,6 +49,7 @@  #include <plat/devs.h>  #include <plat/cpu.h>  #include <mach/regs-gpio.h> +#include <mach/gpio-samsung.h>  #include <plat/samsung-time.h>  #include "common.h" @@ -207,7 +208,7 @@ static struct platform_device *anw6410_devices[] __initdata = {  static void __init anw6410_map_io(void)  {  	s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc)); -	s3c24xx_init_clocks(12000000); +	s3c64xx_set_xtal_freq(12000000);  	s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs));  	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index 7ccfef227c7..9c00d83f715 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -401,4 +401,4 @@ static int __init wlf_gf_module_register(void)  {  	return i2c_add_driver(&wlf_gf_module_driver);  } -module_init(wlf_gf_module_register); +device_initcall(wlf_gf_module_register); diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index eb8e5a1aca4..4b0199fff9f 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -14,6 +14,7 @@  #include <linux/kernel.h>  #include <linux/list.h>  #include <linux/serial_core.h> +#include <linux/serial_s3c.h>  #include <linux/platform_device.h>  #include <linux/fb.h>  #include <linux/io.h> @@ -48,10 +49,9 @@  #include <video/samsung_fimd.h>  #include <mach/hardware.h>  #include <mach/map.h> -  #include <mach/regs-gpio.h> +#include <mach/gpio-samsung.h> -#include <plat/regs-serial.h>  #include <plat/fb.h>  #include <plat/sdhci.h>  #include <plat/gpio-cfg.h> @@ -114,6 +114,7 @@ static struct platform_pwm_backlight_data crag6410_backlight_data = {  	.max_brightness	= 1000,  	.dft_brightness	= 600,  	.pwm_period_ns	= 100000,	/* about 1kHz */ +	.enable_gpio	= -1,  };  static struct platform_device crag6410_backlight_device = { @@ -310,10 +311,6 @@ static struct regulator_consumer_supply wallvdd_consumers[] = {  	REGULATOR_SUPPLY("SPKVDDL", "spi0.1"),  	REGULATOR_SUPPLY("SPKVDDR", "spi0.1"), -	REGULATOR_SUPPLY("SPKVDDL", "wm5102-codec"), -	REGULATOR_SUPPLY("SPKVDDR", "wm5102-codec"), -	REGULATOR_SUPPLY("SPKVDDL", "wm5110-codec"), -	REGULATOR_SUPPLY("SPKVDDR", "wm5110-codec"),  	REGULATOR_SUPPLY("DC1VDD", "0-0034"),  	REGULATOR_SUPPLY("DC2VDD", "0-0034"), @@ -653,14 +650,6 @@ static struct regulator_consumer_supply pvdd_1v8_consumers[] = {  	REGULATOR_SUPPLY("DBVDD3", "spi0.1"),  	REGULATOR_SUPPLY("LDOVDD", "spi0.1"),  	REGULATOR_SUPPLY("CPVDD", "spi0.1"), - -	REGULATOR_SUPPLY("DBVDD2", "wm5102-codec"), -	REGULATOR_SUPPLY("DBVDD3", "wm5102-codec"), -	REGULATOR_SUPPLY("CPVDD", "wm5102-codec"), - -	REGULATOR_SUPPLY("DBVDD2", "wm5110-codec"), -	REGULATOR_SUPPLY("DBVDD3", "wm5110-codec"), -	REGULATOR_SUPPLY("CPVDD", "wm5110-codec"),  };  static struct regulator_init_data pvdd_1v8 = { @@ -743,7 +732,7 @@ static struct s3c2410_platform_i2c i2c1_pdata = {  static void __init crag6410_map_io(void)  {  	s3c64xx_init_io(NULL, 0); -	s3c24xx_init_clocks(12000000); +	s3c64xx_set_xtal_freq(12000000);  	s3c24xx_init_uarts(crag6410_uartcfgs, ARRAY_SIZE(crag6410_uartcfgs));  	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c index f39569e0f2e..72cee08c8bf 100644 --- a/arch/arm/mach-s3c64xx/mach-hmt.c +++ b/arch/arm/mach-s3c64xx/mach-hmt.c @@ -11,6 +11,7 @@  #include <linux/kernel.h>  #include <linux/init.h>  #include <linux/serial_core.h> +#include <linux/serial_s3c.h>  #include <linux/platform_device.h>  #include <linux/io.h>  #include <linux/i2c.h> @@ -33,8 +34,8 @@  #include <asm/irq.h>  #include <asm/mach-types.h> -#include <plat/regs-serial.h>  #include <linux/platform_data/i2c-s3c2410.h> +#include <mach/gpio-samsung.h>  #include <plat/fb.h>  #include <linux/platform_data/mtd-nand-s3c2410.h> @@ -114,6 +115,7 @@ static struct platform_pwm_backlight_data hmt_backlight_data = {  	.max_brightness	= 100 * 256,  	.dft_brightness	= 40 * 256,  	.pwm_period_ns	= 1000000000 / (100 * 256 * 20), +	.enable_gpio	= -1,  	.init		= hmt_bl_init,  	.notify		= hmt_bl_notify,  	.exit		= hmt_bl_exit, @@ -247,7 +249,7 @@ static struct platform_device *hmt_devices[] __initdata = {  static void __init hmt_map_io(void)  {  	s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc)); -	s3c24xx_init_clocks(12000000); +	s3c64xx_set_xtal_freq(12000000);  	s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs));  	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);  } diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c index fc043e3ecdf..9cbc07602ef 100644 --- a/arch/arm/mach-s3c64xx/mach-mini6410.c +++ b/arch/arm/mach-s3c64xx/mach-mini6410.c @@ -22,6 +22,7 @@  #include <linux/mtd/mtd.h>  #include <linux/mtd/partitions.h>  #include <linux/serial_core.h> +#include <linux/serial_s3c.h>  #include <linux/types.h>  #include <asm/mach-types.h> @@ -30,13 +31,15 @@  #include <mach/map.h>  #include <mach/regs-gpio.h> +#include <mach/gpio-samsung.h>  #include <plat/adc.h>  #include <plat/cpu.h>  #include <plat/devs.h>  #include <plat/fb.h>  #include <linux/platform_data/mtd-nand-s3c2410.h> -#include <plat/regs-serial.h> +#include <linux/platform_data/mmc-sdhci-s3c.h> +#include <plat/sdhci.h>  #include <linux/platform_data/touchscreen-s3c2410.h>  #include <video/platform_lcd.h> @@ -214,6 +217,13 @@ static struct platform_device mini6410_lcd_powerdev = {  	.dev.platform_data	= &mini6410_lcd_power_data,  }; +static struct s3c_sdhci_platdata mini6410_hsmmc1_pdata = { +	.max_width		= 4, +	.cd_type		= S3C_SDHCI_CD_GPIO, +	.ext_cd_gpio		= S3C64XX_GPN(10), +	.ext_cd_gpio_invert	= true, +}; +  static struct platform_device *mini6410_devices[] __initdata = {  	&mini6410_device_eth,  	&s3c_device_hsmmc0, @@ -231,7 +241,7 @@ static void __init mini6410_map_io(void)  	u32 tmp;  	s3c64xx_init_io(NULL, 0); -	s3c24xx_init_clocks(12000000); +	s3c64xx_set_xtal_freq(12000000);  	s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs));  	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); @@ -321,6 +331,7 @@ static void __init mini6410_machine_init(void)  	s3c_nand_set_platdata(&mini6410_nand_info);  	s3c_fb_set_platdata(&mini6410_lcd_pdata[features.lcd_index]); +	s3c_sdhci1_set_platdata(&mini6410_hsmmc1_pdata);  	s3c24xx_ts_set_platdata(NULL);  	/* configure nCS1 width to 16 bits */ diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c index 7e2c3908f1f..67f06a9ae65 100644 --- a/arch/arm/mach-s3c64xx/mach-ncp.c +++ b/arch/arm/mach-s3c64xx/mach-ncp.c @@ -16,6 +16,7 @@  #include <linux/timer.h>  #include <linux/init.h>  #include <linux/serial_core.h> +#include <linux/serial_s3c.h>  #include <linux/platform_device.h>  #include <linux/io.h>  #include <linux/i2c.h> @@ -36,7 +37,6 @@  #include <asm/irq.h>  #include <asm/mach-types.h> -#include <plat/regs-serial.h>  #include <linux/platform_data/i2c-s3c2410.h>  #include <plat/fb.h> @@ -86,7 +86,7 @@ static struct map_desc ncp_iodesc[] __initdata = {};  static void __init ncp_map_io(void)  {  	s3c64xx_init_io(ncp_iodesc, ARRAY_SIZE(ncp_iodesc)); -	s3c24xx_init_clocks(12000000); +	s3c64xx_set_xtal_freq(12000000);  	s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs));  	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);  } diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c index 8bed37b3d5a..fbad2af1ef1 100644 --- a/arch/arm/mach-s3c64xx/mach-real6410.c +++ b/arch/arm/mach-s3c64xx/mach-real6410.c @@ -23,6 +23,7 @@  #include <linux/mtd/partitions.h>  #include <linux/platform_device.h>  #include <linux/serial_core.h> +#include <linux/serial_s3c.h>  #include <linux/types.h>  #include <asm/mach-types.h> @@ -31,13 +32,13 @@  #include <mach/map.h>  #include <mach/regs-gpio.h> +#include <mach/gpio-samsung.h>  #include <plat/adc.h>  #include <plat/cpu.h>  #include <plat/devs.h>  #include <plat/fb.h>  #include <linux/platform_data/mtd-nand-s3c2410.h> -#include <plat/regs-serial.h>  #include <linux/platform_data/touchscreen-s3c2410.h>  #include <video/platform_lcd.h> diff --git a/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c new file mode 100644 index 00000000000..2fddf38192d --- /dev/null +++ b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c @@ -0,0 +1,76 @@ +/* + * Samsung's S3C64XX flattened device tree enabled machine + * + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/of_platform.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/system_misc.h> + +#include <plat/cpu.h> +#include <plat/watchdog-reset.h> + +#include <mach/map.h> + +#include "common.h" + +/* + * IO mapping for shared system controller IP. + * + * FIXME: Make remaining drivers use dynamic mapping. + */ +static struct map_desc s3c64xx_dt_iodesc[] __initdata = { +	{ +		.virtual	= (unsigned long)S3C_VA_SYS, +		.pfn		= __phys_to_pfn(S3C64XX_PA_SYSCON), +		.length		= SZ_4K, +		.type		= MT_DEVICE, +	}, +}; + +static void __init s3c64xx_dt_map_io(void) +{ +	debug_ll_io_init(); +	iotable_init(s3c64xx_dt_iodesc, ARRAY_SIZE(s3c64xx_dt_iodesc)); + +	s3c64xx_init_cpu(); + +	if (!soc_is_s3c64xx()) +		panic("SoC is not S3C64xx!"); +} + +static void __init s3c64xx_dt_init_machine(void) +{ +	samsung_wdt_reset_of_init(); +	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static void s3c64xx_dt_restart(enum reboot_mode mode, const char *cmd) +{ +	if (mode != REBOOT_SOFT) +		samsung_wdt_reset(); + +	/* if all else fails, or mode was for soft, jump to 0 */ +	soft_restart(0); +} + +static char const *s3c64xx_dt_compat[] __initdata = { +	"samsung,s3c6400", +	"samsung,s3c6410", +	NULL +}; + +DT_MACHINE_START(S3C6400_DT, "Samsung S3C64xx (Flattened Device Tree)") +	/* Maintainer: Tomasz Figa <tomasz.figa@gmail.com> */ +	.dt_compat	= s3c64xx_dt_compat, +	.map_io		= s3c64xx_dt_map_io, +	.init_machine	= s3c64xx_dt_init_machine, +	.restart        = s3c64xx_dt_restart, +MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c index 86d980b448f..78dd6f73c07 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq.c +++ b/arch/arm/mach-s3c64xx/mach-smartq.c @@ -16,6 +16,7 @@  #include <linux/platform_device.h>  #include <linux/pwm_backlight.h>  #include <linux/serial_core.h> +#include <linux/serial_s3c.h>  #include <linux/spi/spi_gpio.h>  #include <linux/usb/gpio_vbus.h>  #include <linux/platform_data/s3c-hsotg.h> @@ -25,6 +26,7 @@  #include <mach/map.h>  #include <mach/regs-gpio.h> +#include <mach/gpio-samsung.h>  #include <plat/clock.h>  #include <plat/cpu.h> @@ -32,7 +34,6 @@  #include <linux/platform_data/i2c-s3c2410.h>  #include <plat/gpio-cfg.h>  #include <linux/platform_data/hwmon-s3c.h> -#include <plat/regs-serial.h>  #include <linux/platform_data/usb-ohci-s3c2410.h>  #include <plat/sdhci.h>  #include <linux/platform_data/touchscreen-s3c2410.h> @@ -106,7 +107,7 @@ static void smartq_usb_host_enableoc(struct s3c2410_hcd_info *info, int on)  	if (on) {  		ret = request_irq(gpio_to_irq(S3C64XX_GPL(10)), -				  smartq_usb_host_ocirq, IRQF_DISABLED | +				  smartq_usb_host_ocirq,  				  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,  				  "USB host overcurrent", info);  		if (ret != 0) @@ -151,6 +152,7 @@ static struct platform_pwm_backlight_data smartq_backlight_data = {  	.max_brightness	= 1000,  	.dft_brightness	= 600,  	.pwm_period_ns	= 1000000000 / (1000 * 20), +	.enable_gpio	= -1,  	.init		= smartq_bl_init,  }; @@ -337,13 +339,6 @@ err:  	return ret;  } -static int __init smartq_usb_otg_init(void) -{ -	clk_xusbxti.rate = 12000000; - -	return 0; -} -  static int __init smartq_wifi_init(void)  {  	int ret; @@ -377,7 +372,8 @@ static struct map_desc smartq_iodesc[] __initdata = {};  void __init smartq_map_io(void)  {  	s3c64xx_init_io(smartq_iodesc, ARRAY_SIZE(smartq_iodesc)); -	s3c24xx_init_clocks(12000000); +	s3c64xx_set_xtal_freq(12000000); +	s3c64xx_set_xusbxti_freq(12000000);  	s3c24xx_init_uarts(smartq_uartcfgs, ARRAY_SIZE(smartq_uartcfgs));  	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); @@ -399,7 +395,6 @@ void __init smartq_machine_init(void)  	WARN_ON(smartq_lcd_setup_gpio());  	WARN_ON(smartq_power_off_init());  	WARN_ON(smartq_usb_host_init()); -	WARN_ON(smartq_usb_otg_init());  	WARN_ON(smartq_wifi_init());  	platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices)); diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c64xx/mach-smartq5.c index 8aca5daf3d0..dec4c08e834 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq5.c +++ b/arch/arm/mach-s3c64xx/mach-smartq5.c @@ -23,6 +23,7 @@  #include <video/samsung_fimd.h>  #include <mach/map.h>  #include <mach/regs-gpio.h> +#include <mach/gpio-samsung.h>  #include <plat/cpu.h>  #include <plat/devs.h> diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c64xx/mach-smartq7.c index a052e107c0b..27b322069c7 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq7.c +++ b/arch/arm/mach-s3c64xx/mach-smartq7.c @@ -23,6 +23,7 @@  #include <video/samsung_fimd.h>  #include <mach/map.h>  #include <mach/regs-gpio.h> +#include <mach/gpio-samsung.h>  #include <plat/cpu.h>  #include <plat/devs.h> diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c index d70c0843aea..c85d1cbe769 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6400.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c @@ -16,6 +16,7 @@  #include <linux/timer.h>  #include <linux/init.h>  #include <linux/serial_core.h> +#include <linux/serial_s3c.h>  #include <linux/platform_device.h>  #include <linux/i2c.h>  #include <linux/io.h> @@ -29,12 +30,11 @@  #include <mach/hardware.h>  #include <mach/map.h> -#include <plat/regs-serial.h> -  #include <plat/clock.h>  #include <plat/devs.h>  #include <plat/cpu.h>  #include <linux/platform_data/i2c-s3c2410.h> +#include <mach/gpio-samsung.h>  #include <plat/samsung-time.h>  #include "common.h" @@ -65,7 +65,7 @@ static struct map_desc smdk6400_iodesc[] = {};  static void __init smdk6400_map_io(void)  {  	s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc)); -	s3c24xx_init_clocks(12000000); +	s3c64xx_set_xtal_freq(12000000);  	s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs));  	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);  } diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index d90b450c564..c6a8b2ab024 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -19,6 +19,7 @@  #include <linux/init.h>  #include <linux/input.h>  #include <linux/serial_core.h> +#include <linux/serial_s3c.h>  #include <linux/platform_device.h>  #include <linux/io.h>  #include <linux/i2c.h> @@ -55,8 +56,8 @@  #include <asm/irq.h>  #include <asm/mach-types.h> -#include <plat/regs-serial.h>  #include <mach/regs-gpio.h> +#include <mach/gpio-samsung.h>  #include <linux/platform_data/ata-samsung_cf.h>  #include <linux/platform_data/i2c-s3c2410.h>  #include <plat/fb.h> @@ -625,6 +626,7 @@ static struct samsung_bl_gpio_info smdk6410_bl_gpio_info = {  static struct platform_pwm_backlight_data smdk6410_bl_data = {  	.pwm_id = 1, +	.enable_gpio = -1,  };  static struct s3c_hsotg_plat smdk6410_hsotg_pdata; @@ -634,7 +636,7 @@ static void __init smdk6410_map_io(void)  	u32 tmp;  	s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc)); -	s3c24xx_init_clocks(12000000); +	s3c64xx_set_xtal_freq(12000000);  	s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs));  	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); diff --git a/arch/arm/mach-s3c64xx/pl080.c b/arch/arm/mach-s3c64xx/pl080.c new file mode 100644 index 00000000000..901a984bddc --- /dev/null +++ b/arch/arm/mach-s3c64xx/pl080.c @@ -0,0 +1,244 @@ +/* + * Samsung's S3C64XX generic DMA support using amba-pl08x driver. + * + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/amba/bus.h> +#include <linux/amba/pl080.h> +#include <linux/amba/pl08x.h> +#include <linux/of.h> + +#include <mach/irqs.h> +#include <mach/map.h> + +#include "regs-sys.h" + +static int pl08x_get_xfer_signal(const struct pl08x_channel_data *cd) +{ +	return cd->min_signal; +} + +static void pl08x_put_xfer_signal(const struct pl08x_channel_data *cd, int ch) +{ +} + +/* + * DMA0 + */ + +static struct pl08x_channel_data s3c64xx_dma0_info[] = { +	{ +		.bus_id = "uart0_tx", +		.min_signal = 0, +		.max_signal = 0, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "uart0_rx", +		.min_signal = 1, +		.max_signal = 1, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "uart1_tx", +		.min_signal = 2, +		.max_signal = 2, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "uart1_rx", +		.min_signal = 3, +		.max_signal = 3, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "uart2_tx", +		.min_signal = 4, +		.max_signal = 4, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "uart2_rx", +		.min_signal = 5, +		.max_signal = 5, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "uart3_tx", +		.min_signal = 6, +		.max_signal = 6, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "uart3_rx", +		.min_signal = 7, +		.max_signal = 7, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "pcm0_tx", +		.min_signal = 8, +		.max_signal = 8, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "pcm0_rx", +		.min_signal = 9, +		.max_signal = 9, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "i2s0_tx", +		.min_signal = 10, +		.max_signal = 10, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "i2s0_rx", +		.min_signal = 11, +		.max_signal = 11, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "spi0_tx", +		.min_signal = 12, +		.max_signal = 12, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "spi0_rx", +		.min_signal = 13, +		.max_signal = 13, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "i2s2_tx", +		.min_signal = 14, +		.max_signal = 14, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "i2s2_rx", +		.min_signal = 15, +		.max_signal = 15, +		.periph_buses = PL08X_AHB2, +	} +}; + +struct pl08x_platform_data s3c64xx_dma0_plat_data = { +	.memcpy_channel = { +		.bus_id = "memcpy", +		.cctl_memcpy = +			(PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT | +			PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT | +			PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | +			PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | +			PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | +			PL080_CONTROL_PROT_SYS), +	}, +	.lli_buses = PL08X_AHB1, +	.mem_buses = PL08X_AHB1, +	.get_xfer_signal = pl08x_get_xfer_signal, +	.put_xfer_signal = pl08x_put_xfer_signal, +	.slave_channels = s3c64xx_dma0_info, +	.num_slave_channels = ARRAY_SIZE(s3c64xx_dma0_info), +}; + +static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0, +			0x75000000, {IRQ_DMA0}, &s3c64xx_dma0_plat_data); + +/* + * DMA1 + */ + +static struct pl08x_channel_data s3c64xx_dma1_info[] = { +	{ +		.bus_id = "pcm1_tx", +		.min_signal = 0, +		.max_signal = 0, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "pcm1_rx", +		.min_signal = 1, +		.max_signal = 1, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "i2s1_tx", +		.min_signal = 2, +		.max_signal = 2, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "i2s1_rx", +		.min_signal = 3, +		.max_signal = 3, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "spi1_tx", +		.min_signal = 4, +		.max_signal = 4, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "spi1_rx", +		.min_signal = 5, +		.max_signal = 5, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "ac97_out", +		.min_signal = 6, +		.max_signal = 6, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "ac97_in", +		.min_signal = 7, +		.max_signal = 7, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "ac97_mic", +		.min_signal = 8, +		.max_signal = 8, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "pwm", +		.min_signal = 9, +		.max_signal = 9, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "irda", +		.min_signal = 10, +		.max_signal = 10, +		.periph_buses = PL08X_AHB2, +	}, { +		.bus_id = "external", +		.min_signal = 11, +		.max_signal = 11, +		.periph_buses = PL08X_AHB2, +	}, +}; + +struct pl08x_platform_data s3c64xx_dma1_plat_data = { +	.memcpy_channel = { +		.bus_id = "memcpy", +		.cctl_memcpy = +			(PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT | +			PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT | +			PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | +			PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | +			PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | +			PL080_CONTROL_PROT_SYS), +	}, +	.lli_buses = PL08X_AHB1, +	.mem_buses = PL08X_AHB1, +	.get_xfer_signal = pl08x_get_xfer_signal, +	.put_xfer_signal = pl08x_put_xfer_signal, +	.slave_channels = s3c64xx_dma1_info, +	.num_slave_channels = ARRAY_SIZE(s3c64xx_dma1_info), +}; + +static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0, +			0x75100000, {IRQ_DMA1}, &s3c64xx_dma1_plat_data); + +static int __init s3c64xx_pl080_init(void) +{ +	/* Set all DMA configuration to be DMA, not SDMA */ +	writel(0xffffff, S3C64XX_SDMA_SEL); + +	if (of_have_populated_dt()) +		return 0; + +	amba_device_register(&s3c64xx_dma0_device, &iomem_resource); +	amba_device_register(&s3c64xx_dma1_device, &iomem_resource); + +	return 0; +} +arch_initcall(s3c64xx_pl080_init); diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c index 6a1f91fea67..6b37694fa33 100644 --- a/arch/arm/mach-s3c64xx/pm.c +++ b/arch/arm/mach-s3c64xx/pm.c @@ -28,6 +28,7 @@  #include <mach/regs-gpio.h>  #include <mach/regs-clock.h> +#include <mach/gpio-samsung.h>  #include "regs-gpio-memport.h"  #include "regs-modem.h" @@ -194,29 +195,8 @@ void s3c_pm_debug_smdkled(u32 set, u32 clear)  #endif  static struct sleep_save core_save[] = { -	SAVE_ITEM(S3C_APLL_LOCK), -	SAVE_ITEM(S3C_MPLL_LOCK), -	SAVE_ITEM(S3C_EPLL_LOCK), -	SAVE_ITEM(S3C_CLK_SRC), -	SAVE_ITEM(S3C_CLK_DIV0), -	SAVE_ITEM(S3C_CLK_DIV1), -	SAVE_ITEM(S3C_CLK_DIV2), -	SAVE_ITEM(S3C_CLK_OUT), -	SAVE_ITEM(S3C_HCLK_GATE), -	SAVE_ITEM(S3C_PCLK_GATE), -	SAVE_ITEM(S3C_SCLK_GATE), -	SAVE_ITEM(S3C_MEM0_GATE), - -	SAVE_ITEM(S3C_EPLL_CON1), -	SAVE_ITEM(S3C_EPLL_CON0), -  	SAVE_ITEM(S3C64XX_MEM0DRVCON),  	SAVE_ITEM(S3C64XX_MEM1DRVCON), - -#ifndef CONFIG_CPU_FREQ -	SAVE_ITEM(S3C_APLL_CON), -	SAVE_ITEM(S3C_MPLL_CON), -#endif  };  static struct sleep_save misc_save[] = { @@ -352,7 +332,6 @@ static __init int s3c64xx_pm_initcall(void)  {  	pm_cpu_prep = s3c64xx_pm_prepare;  	pm_cpu_sleep = s3c64xx_cpu_suspend; -	pm_uart_udivslot = 1;  #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK  	gpio_request(S3C64XX_GPN(12), "DEBUG_LED0"); diff --git a/arch/arm/mach-s3c64xx/s3c6400.c b/arch/arm/mach-s3c64xx/s3c6400.c index 4869714c6f1..8c42807bf57 100644 --- a/arch/arm/mach-s3c64xx/s3c6400.c +++ b/arch/arm/mach-s3c64xx/s3c6400.c @@ -9,6 +9,10 @@   * published by the Free Software Foundation.  */ +/* + * NOTE: Code in this file is not used when booting with Device Tree support. + */ +  #include <linux/kernel.h>  #include <linux/types.h>  #include <linux/interrupt.h> @@ -19,7 +23,9 @@  #include <linux/io.h>  #include <linux/device.h>  #include <linux/serial_core.h> +#include <linux/serial_s3c.h>  #include <linux/platform_device.h> +#include <linux/of.h>  #include <asm/mach/arch.h>  #include <asm/mach/map.h> @@ -29,7 +35,6 @@  #include <asm/irq.h>  #include <plat/cpu-freq.h> -#include <plat/regs-serial.h>  #include <mach/regs-clock.h>  #include <plat/cpu.h> @@ -58,12 +63,6 @@ void __init s3c6400_map_io(void)  	s3c64xx_onenand1_setname("s3c6400-onenand");  } -void __init s3c6400_init_clocks(int xtal) -{ -	s3c64xx_register_clocks(xtal, S3C6400_CLKDIV0_ARM_MASK); -	s3c64xx_setup_clocks(); -} -  void __init s3c6400_init_irq(void)  {  	/* VIC0 does not have IRQS 5..7, @@ -82,6 +81,10 @@ static struct device s3c6400_dev = {  static int __init s3c6400_core_init(void)  { +	/* Not applicable when using DT. */ +	if (of_have_populated_dt()) +		return 0; +  	return subsys_system_register(&s3c6400_subsys, NULL);  } diff --git a/arch/arm/mach-s3c64xx/s3c6410.c b/arch/arm/mach-s3c64xx/s3c6410.c index 31c29fdf180..5be3f09bac9 100644 --- a/arch/arm/mach-s3c64xx/s3c6410.c +++ b/arch/arm/mach-s3c64xx/s3c6410.c @@ -10,6 +10,10 @@   * published by the Free Software Foundation.  */ +/* + * NOTE: Code in this file is not used when booting with Device Tree support. + */ +  #include <linux/kernel.h>  #include <linux/types.h>  #include <linux/interrupt.h> @@ -20,7 +24,9 @@  #include <linux/io.h>  #include <linux/device.h>  #include <linux/serial_core.h> +#include <linux/serial_s3c.h>  #include <linux/platform_device.h> +#include <linux/of.h>  #include <asm/mach/arch.h>  #include <asm/mach/map.h> @@ -30,7 +36,6 @@  #include <asm/irq.h>  #include <plat/cpu-freq.h> -#include <plat/regs-serial.h>  #include <mach/regs-clock.h>  #include <plat/cpu.h> @@ -62,13 +67,6 @@ void __init s3c6410_map_io(void)  	s3c_cfcon_setname("s3c64xx-pata");  } -void __init s3c6410_init_clocks(int xtal) -{ -	printk(KERN_DEBUG "%s: initialising clocks\n", __func__); -	s3c64xx_register_clocks(xtal, S3C6410_CLKDIV0_ARM_MASK); -	s3c64xx_setup_clocks(); -} -  void __init s3c6410_init_irq(void)  {  	/* VIC0 is missing IRQ7, VIC1 is fully populated. */ @@ -86,6 +84,10 @@ static struct device s3c6410_dev = {  static int __init s3c6410_core_init(void)  { +	/* Not applicable when using DT. */ +	if (of_have_populated_dt()) +		return 0; +  	return subsys_system_register(&s3c6410_subsys, NULL);  } diff --git a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c index 2cf80026c58..9d17bff12d4 100644 --- a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c +++ b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c @@ -19,6 +19,7 @@  #include <plat/fb.h>  #include <plat/gpio-cfg.h> +#include <mach/gpio-samsung.h>  void s3c64xx_fb_gpio_setup_24bpp(void)  { diff --git a/arch/arm/mach-s3c64xx/setup-i2c0.c b/arch/arm/mach-s3c64xx/setup-i2c0.c index 40666ba8d60..4b8c1cfdd1f 100644 --- a/arch/arm/mach-s3c64xx/setup-i2c0.c +++ b/arch/arm/mach-s3c64xx/setup-i2c0.c @@ -20,6 +20,7 @@ struct platform_device; /* don't need the contents */  #include <linux/platform_data/i2c-s3c2410.h>  #include <plat/gpio-cfg.h> +#include <mach/gpio-samsung.h>  void s3c_i2c0_cfg_gpio(struct platform_device *dev)  { diff --git a/arch/arm/mach-s3c64xx/setup-i2c1.c b/arch/arm/mach-s3c64xx/setup-i2c1.c index 3fdb24c4e62..cd1df71ee13 100644 --- a/arch/arm/mach-s3c64xx/setup-i2c1.c +++ b/arch/arm/mach-s3c64xx/setup-i2c1.c @@ -20,6 +20,7 @@ struct platform_device; /* don't need the contents */  #include <linux/platform_data/i2c-s3c2410.h>  #include <plat/gpio-cfg.h> +#include <mach/gpio-samsung.h>  void s3c_i2c1_cfg_gpio(struct platform_device *dev)  { diff --git a/arch/arm/mach-s3c64xx/setup-ide.c b/arch/arm/mach-s3c64xx/setup-ide.c index 648d8b85bf6..689fb72e715 100644 --- a/arch/arm/mach-s3c64xx/setup-ide.c +++ b/arch/arm/mach-s3c64xx/setup-ide.c @@ -17,6 +17,7 @@  #include <mach/map.h>  #include <mach/regs-clock.h>  #include <plat/gpio-cfg.h> +#include <mach/gpio-samsung.h>  #include <linux/platform_data/ata-samsung_cf.h>  void s3c64xx_ide_setup_gpio(void) diff --git a/arch/arm/mach-s3c64xx/setup-keypad.c b/arch/arm/mach-s3c64xx/setup-keypad.c index 1d4d0ee9e87..6ad9a89dfdd 100644 --- a/arch/arm/mach-s3c64xx/setup-keypad.c +++ b/arch/arm/mach-s3c64xx/setup-keypad.c @@ -13,6 +13,7 @@  #include <linux/gpio.h>  #include <plat/gpio-cfg.h>  #include <plat/keypad.h> +#include <mach/gpio-samsung.h>  void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)  { diff --git a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c index 6eac071afae..f426b7a16c1 100644 --- a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c +++ b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c @@ -20,6 +20,7 @@  #include <plat/gpio-cfg.h>  #include <plat/sdhci.h> +#include <mach/gpio-samsung.h>  void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)  { diff --git a/arch/arm/mach-s3c64xx/setup-spi.c b/arch/arm/mach-s3c64xx/setup-spi.c index 4dc53450d71..5fd1a315c90 100644 --- a/arch/arm/mach-s3c64xx/setup-spi.c +++ b/arch/arm/mach-s3c64xx/setup-spi.c @@ -10,6 +10,7 @@  #include <linux/gpio.h>  #include <plat/gpio-cfg.h> +#include <mach/gpio-samsung.h>  #ifdef CONFIG_S3C64XX_DEV_SPI0  int s3c64xx_spi0_cfg_gpio(void)  | 
