提交 bbba7560 编写于 作者: R Russell King

Merge branch 'for-rmk' of...

Merge branch 'for-rmk' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into devel-stable
......@@ -766,6 +766,7 @@ config ARCH_S5PV310
select ARCH_SPARSEMEM_ENABLE
select GENERIC_GPIO
select HAVE_CLK
select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
select HAVE_S3C_RTC if RTC_CLASS
select HAVE_S3C2410_I2C if I2C
......
......@@ -75,38 +75,38 @@ static unsigned char bast_pc104_irqmasks[] = {
static unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 };
static void
bast_pc104_mask(unsigned int irqno)
bast_pc104_mask(struct irq_data *data)
{
unsigned long temp;
temp = __raw_readb(BAST_VA_PC104_IRQMASK);
temp &= ~bast_pc104_irqmasks[irqno];
temp &= ~bast_pc104_irqmasks[data->irq];
__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
}
static void
bast_pc104_maskack(unsigned int irqno)
bast_pc104_maskack(struct irq_data *data)
{
struct irq_desc *desc = irq_desc + IRQ_ISA;
bast_pc104_mask(irqno);
desc->chip->ack(IRQ_ISA);
bast_pc104_mask(data);
desc->irq_data.chip->irq_ack(&desc->irq_data);
}
static void
bast_pc104_unmask(unsigned int irqno)
bast_pc104_unmask(struct irq_data *data)
{
unsigned long temp;
temp = __raw_readb(BAST_VA_PC104_IRQMASK);
temp |= bast_pc104_irqmasks[irqno];
temp |= bast_pc104_irqmasks[data->irq];
__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
}
static struct irq_chip bast_pc104_chip = {
.mask = bast_pc104_mask,
.unmask = bast_pc104_unmask,
.ack = bast_pc104_maskack
.irq_mask = bast_pc104_mask,
.irq_unmask = bast_pc104_unmask,
.irq_ack = bast_pc104_maskack
};
static void
......@@ -123,7 +123,7 @@ bast_irq_pc104_demux(unsigned int irq,
/* ack if we get an irq with nothing (ie, startup) */
desc = irq_desc + IRQ_ISA;
desc->chip->ack(IRQ_ISA);
desc->irq_data.chip->irq_ack(&desc->irq_data);
} else {
/* handle the IRQ */
......
......@@ -152,8 +152,8 @@
#define IRQ_S3C2416_HSMMC0 S3C2410_IRQ(21) /* S3C2416/S3C2450 */
#define IRQ_HSMMC0 IRQ_S3C2443_HSMMC
#define IRQ_HSMMC1 IRQ_S3C2416_HSMMC0
#define IRQ_HSMMC0 IRQ_S3C2416_HSMMC0
#define IRQ_HSMMC1 IRQ_S3C2443_HSMMC
#define IRQ_S3C2443_LCD1 S3C2410_IRQSUB(14)
#define IRQ_S3C2443_LCD2 S3C2410_IRQSUB(15)
......
......@@ -112,8 +112,8 @@
#define S3C_PA_IIC S3C2410_PA_IIC
#define S3C_PA_UART S3C24XX_PA_UART
#define S3C_PA_USBHOST S3C2410_PA_USBHOST
#define S3C_PA_HSMMC0 S3C2443_PA_HSMMC
#define S3C_PA_HSMMC1 S3C2416_PA_HSMMC0
#define S3C_PA_HSMMC0 S3C2416_PA_HSMMC0
#define S3C_PA_HSMMC1 S3C2443_PA_HSMMC
#define S3C_PA_WDT S3C2410_PA_WATCHDOG
#define S3C_PA_NAND S3C24XX_PA_NAND
......
......@@ -86,6 +86,7 @@
#define S3C2443_HCLKCON_LCDC (1<<9)
#define S3C2443_HCLKCON_USBH (1<<11)
#define S3C2443_HCLKCON_USBD (1<<12)
#define S3C2416_HCLKCON_HSMMC0 (1<<15)
#define S3C2443_HCLKCON_HSMMC (1<<16)
#define S3C2443_HCLKCON_CFC (1<<17)
#define S3C2443_HCLKCON_SSMC (1<<18)
......
......@@ -49,9 +49,9 @@
*/
static void
s3c2412_irq_mask(unsigned int irqno)
s3c2412_irq_mask(struct irq_data *data)
{
unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
unsigned long mask;
mask = __raw_readl(S3C2410_INTMSK);
......@@ -62,9 +62,9 @@ s3c2412_irq_mask(unsigned int irqno)
}
static inline void
s3c2412_irq_ack(unsigned int irqno)
s3c2412_irq_ack(struct irq_data *data)
{
unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
__raw_writel(bitval, S3C2412_EINTPEND);
__raw_writel(bitval, S3C2410_SRCPND);
......@@ -72,9 +72,9 @@ s3c2412_irq_ack(unsigned int irqno)
}
static inline void
s3c2412_irq_maskack(unsigned int irqno)
s3c2412_irq_maskack(struct irq_data *data)
{
unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
unsigned long mask;
mask = __raw_readl(S3C2410_INTMSK);
......@@ -89,9 +89,9 @@ s3c2412_irq_maskack(unsigned int irqno)
}
static void
s3c2412_irq_unmask(unsigned int irqno)
s3c2412_irq_unmask(struct irq_data *data)
{
unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
unsigned long mask;
mask = __raw_readl(S3C2412_EINTMASK);
......@@ -102,11 +102,11 @@ s3c2412_irq_unmask(unsigned int irqno)
}
static struct irq_chip s3c2412_irq_eint0t4 = {
.ack = s3c2412_irq_ack,
.mask = s3c2412_irq_mask,
.unmask = s3c2412_irq_unmask,
.set_wake = s3c_irq_wake,
.set_type = s3c_irqext_type,
.irq_ack = s3c2412_irq_ack,
.irq_mask = s3c2412_irq_mask,
.irq_unmask = s3c2412_irq_unmask,
.irq_set_wake = s3c_irq_wake,
.irq_set_type = s3c_irqext_type,
};
#define INTBIT(x) (1 << ((x) - S3C2410_IRQSUB(0)))
......@@ -132,29 +132,29 @@ static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc)
#define INTMSK_CFSDI (1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0))
#define SUBMSK_CFSDI INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF)
static void s3c2412_irq_cfsdi_mask(unsigned int irqno)
static void s3c2412_irq_cfsdi_mask(struct irq_data *data)
{
s3c_irqsub_mask(irqno, INTMSK_CFSDI, SUBMSK_CFSDI);
s3c_irqsub_mask(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI);
}
static void s3c2412_irq_cfsdi_unmask(unsigned int irqno)
static void s3c2412_irq_cfsdi_unmask(struct irq_data *data)
{
s3c_irqsub_unmask(irqno, INTMSK_CFSDI);
s3c_irqsub_unmask(data->irq, INTMSK_CFSDI);
}
static void s3c2412_irq_cfsdi_ack(unsigned int irqno)
static void s3c2412_irq_cfsdi_ack(struct irq_data *data)
{
s3c_irqsub_maskack(irqno, INTMSK_CFSDI, SUBMSK_CFSDI);
s3c_irqsub_maskack(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI);
}
static struct irq_chip s3c2412_irq_cfsdi = {
.name = "s3c2412-cfsdi",
.ack = s3c2412_irq_cfsdi_ack,
.mask = s3c2412_irq_cfsdi_mask,
.unmask = s3c2412_irq_cfsdi_unmask,
.irq_ack = s3c2412_irq_cfsdi_ack,
.irq_mask = s3c2412_irq_cfsdi_mask,
.irq_unmask = s3c2412_irq_cfsdi_unmask,
};
static int s3c2412_irq_rtc_wake(unsigned int irqno, unsigned int state)
static int s3c2412_irq_rtc_wake(struct irq_data *data, unsigned int state)
{
unsigned long pwrcfg;
......@@ -165,7 +165,7 @@ static int s3c2412_irq_rtc_wake(unsigned int irqno, unsigned int state)
pwrcfg |= S3C2412_PWRCFG_RTC_MASKIRQ;
__raw_writel(pwrcfg, S3C2412_PWRCFG);
return s3c_irq_chip.set_wake(irqno, state);
return s3c_irq_chip.irq_set_wake(data, state);
}
static struct irq_chip s3c2412_irq_rtc_chip;
......@@ -193,7 +193,7 @@ static int s3c2412_irq_add(struct sys_device *sysdev)
/* change RTC IRQ's set wake method */
s3c2412_irq_rtc_chip = s3c_irq_chip;
s3c2412_irq_rtc_chip.set_wake = s3c2412_irq_rtc_wake;
s3c2412_irq_rtc_chip.irq_set_wake = s3c2412_irq_rtc_wake;
set_irq_chip(IRQ_RTC, &s3c2412_irq_rtc_chip);
......
......@@ -31,6 +31,17 @@ config S3C2416_PM
help
Internal config node to apply S3C2416 power management
config S3C2416_SETUP_SDHCI
bool
select S3C2416_SETUP_SDHCI_GPIO
help
Internal helper functions for S3C2416 based SDHCI systems
config S3C2416_SETUP_SDHCI_GPIO
bool
help
Common setup code for SDHCI gpio.
menu "S3C2416 Machines"
config MACH_SMDK2416
......@@ -42,6 +53,7 @@ config MACH_SMDK2416
select S3C_DEV_HSMMC1
select S3C_DEV_NAND
select S3C_DEV_USB_HOST
select S3C2416_SETUP_SDHCI
select S3C2416_PM if PM
help
Say Y here if you are using an SMDK2416
......
......@@ -14,6 +14,10 @@ obj-$(CONFIG_CPU_S3C2416) += irq.o
obj-$(CONFIG_S3C2416_PM) += pm.o
#obj-$(CONFIG_S3C2416_DMA) += dma.o
# Device setup
obj-$(CONFIG_S3C2416_SETUP_SDHCI) += setup-sdhci.o
obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
# Machine support
obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o
......@@ -38,12 +38,11 @@ static unsigned int armdiv[8] = {
[7] = 8,
};
/* ID to hardware numbering, 0 is HSMMC1, 1 is HSMMC0 */
static struct clksrc_clk hsmmc_div[] = {
[0] = {
.clk = {
.name = "hsmmc-div",
.id = 1,
.id = 0,
.parent = &clk_esysclk.clk,
},
.reg_div = { .reg = S3C2416_CLKDIV2, .size = 2, .shift = 6 },
......@@ -51,7 +50,7 @@ static struct clksrc_clk hsmmc_div[] = {
[1] = {
.clk = {
.name = "hsmmc-div",
.id = 0,
.id = 1,
.parent = &clk_esysclk.clk,
},
.reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
......@@ -61,7 +60,7 @@ static struct clksrc_clk hsmmc_div[] = {
static struct clksrc_clk hsmmc_mux[] = {
[0] = {
.clk = {
.id = 1,
.id = 0,
.name = "hsmmc-if",
.ctrlbit = (1 << 6),
.enable = s3c2443_clkcon_enable_s,
......@@ -77,7 +76,7 @@ static struct clksrc_clk hsmmc_mux[] = {
},
[1] = {
.clk = {
.id = 0,
.id = 1,
.name = "hsmmc-if",
.ctrlbit = (1 << 12),
.enable = s3c2443_clkcon_enable_s,
......@@ -93,6 +92,13 @@ static struct clksrc_clk hsmmc_mux[] = {
},
};
static struct clk hsmmc0_clk = {
.name = "hsmmc",
.id = 0,
.parent = &clk_h,
.enable = s3c2443_clkcon_enable_h,
.ctrlbit = S3C2416_HCLKCON_HSMMC0,
};
static inline unsigned int s3c2416_fclk_div(unsigned long clkcon0)
{
......@@ -130,6 +136,8 @@ void __init s3c2416_init_clocks(int xtal)
for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
s3c_register_clksrc(clksrcs[ptr], 1);
s3c24xx_register_clock(&hsmmc0_clk);
s3c_pwmclk_init();
}
......@@ -77,28 +77,27 @@ static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
static void s3c2416_irq_wdtac97_mask(unsigned int irqno)
static void s3c2416_irq_wdtac97_mask(struct irq_data *data)
{
s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
}
static void s3c2416_irq_wdtac97_unmask(unsigned int irqno)
static void s3c2416_irq_wdtac97_unmask(struct irq_data *data)
{
s3c_irqsub_unmask(irqno, INTMSK_WDTAC97);
s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
}
static void s3c2416_irq_wdtac97_ack(unsigned int irqno)
static void s3c2416_irq_wdtac97_ack(struct irq_data *data)
{
s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
}
static struct irq_chip s3c2416_irq_wdtac97 = {
.mask = s3c2416_irq_wdtac97_mask,
.unmask = s3c2416_irq_wdtac97_unmask,
.ack = s3c2416_irq_wdtac97_ack,
.irq_mask = s3c2416_irq_wdtac97_mask,
.irq_unmask = s3c2416_irq_wdtac97_unmask,
.irq_ack = s3c2416_irq_wdtac97_ack,
};
/* LCD sub interrupts */
static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
......@@ -109,28 +108,27 @@ static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
static void s3c2416_irq_lcd_mask(unsigned int irqno)
static void s3c2416_irq_lcd_mask(struct irq_data *data)
{
s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD);
s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
}
static void s3c2416_irq_lcd_unmask(unsigned int irqno)
static void s3c2416_irq_lcd_unmask(struct irq_data *data)
{
s3c_irqsub_unmask(irqno, INTMSK_LCD);
s3c_irqsub_unmask(data->irq, INTMSK_LCD);
}
static void s3c2416_irq_lcd_ack(unsigned int irqno)
static void s3c2416_irq_lcd_ack(struct irq_data *data)
{
s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD);
s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
}
static struct irq_chip s3c2416_irq_lcd = {
.mask = s3c2416_irq_lcd_mask,
.unmask = s3c2416_irq_lcd_unmask,
.ack = s3c2416_irq_lcd_ack,
.irq_mask = s3c2416_irq_lcd_mask,
.irq_unmask = s3c2416_irq_lcd_unmask,
.irq_ack = s3c2416_irq_lcd_ack,
};
/* DMA sub interrupts */
static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
......@@ -142,28 +140,27 @@ static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
static void s3c2416_irq_dma_mask(unsigned int irqno)
static void s3c2416_irq_dma_mask(struct irq_data *data)
{
s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA);
s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
}
static void s3c2416_irq_dma_unmask(unsigned int irqno)
static void s3c2416_irq_dma_unmask(struct irq_data *data)
{
s3c_irqsub_unmask(irqno, INTMSK_DMA);
s3c_irqsub_unmask(data->irq, INTMSK_DMA);
}
static void s3c2416_irq_dma_ack(unsigned int irqno)
static void s3c2416_irq_dma_ack(struct irq_data *data)
{
s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA);
s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
}
static struct irq_chip s3c2416_irq_dma = {
.mask = s3c2416_irq_dma_mask,
.unmask = s3c2416_irq_dma_unmask,
.ack = s3c2416_irq_dma_ack,
.irq_mask = s3c2416_irq_dma_mask,
.irq_unmask = s3c2416_irq_dma_unmask,
.irq_ack = s3c2416_irq_dma_ack,
};
/* UART3 sub interrupts */
static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
......@@ -174,28 +171,27 @@ static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
#define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
static void s3c2416_irq_uart3_mask(unsigned int irqno)
static void s3c2416_irq_uart3_mask(struct irq_data *data)
{
s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3);
s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
}
static void s3c2416_irq_uart3_unmask(unsigned int irqno)
static void s3c2416_irq_uart3_unmask(struct irq_data *data)
{
s3c_irqsub_unmask(irqno, INTMSK_UART3);
s3c_irqsub_unmask(data->irq, INTMSK_UART3);
}
static void s3c2416_irq_uart3_ack(unsigned int irqno)
static void s3c2416_irq_uart3_ack(struct irq_data *data)
{
s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3);
s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
}
static struct irq_chip s3c2416_irq_uart3 = {
.mask = s3c2416_irq_uart3_mask,
.unmask = s3c2416_irq_uart3_unmask,
.ack = s3c2416_irq_uart3_ack,
.irq_mask = s3c2416_irq_uart3_mask,
.irq_unmask = s3c2416_irq_uart3_unmask,
.irq_ack = s3c2416_irq_uart3_ack,
};
/* IRQ initialisation code */
static int __init s3c2416_add_sub(unsigned int base,
......
......@@ -46,6 +46,7 @@
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/nand.h>
#include <plat/sdhci.h>
#include <plat/regs-fb-v4.h>
#include <plat/fb.h>
......@@ -110,6 +111,13 @@ static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = {
.ucon = UCON,
.ulcon = ULCON | 0x50,
.ufcon = UFCON,
},
[3] = {
.hwport = 3,
.flags = 0,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
}
};
......@@ -159,6 +167,18 @@ static struct s3c_fb_platdata smdk2416_fb_platdata = {
.vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
};
static struct s3c_sdhci_platdata smdk2416_hsmmc0_pdata __initdata = {
.max_width = 4,
.cd_type = S3C_SDHCI_CD_GPIO,
.ext_cd_gpio = S3C2410_GPF(1),
.ext_cd_gpio_invert = 1,
};
static struct s3c_sdhci_platdata smdk2416_hsmmc1_pdata __initdata = {
.max_width = 4,
.cd_type = S3C_SDHCI_CD_NONE,
};
static struct platform_device *smdk2416_devices[] __initdata = {
&s3c_device_fb,
&s3c_device_wdt,
......@@ -180,6 +200,9 @@ static void __init smdk2416_machine_init(void)
s3c_i2c0_set_platdata(NULL);
s3c_fb_set_platdata(&smdk2416_fb_platdata);
s3c_sdhci0_set_platdata(&smdk2416_hsmmc0_pdata);
s3c_sdhci1_set_platdata(&smdk2416_hsmmc1_pdata);
gpio_request(S3C2410_GPB(4), "USBHost Power");
gpio_direction_output(S3C2410_GPB(4), 1);
......
......@@ -53,6 +53,7 @@
#include <plat/s3c2416.h>
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/sdhci.h>
#include <plat/iic-core.h>
#include <plat/fb-core.h>
......@@ -115,6 +116,10 @@ void __init s3c2416_map_io(void)
s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_updown;
s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_updown;
/* initialize device information early */
s3c2416_default_sdhci0();
s3c2416_default_sdhci1();
iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc));
}
......
/* linux/arch/arm/plat-s3c2416/setup-sdhci-gpio.c
*
* Copyright 2010 Promwad Innovation Company
* Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
*
* S3C2416 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
*
* Based on mach-s3c64xx/setup-sdhci-gpio.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>
void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{
s3c_gpio_cfgrange_nopull(S3C2410_GPE(5), 2 + width, S3C_GPIO_SFN(2));
}
void s3c2416_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
{
s3c_gpio_cfgrange_nopull(S3C2410_GPL(0), width, S3C_GPIO_SFN(2));
s3c_gpio_cfgrange_nopull(S3C2410_GPL(8), 2, S3C_GPIO_SFN(2));
}
/* linux/arch/arm/mach-s3c2416/setup-sdhci.c
*
* Copyright 2010 Promwad Innovation Company
* Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
*
* S3C2416 - Helper functions for settign up SDHCI device(s) (HSMMC)
*
* Based on mach-s3c64xx/setup-sdhci.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include <plat/regs-sdhci.h>
#include <plat/sdhci.h>
/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
char *s3c2416_hsmmc_clksrcs[4] = {
[0] = "hsmmc",
[1] = "hsmmc",
[2] = "hsmmc-if",
/* [3] = "48m", - note not successfully used yet */
};
void s3c2416_setup_sdhci_cfg_card(struct platform_device *dev,
void __iomem *r,
struct mmc_ios *ios,
struct mmc_card *card)
{
u32 ctrl2, ctrl3;
ctrl2 = __raw_readl(r + S3C_SDHCI_CONTROL2);
ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
S3C_SDHCI_CTRL2_ENFBCLKRX |
S3C_SDHCI_CTRL2_DFCNT_NONE |
S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
if (ios->clock < 25 * 1000000)
ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
S3C_SDHCI_CTRL3_FCSEL2 |
S3C_SDHCI_CTRL3_FCSEL1 |
S3C_SDHCI_CTRL3_FCSEL0);
else
ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
__raw_writel(ctrl2, r + S3C_SDHCI_CONTROL2);
__raw_writel(ctrl3, r + S3C_SDHCI_CONTROL3);
}
......@@ -69,27 +69,27 @@ static void s3c_irq_demux_wdtac97(unsigned int irq,
#define INTMSK_WDT (1UL << (IRQ_WDT - IRQ_EINT0))
static void
s3c_irq_wdtac97_mask(unsigned int irqno)
s3c_irq_wdtac97_mask(struct irq_data *data)
{
s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13);
s3c_irqsub_mask(data->irq, INTMSK_WDT, 3 << 13);
}
static void
s3c_irq_wdtac97_unmask(unsigned int irqno)
s3c_irq_wdtac97_unmask(struct irq_data *data)
{
s3c_irqsub_unmask(irqno, INTMSK_WDT);
s3c_irqsub_unmask(data->irq, INTMSK_WDT);
}
static void
s3c_irq_wdtac97_ack(unsigned int irqno)
s3c_irq_wdtac97_ack(struct irq_data *data)
{
s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13);
s3c_irqsub_maskack(data->irq, INTMSK_WDT, 3 << 13);
}
static struct irq_chip s3c_irq_wdtac97 = {
.mask = s3c_irq_wdtac97_mask,
.unmask = s3c_irq_wdtac97_unmask,
.ack = s3c_irq_wdtac97_ack,
.irq_mask = s3c_irq_wdtac97_mask,
.irq_unmask = s3c_irq_wdtac97_unmask,
.irq_ack = s3c_irq_wdtac97_ack,
};
static int s3c2440_irq_add(struct sys_device *sysdev)
......
......@@ -68,27 +68,27 @@ static void s3c_irq_demux_cam(unsigned int irq,
#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
static void
s3c_irq_cam_mask(unsigned int irqno)
s3c_irq_cam_mask(struct irq_data *data)
{
s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
s3c_irqsub_mask(data->irq, INTMSK_CAM, 3 << 11);
}
static void
s3c_irq_cam_unmask(unsigned int irqno)
s3c_irq_cam_unmask(struct irq_data *data)
{
s3c_irqsub_unmask(irqno, INTMSK_CAM);
s3c_irqsub_unmask(data->irq, INTMSK_CAM);
}
static void
s3c_irq_cam_ack(unsigned int irqno)
s3c_irq_cam_ack(struct irq_data *data)
{
s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
s3c_irqsub_maskack(data->irq, INTMSK_CAM, 3 << 11);
}
static struct irq_chip s3c_irq_cam = {
.mask = s3c_irq_cam_mask,
.unmask = s3c_irq_cam_unmask,
.ack = s3c_irq_cam_ack,
.irq_mask = s3c_irq_cam_mask,
.irq_unmask = s3c_irq_cam_unmask,
.irq_ack = s3c_irq_cam_ack,
};
static int s3c244x_irq_add(struct sys_device *sysdev)
......
......@@ -10,6 +10,7 @@ config CPU_S3C2443
select CPU_LLSERIAL_S3C2440
select SAMSUNG_CLKSRC
select S3C2443_CLOCK
select S3C_GPIO_PULL_S3C2443
help
Support for the S3C2443 SoC from the S3C24XX line
......@@ -25,7 +26,7 @@ config MACH_SMDK2443
bool "SMDK2443"
select CPU_S3C2443
select MACH_SMDK
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
help
Say Y here if you are using an SMDK2443
......
......@@ -196,7 +196,7 @@ static struct clksrc_clk clk_hsspi = {
static struct clksrc_clk clk_hsmmc_div = {
.clk = {
.name = "hsmmc-div",
.id = -1,
.id = 1,
.parent = &clk_esysclk.clk,
},
.reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
......@@ -231,7 +231,7 @@ static int s3c2443_enable_hsmmc(struct clk *clk, int enable)
static struct clk clk_hsmmc = {
.name = "hsmmc-if",
.id = -1,
.id = 1,
.parent = &clk_hsmmc_div.clk,
.enable = s3c2443_enable_hsmmc,
.ops = &(struct clk_ops) {
......
......@@ -75,28 +75,27 @@ static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
static void s3c2443_irq_wdtac97_mask(unsigned int irqno)
static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
{
s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
}
static void s3c2443_irq_wdtac97_unmask(unsigned int irqno)
static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
{
s3c_irqsub_unmask(irqno, INTMSK_WDTAC97);
s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
}
static void s3c2443_irq_wdtac97_ack(unsigned int irqno)
static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
{
s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
}
static struct irq_chip s3c2443_irq_wdtac97 = {
.mask = s3c2443_irq_wdtac97_mask,
.unmask = s3c2443_irq_wdtac97_unmask,
.ack = s3c2443_irq_wdtac97_ack,
.irq_mask = s3c2443_irq_wdtac97_mask,
.irq_unmask = s3c2443_irq_wdtac97_unmask,
.irq_ack = s3c2443_irq_wdtac97_ack,
};
/* LCD sub interrupts */
static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
......@@ -107,28 +106,27 @@ static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
static void s3c2443_irq_lcd_mask(unsigned int irqno)
static void s3c2443_irq_lcd_mask(struct irq_data *data)
{
s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD);
s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
}
static void s3c2443_irq_lcd_unmask(unsigned int irqno)
static void s3c2443_irq_lcd_unmask(struct irq_data *data)
{
s3c_irqsub_unmask(irqno, INTMSK_LCD);
s3c_irqsub_unmask(data->irq, INTMSK_LCD);
}
static void s3c2443_irq_lcd_ack(unsigned int irqno)
static void s3c2443_irq_lcd_ack(struct irq_data *data)
{
s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD);
s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
}
static struct irq_chip s3c2443_irq_lcd = {
.mask = s3c2443_irq_lcd_mask,
.unmask = s3c2443_irq_lcd_unmask,
.ack = s3c2443_irq_lcd_ack,
.irq_mask = s3c2443_irq_lcd_mask,
.irq_unmask = s3c2443_irq_lcd_unmask,
.irq_ack = s3c2443_irq_lcd_ack,
};
/* DMA sub interrupts */
static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
......@@ -139,29 +137,27 @@ static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
static void s3c2443_irq_dma_mask(unsigned int irqno)
static void s3c2443_irq_dma_mask(struct irq_data *data)
{
s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA);
s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
}
static void s3c2443_irq_dma_unmask(unsigned int irqno)
static void s3c2443_irq_dma_unmask(struct irq_data *data)
{
s3c_irqsub_unmask(irqno, INTMSK_DMA);
s3c_irqsub_unmask(data->irq, INTMSK_DMA);
}
static void s3c2443_irq_dma_ack(unsigned int irqno)
static void s3c2443_irq_dma_ack(struct irq_data *data)
{
s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA);
s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
}
static struct irq_chip s3c2443_irq_dma = {
.mask = s3c2443_irq_dma_mask,
.unmask = s3c2443_irq_dma_unmask,
.ack = s3c2443_irq_dma_ack,
.irq_mask = s3c2443_irq_dma_mask,
.irq_unmask = s3c2443_irq_dma_unmask,
.irq_ack = s3c2443_irq_dma_ack,
};
/* UART3 sub interrupts */
static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
......@@ -172,28 +168,27 @@ static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
#define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
static void s3c2443_irq_uart3_mask(unsigned int irqno)
static void s3c2443_irq_uart3_mask(struct irq_data *data)
{
s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3);
s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
}
static void s3c2443_irq_uart3_unmask(unsigned int irqno)
static void s3c2443_irq_uart3_unmask(struct irq_data *data)
{
s3c_irqsub_unmask(irqno, INTMSK_UART3);
s3c_irqsub_unmask(data->irq, INTMSK_UART3);
}
static void s3c2443_irq_uart3_ack(unsigned int irqno)
static void s3c2443_irq_uart3_ack(struct irq_data *data)
{
s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3);
s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
}
static struct irq_chip s3c2443_irq_uart3 = {
.mask = s3c2443_irq_uart3_mask,
.unmask = s3c2443_irq_uart3_unmask,
.ack = s3c2443_irq_uart3_ack,
.irq_mask = s3c2443_irq_uart3_mask,
.irq_unmask = s3c2443_irq_uart3_unmask,
.irq_ack = s3c2443_irq_uart3_ack,
};
/* CAM sub interrupts */
static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
......@@ -204,25 +199,25 @@ static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
#define SUBMSK_CAM INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
static void s3c2443_irq_cam_mask(unsigned int irqno)
static void s3c2443_irq_cam_mask(struct irq_data *data)
{
s3c_irqsub_mask(irqno, INTMSK_CAM, SUBMSK_CAM);
s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM);
}
static void s3c2443_irq_cam_unmask(unsigned int irqno)
static void s3c2443_irq_cam_unmask(struct irq_data *data)
{
s3c_irqsub_unmask(irqno, INTMSK_CAM);
s3c_irqsub_unmask(data->irq, INTMSK_CAM);
}
static void s3c2443_irq_cam_ack(unsigned int irqno)
static void s3c2443_irq_cam_ack(struct irq_data *data)
{
s3c_irqsub_maskack(irqno, INTMSK_CAM, SUBMSK_CAM);
s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM);
}
static struct irq_chip s3c2443_irq_cam = {
.mask = s3c2443_irq_cam_mask,
.unmask = s3c2443_irq_cam_unmask,
.ack = s3c2443_irq_cam_ack,
.irq_mask = s3c2443_irq_cam_mask,
.irq_unmask = s3c2443_irq_cam_unmask,
.irq_ack = s3c2443_irq_cam_ack,
};
/* IRQ initialisation code */
......
......@@ -99,13 +99,20 @@ static struct s3c2410_uartcfg smdk2443_uartcfgs[] __initdata = {
.ucon = 0x3c5,
.ulcon = 0x43,
.ufcon = 0x51,
},
[3] = {
.hwport = 3,
.flags = 0,
.ucon = 0x3c5,
.ulcon = 0x03,
.ufcon = 0x51,
}
};
static struct platform_device *smdk2443_devices[] __initdata = {
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
#ifdef CONFIG_SND_SOC_SMDK2443_WM9710
&s3c_device_ac97,
#endif
......
......@@ -16,6 +16,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/sysdev.h>
......@@ -32,6 +33,9 @@
#include <mach/regs-s3c2443-clock.h>
#include <mach/reset.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>
#include <plat/s3c2443.h>
#include <plat/devs.h>
#include <plat/cpu.h>
......@@ -86,6 +90,9 @@ void __init s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no)
void __init s3c2443_map_io(void)
{
s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_s3c2443;
s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_s3c2443;
iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc));
}
......
......@@ -127,7 +127,7 @@ int s3c64xx_sclk_ctrl(struct clk *clk, int enable)
return s3c64xx_gate(S3C_SCLK_GATE, clk, enable);
}
static struct clk init_clocks_disable[] = {
static struct clk init_clocks_off[] = {
{
.name = "nand",
.id = -1,
......@@ -695,7 +695,7 @@ static struct clksrc_clk clksrcs[] = {
}, {
.clk = {
.name = "audio-bus",
.id = -1, /* There's only one IISv4 port */
.id = 2,
.ctrlbit = S3C6410_CLKCON_SCLK_AUDIO2,
.enable = s3c64xx_sclk_ctrl,
},
......@@ -834,10 +834,6 @@ static struct clk *clks[] __initdata = {
void __init s3c64xx_register_clocks(unsigned long xtal,
unsigned armclk_divlimit)
{
struct clk *clkp;
int ret;
int ptr;
armclk_mask = armclk_divlimit;
s3c24xx_register_baseclocks(xtal);
......@@ -845,17 +841,8 @@ void __init s3c64xx_register_clocks(unsigned long xtal,
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
clkp = init_clocks_disable;
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
ret = s3c24xx_register_clock(clkp);
if (ret < 0) {
printk(KERN_ERR "Failed to register clock %s (%d)\n",
clkp->name, ret);
}
(clkp->enable)(clkp, 0);
}
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(clks1, ARRAY_SIZE(clks1));
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
......
......@@ -22,7 +22,12 @@
#include <plat/audio.h>
#include <plat/gpio-cfg.h>
static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
static const char *rclksrc[] = {
[0] = "iis",
[1] = "audio-bus",
};
static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev)
{
unsigned int base;
......@@ -33,6 +38,12 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
case 1:
base = S3C64XX_GPE(0);
break;
case 2:
s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
return 0;
default:
printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
pdev->id);
......@@ -44,16 +55,6 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
return 0;
}
static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev)
{
s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
return 0;
}
static struct resource s3c64xx_iis0_resource[] = {
[0] = {
.start = S3C64XX_PA_IIS0,
......@@ -72,17 +73,22 @@ static struct resource s3c64xx_iis0_resource[] = {
},
};
static struct s3c_audio_pdata s3c_i2s0_pdata = {
.cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
static struct s3c_audio_pdata i2sv3_pdata = {
.cfg_gpio = s3c64xx_i2s_cfg_gpio,
.type = {
.i2s = {
.src_clk = rclksrc,
},
},
};
struct platform_device s3c64xx_device_iis0 = {
.name = "s3c64xx-iis",
.name = "samsung-i2s",
.id = 0,
.num_resources = ARRAY_SIZE(s3c64xx_iis0_resource),
.resource = s3c64xx_iis0_resource,
.dev = {
.platform_data = &s3c_i2s0_pdata,
.platform_data = &i2sv3_pdata,
},
};
EXPORT_SYMBOL(s3c64xx_device_iis0);
......@@ -105,17 +111,13 @@ static struct resource s3c64xx_iis1_resource[] = {
},
};
static struct s3c_audio_pdata s3c_i2s1_pdata = {
.cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
};
struct platform_device s3c64xx_device_iis1 = {
.name = "s3c64xx-iis",
.name = "samsung-i2s",
.id = 1,
.num_resources = ARRAY_SIZE(s3c64xx_iis1_resource),
.resource = s3c64xx_iis1_resource,
.dev = {
.platform_data = &s3c_i2s1_pdata,
.platform_data = &i2sv3_pdata,
},
};
EXPORT_SYMBOL(s3c64xx_device_iis1);
......@@ -138,17 +140,23 @@ static struct resource s3c64xx_iisv4_resource[] = {
},
};
static struct s3c_audio_pdata s3c_i2sv4_pdata = {
.cfg_gpio = s3c64xx_i2sv4_cfg_gpio,
static struct s3c_audio_pdata i2sv4_pdata = {
.cfg_gpio = s3c64xx_i2s_cfg_gpio,
.type = {
.i2s = {
.quirks = QUIRK_PRI_6CHAN,
.src_clk = rclksrc,
},
},
};
struct platform_device s3c64xx_device_iisv4 = {
.name = "s3c64xx-iis-v4",
.id = -1,
.name = "samsung-i2s",
.id = 2,
.num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource),
.resource = s3c64xx_iisv4_resource,
.dev = {
.platform_data = &s3c_i2sv4_pdata,
.platform_data = &i2sv4_pdata,
},
};
EXPORT_SYMBOL(s3c64xx_device_iisv4);
......
......@@ -212,6 +212,7 @@ static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan)
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);
......
......@@ -30,41 +30,41 @@
#include <plat/pm.h>
#define eint_offset(irq) ((irq) - IRQ_EINT(0))
#define eint_irq_to_bit(irq) (1 << eint_offset(irq))
#define eint_irq_to_bit(irq) ((u32)(1 << eint_offset(irq)))
static inline void s3c_irq_eint_mask(unsigned int irq)
static inline void s3c_irq_eint_mask(struct irq_data *data)
{
u32 mask;
mask = __raw_readl(S3C64XX_EINT0MASK);
mask |= eint_irq_to_bit(irq);
mask |= (u32)data->chip_data;
__raw_writel(mask, S3C64XX_EINT0MASK);
}
static void s3c_irq_eint_unmask(unsigned int irq)
static void s3c_irq_eint_unmask(struct irq_data *data)
{
u32 mask;
mask = __raw_readl(S3C64XX_EINT0MASK);
mask &= ~eint_irq_to_bit(irq);
mask &= ~((u32)data->chip_data);
__raw_writel(mask, S3C64XX_EINT0MASK);
}
static inline void s3c_irq_eint_ack(unsigned int irq)
static inline void s3c_irq_eint_ack(struct irq_data *data)
{
__raw_writel(eint_irq_to_bit(irq), S3C64XX_EINT0PEND);
__raw_writel((u32)data->chip_data, S3C64XX_EINT0PEND);
}
static void s3c_irq_eint_maskack(unsigned int irq)
static void s3c_irq_eint_maskack(struct irq_data *data)
{
/* compiler should in-line these */
s3c_irq_eint_mask(irq);
s3c_irq_eint_ack(irq);
s3c_irq_eint_mask(data);
s3c_irq_eint_ack(data);
}
static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
static int s3c_irq_eint_set_type(struct irq_data *data, unsigned int type)
{
int offs = eint_offset(irq);
int offs = eint_offset(data->irq);
int pin, pin_val;
int shift;
u32 ctrl, mask;
......@@ -140,12 +140,12 @@ static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
static struct irq_chip s3c_irq_eint = {
.name = "s3c-eint",
.mask = s3c_irq_eint_mask,
.unmask = s3c_irq_eint_unmask,
.mask_ack = s3c_irq_eint_maskack,
.ack = s3c_irq_eint_ack,
.set_type = s3c_irq_eint_set_type,
.set_wake = s3c_irqext_wake,
.irq_mask = s3c_irq_eint_mask,
.irq_unmask = s3c_irq_eint_unmask,
.irq_mask_ack = s3c_irq_eint_maskack,
.irq_ack = s3c_irq_eint_ack,
.irq_set_type = s3c_irq_eint_set_type,
.irq_set_wake = s3c_irqext_wake,
};
/* s3c_irq_demux_eint
......@@ -198,6 +198,7 @@ static int __init s3c64xx_init_irq_eint(void)
for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
set_irq_chip(irq, &s3c_irq_eint);
set_irq_chip_data(irq, (void *)eint_irq_to_bit(irq));
set_irq_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
......
......@@ -340,7 +340,7 @@ void __init_or_cpufreq s5p6442_setup_clocks(void)
clk_pclkd1.rate = pclkd1;
}
static struct clk init_clocks_disable[] = {
static struct clk init_clocks_off[] = {
{
.name = "pdma",
.id = -1,
......@@ -408,23 +408,13 @@ static struct clk *clks[] __initdata = {
void __init s5p6442_register_clocks(void)
{
struct clk *clkptr;
int i, ret;
s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
clkptr = init_clocks_disable;
for (i = 0; i < ARRAY_SIZE(init_clocks_disable); i++, clkptr++) {
ret = s3c24xx_register_clock(clkptr);
if (ret < 0) {
printk(KERN_ERR "Fail to register clock %s (%d)\n",
clkptr->name, ret);
} else
(clkptr->enable)(clkptr, 0);
}
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_pwmclk_init();
}
......@@ -29,7 +29,7 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev)
base = S5P6442_GPC1(0);
break;
case -1:
case 0:
base = S5P6442_GPC0(0);
break;
......@@ -42,8 +42,19 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev)
return 0;
}
static struct s3c_audio_pdata s3c_i2s_pdata = {
static const char *rclksrc_v35[] = {
[0] = "busclk",
[1] = "i2sclk",
};
static struct s3c_audio_pdata i2sv35_pdata = {
.cfg_gpio = s5p6442_cfg_i2s,
.type = {
.i2s = {
.quirks = QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR,
.src_clk = rclksrc_v35,
},
},
};
static struct resource s5p6442_iis0_resource[] = {
......@@ -62,15 +73,34 @@ static struct resource s5p6442_iis0_resource[] = {
.end = DMACH_I2S0_RX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = DMACH_I2S0S_TX,
.end = DMACH_I2S0S_TX,
.flags = IORESOURCE_DMA,
},
};
struct platform_device s5p6442_device_iis0 = {
.name = "s3c64xx-iis-v4",
.id = -1,
.name = "samsung-i2s",
.id = 0,
.num_resources = ARRAY_SIZE(s5p6442_iis0_resource),
.resource = s5p6442_iis0_resource,
.dev = {
.platform_data = &s3c_i2s_pdata,
.platform_data = &i2sv35_pdata,
},
};
static const char *rclksrc_v3[] = {
[0] = "iis",
[1] = "sclk_audio",
};
static struct s3c_audio_pdata i2sv3_pdata = {
.cfg_gpio = s5p6442_cfg_i2s,
.type = {
.i2s = {
.src_clk = rclksrc_v3,
},
},
};
......@@ -93,12 +123,12 @@ static struct resource s5p6442_iis1_resource[] = {
};
struct platform_device s5p6442_device_iis1 = {
.name = "s3c64xx-iis",
.name = "samsung-i2s",
.id = 1,
.num_resources = ARRAY_SIZE(s5p6442_iis1_resource),
.resource = s5p6442_iis1_resource,
.dev = {
.platform_data = &s3c_i2s_pdata,
.platform_data = &i2sv3_pdata,
},
};
......
......@@ -28,6 +28,9 @@
#define S5P6442_PA_VIC1 (0xE4100000)
#define S5P6442_PA_VIC2 (0xE4200000)
#define S5P6442_PA_SROMC (0xE7000000)
#define S5P_PA_SROMC S5P6442_PA_SROMC
#define S5P6442_PA_MDMA 0xE8000000
#define S5P6442_PA_PDMA 0xE9000000
......
......@@ -12,6 +12,7 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/i2c.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
......@@ -25,6 +26,7 @@
#include <plat/s5p6442.h>
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/iic.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDK6442_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
......@@ -65,10 +67,15 @@ static struct s3c2410_uartcfg smdk6442_uartcfgs[] __initdata = {
};
static struct platform_device *smdk6442_devices[] __initdata = {
&s3c_device_i2c0,
&s5p6442_device_iis0,
&s3c_device_wdt,
};
static struct i2c_board_info smdk6442_i2c_devs0[] __initdata = {
{ I2C_BOARD_INFO("wm8580", 0x1b), },
};
static void __init smdk6442_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
......@@ -78,6 +85,9 @@ static void __init smdk6442_map_io(void)
static void __init smdk6442_machine_init(void)
{
s3c_i2c0_set_platdata(NULL);
i2c_register_board_info(0, smdk6442_i2c_devs0,
ARRAY_SIZE(smdk6442_i2c_devs0));
platform_add_devices(smdk6442_devices, ARRAY_SIZE(smdk6442_devices));
}
......
......@@ -14,12 +14,15 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/gpio.h>
struct platform_device; /* don't need the contents */
#include <plat/gpio-cfg.h>
#include <plat/iic.h>
void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{
/* Will be populated later */
s3c_gpio_cfgall_range(S5P6442_GPD1(0), 2,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
......@@ -12,9 +12,9 @@ obj- :=
# Core support for S5P64X0 system
obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o
obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o gpiolib.o
obj-$(CONFIG_ARCH_S5P64X0) += setup-i2c0.o
obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o gpio.o
obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o
obj-$(CONFIG_CPU_S5P6450) += clock-s5p6450.o
# machine support
......
......@@ -133,7 +133,7 @@ static struct clksrc_clk clk_pclk_low = {
* recommended to keep the following clocks disabled until the driver requests
* for enabling the clock.
*/
static struct clk init_clocks_disable[] = {
static struct clk init_clocks_off[] = {
{
.name = "nand",
.id = -1,
......@@ -261,7 +261,7 @@ static struct clk init_clocks_disable[] = {
.enable = s5p64x0_pclk_ctrl,
.ctrlbit = (1 << 25),
}, {
.name = "i2s_v40",
.name = "iis",
.id = 0,
.parent = &clk_pclk_low.clk,
.enable = s5p64x0_pclk_ctrl,
......@@ -419,7 +419,7 @@ static struct clksrc_sources clkset_audio = {
static struct clksrc_clk clksrcs[] = {
{
.clk = {
.name = "mmc_bus",
.name = "sclk_mmc",
.id = 0,
.ctrlbit = (1 << 24),
.enable = s5p64x0_sclk_ctrl,
......@@ -429,7 +429,7 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "mmc_bus",
.name = "sclk_mmc",
.id = 1,
.ctrlbit = (1 << 25),
.enable = s5p64x0_sclk_ctrl,
......@@ -439,7 +439,7 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
}, {
.clk = {
.name = "mmc_bus",
.name = "sclk_mmc",
.id = 2,
.ctrlbit = (1 << 26),
.enable = s5p64x0_sclk_ctrl,
......@@ -602,8 +602,6 @@ static struct clk *clks[] __initdata = {
void __init s5p6440_register_clocks(void)
{
struct clk *clkp;
int ret;
int ptr;
s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
......@@ -614,16 +612,8 @@ void __init s5p6440_register_clocks(void)
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
clkp = init_clocks_disable;
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
ret = s3c24xx_register_clock(clkp);
if (ret < 0) {
printk(KERN_ERR "Failed to register clock %s (%d)\n",
clkp->name, ret);
}
(clkp->enable)(clkp, 0);
}
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_pwmclk_init();
}
......@@ -181,7 +181,7 @@ static struct clksrc_clk clk_pclk_low = {
* recommended to keep the following clocks disabled until the driver requests
* for enabling the clock.
*/
static struct clk init_clocks_disable[] = {
static struct clk init_clocks_off[] = {
{
.name = "usbhost",
.id = -1,
......@@ -230,6 +230,12 @@ static struct clk init_clocks_disable[] = {
.parent = &clk_pclk_low.clk,
.enable = s5p64x0_pclk_ctrl,
.ctrlbit = (1 << 5),
}, {
.name = "rtc",
.id = -1,
.parent = &clk_pclk_low.clk,
.enable = s5p64x0_pclk_ctrl,
.ctrlbit = (1 << 6),
}, {
.name = "adc",
.id = -1,
......@@ -256,10 +262,22 @@ static struct clk init_clocks_disable[] = {
.ctrlbit = (1 << 22),
}, {
.name = "iis",
.id = -1,
.id = 0,
.parent = &clk_pclk_low.clk,
.enable = s5p64x0_pclk_ctrl,
.ctrlbit = (1 << 26),
}, {
.name = "iis",
.id = 1,
.parent = &clk_pclk_low.clk,
.enable = s5p64x0_pclk_ctrl,
.ctrlbit = (1 << 15),
}, {
.name = "iis",
.id = 2,
.parent = &clk_pclk_low.clk,
.enable = s5p64x0_pclk_ctrl,
.ctrlbit = (1 << 16),
}, {
.name = "i2c",
.id = 1,
......@@ -633,8 +651,6 @@ void __init_or_cpufreq s5p6450_setup_clocks(void)
void __init s5p6450_register_clocks(void)
{
struct clk *clkp;
int ret;
int ptr;
for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
......@@ -643,16 +659,8 @@ void __init s5p6450_register_clocks(void)
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
clkp = init_clocks_disable;
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
ret = s3c24xx_register_clock(clkp);
if (ret < 0) {
printk(KERN_ERR "Failed to register clock %s (%d)\n",
clkp->name, ret);
}
(clkp->enable)(clkp, 0);
}
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_pwmclk_init();
}
......@@ -19,15 +19,19 @@
#include <mach/dma.h>
#include <mach/irqs.h>
static const char *rclksrc[] = {
[0] = "iis",
[1] = "sclk_audio2",
};
static int s5p6440_cfg_i2s(struct platform_device *pdev)
{
/* configure GPIO for i2s port */
switch (pdev->id) {
case -1:
s3c_gpio_cfgpin_range(S5P6440_GPR(4), 5, S3C_GPIO_SFN(5));
s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(5));
case 0:
s3c_gpio_cfgpin_range(S5P6440_GPC(4), 2, S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6440_GPC(7), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin_range(S5P6440_GPH(6), 4, S3C_GPIO_SFN(5));
break;
default:
printk(KERN_ERR "Invalid Device %d\n", pdev->id);
return -EINVAL;
......@@ -36,17 +40,58 @@ static int s5p6440_cfg_i2s(struct platform_device *pdev)
return 0;
}
static struct s3c_audio_pdata s5p6440_i2s_pdata = {
.cfg_gpio = s5p6440_cfg_i2s,
.type = {
.i2s = {
.quirks = QUIRK_PRI_6CHAN,
.src_clk = rclksrc,
},
},
};
static struct resource s5p64x0_i2s0_resource[] = {
[0] = {
.start = S5P64X0_PA_I2S,
.end = S5P64X0_PA_I2S + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_I2S0_TX,
.end = DMACH_I2S0_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_I2S0_RX,
.end = DMACH_I2S0_RX,
.flags = IORESOURCE_DMA,
},
};
struct platform_device s5p6440_device_iis = {
.name = "samsung-i2s",
.id = 0,
.num_resources = ARRAY_SIZE(s5p64x0_i2s0_resource),
.resource = s5p64x0_i2s0_resource,
.dev = {
.platform_data = &s5p6440_i2s_pdata,
},
};
static int s5p6450_cfg_i2s(struct platform_device *pdev)
{
/* configure GPIO for i2s port */
switch (pdev->id) {
case -1:
s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5));
case 0:
s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5));
s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5));
break;
case 1:
s3c_gpio_cfgpin(S5P6440_GPB(4), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin_range(S5P6450_GPC(0), 4, S3C_GPIO_SFN(5));
break;
case 2:
s3c_gpio_cfgpin_range(S5P6450_GPK(0), 5, S3C_GPIO_SFN(5));
break;
default:
printk(KERN_ERR "Invalid Device %d\n", pdev->id);
return -EINVAL;
......@@ -55,47 +100,86 @@ static int s5p6450_cfg_i2s(struct platform_device *pdev)
return 0;
}
static struct s3c_audio_pdata s5p6440_i2s_pdata = {
.cfg_gpio = s5p6440_cfg_i2s,
static struct s3c_audio_pdata s5p6450_i2s0_pdata = {
.cfg_gpio = s5p6450_cfg_i2s,
.type = {
.i2s = {
.quirks = QUIRK_PRI_6CHAN,
.src_clk = rclksrc,
},
},
};
struct platform_device s5p6450_device_iis0 = {
.name = "samsung-i2s",
.id = 0,
.num_resources = ARRAY_SIZE(s5p64x0_i2s0_resource),
.resource = s5p64x0_i2s0_resource,
.dev = {
.platform_data = &s5p6450_i2s0_pdata,
},
};
static struct s3c_audio_pdata s5p6450_i2s_pdata = {
.cfg_gpio = s5p6450_cfg_i2s,
.type = {
.i2s = {
.src_clk = rclksrc,
},
},
};
static struct resource s5p64x0_iis0_resource[] = {
static struct resource s5p6450_i2s1_resource[] = {
[0] = {
.start = S5P64X0_PA_I2S,
.end = S5P64X0_PA_I2S + 0x100 - 1,
.start = S5P6450_PA_I2S1,
.end = S5P6450_PA_I2S1 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_I2S0_TX,
.end = DMACH_I2S0_TX,
.start = DMACH_I2S1_TX,
.end = DMACH_I2S1_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_I2S0_RX,
.end = DMACH_I2S0_RX,
.start = DMACH_I2S1_RX,
.end = DMACH_I2S1_RX,
.flags = IORESOURCE_DMA,
},
};
struct platform_device s5p6440_device_iis = {
.name = "s3c64xx-iis-v4",
.id = -1,
.num_resources = ARRAY_SIZE(s5p64x0_iis0_resource),
.resource = s5p64x0_iis0_resource,
struct platform_device s5p6450_device_iis1 = {
.name = "samsung-i2s",
.id = 1,
.num_resources = ARRAY_SIZE(s5p6450_i2s1_resource),
.resource = s5p6450_i2s1_resource,
.dev = {
.platform_data = &s5p6440_i2s_pdata,
.platform_data = &s5p6450_i2s_pdata,
},
};
struct platform_device s5p6450_device_iis0 = {
.name = "s3c64xx-iis-v4",
.id = -1,
.num_resources = ARRAY_SIZE(s5p64x0_iis0_resource),
.resource = s5p64x0_iis0_resource,
static struct resource s5p6450_i2s2_resource[] = {
[0] = {
.start = S5P6450_PA_I2S2,
.end = S5P6450_PA_I2S2 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_I2S2_TX,
.end = DMACH_I2S2_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_I2S2_RX,
.end = DMACH_I2S2_RX,
.flags = IORESOURCE_DMA,
},
};
struct platform_device s5p6450_device_iis2 = {
.name = "samsung-i2s",
.id = 2,
.num_resources = ARRAY_SIZE(s5p6450_i2s2_resource),
.resource = s5p6450_i2s2_resource,
.dev = {
.platform_data = &s5p6450_i2s_pdata,
},
......
/* linux/arch/arm/mach-s5p64x0/gpio.c
/* linux/arch/arm/mach-s5p64x0/gpiolib.c
*
* Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
......@@ -17,13 +17,12 @@
#include <mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/regs-clock.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>
/* To be implemented S5P6450 GPIO */
/*
* S5P6440 GPIO bank summary:
*
......@@ -40,6 +39,25 @@
* P 8 2Bit Yes 8
* R 15 4Bit[2] Yes 8
*
* S5P6450 GPIO bank summary:
*
* Bank GPIOs Style SlpCon ExtInt Group
* A 6 4Bit Yes 1
* B 7 4Bit Yes 1
* C 8 4Bit Yes 2
* D 8 4Bit Yes None
* F 2 2Bit Yes None
* G 14 4Bit[2] Yes 5
* H 10 4Bit[2] Yes 6
* I 16 2Bit Yes None
* J 12 2Bit Yes None
* K 5 4Bit Yes None
* N 16 2Bit No IRQ_EINT
* P 11 2Bit Yes 8
* Q 14 2Bit Yes None
* R 15 4Bit[2] Yes None
* S 8 2Bit Yes None
*
* [1] BANKF pins 14,15 do not form part of the external interrupt sources
* [2] BANK has two control registers, GPxCON0 and GPxCON1
*/
......@@ -190,7 +208,7 @@ static struct s3c_gpio_cfg s5p64x0_gpio_cfgs[] = {
static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
{
.base = S5P6440_GPA_BASE,
.base = S5P64X0_GPA_BASE,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6440_GPA(0),
......@@ -198,7 +216,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
.label = "GPA",
},
}, {
.base = S5P6440_GPB_BASE,
.base = S5P64X0_GPB_BASE,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6440_GPB(0),
......@@ -206,7 +224,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
.label = "GPB",
},
}, {
.base = S5P6440_GPC_BASE,
.base = S5P64X0_GPC_BASE,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6440_GPC(0),
......@@ -214,7 +232,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
.label = "GPC",
},
}, {
.base = S5P6440_GPG_BASE,
.base = S5P64X0_GPG_BASE,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6440_GPG(0),
......@@ -226,7 +244,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = {
{
.base = S5P6440_GPH_BASE + 0x4,
.base = S5P64X0_GPH_BASE + 0x4,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6440_GPH(0),
......@@ -238,7 +256,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = {
static struct s3c_gpio_chip s5p6440_gpio_rbank_4bit2[] = {
{
.base = S5P6440_GPR_BASE + 0x4,
.base = S5P64X0_GPR_BASE + 0x4,
.config = &s5p64x0_gpio_cfgs[2],
.chip = {
.base = S5P6440_GPR(0),
......@@ -250,7 +268,7 @@ static struct s3c_gpio_chip s5p6440_gpio_rbank_4bit2[] = {
static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
{
.base = S5P6440_GPF_BASE,
.base = S5P64X0_GPF_BASE,
.config = &s5p64x0_gpio_cfgs[5],
.chip = {
.base = S5P6440_GPF(0),
......@@ -258,7 +276,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
.label = "GPF",
},
}, {
.base = S5P6440_GPI_BASE,
.base = S5P64X0_GPI_BASE,
.config = &s5p64x0_gpio_cfgs[3],
.chip = {
.base = S5P6440_GPI(0),
......@@ -266,7 +284,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
.label = "GPI",
},
}, {
.base = S5P6440_GPJ_BASE,
.base = S5P64X0_GPJ_BASE,
.config = &s5p64x0_gpio_cfgs[3],
.chip = {
.base = S5P6440_GPJ(0),
......@@ -274,7 +292,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
.label = "GPJ",
},
}, {
.base = S5P6440_GPN_BASE,
.base = S5P64X0_GPN_BASE,
.config = &s5p64x0_gpio_cfgs[4],
.chip = {
.base = S5P6440_GPN(0),
......@@ -282,7 +300,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
.label = "GPN",
},
}, {
.base = S5P6440_GPP_BASE,
.base = S5P64X0_GPP_BASE,
.config = &s5p64x0_gpio_cfgs[5],
.chip = {
.base = S5P6440_GPP(0),
......@@ -292,6 +310,142 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
},
};
static struct s3c_gpio_chip s5p6450_gpio_4bit[] = {
{
.base = S5P64X0_GPA_BASE,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6450_GPA(0),
.ngpio = S5P6450_GPIO_A_NR,
.label = "GPA",
},
}, {
.base = S5P64X0_GPB_BASE,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6450_GPB(0),
.ngpio = S5P6450_GPIO_B_NR,
.label = "GPB",
},
}, {
.base = S5P64X0_GPC_BASE,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6450_GPC(0),
.ngpio = S5P6450_GPIO_C_NR,
.label = "GPC",
},
}, {
.base = S5P6450_GPD_BASE,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6450_GPD(0),
.ngpio = S5P6450_GPIO_D_NR,
.label = "GPD",
},
}, {
.base = S5P6450_GPK_BASE,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6450_GPK(0),
.ngpio = S5P6450_GPIO_K_NR,
.label = "GPK",
},
},
};
static struct s3c_gpio_chip s5p6450_gpio_4bit2[] = {
{
.base = S5P64X0_GPG_BASE + 0x4,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6450_GPG(0),
.ngpio = S5P6450_GPIO_G_NR,
.label = "GPG",
},
}, {
.base = S5P64X0_GPH_BASE + 0x4,
.config = &s5p64x0_gpio_cfgs[1],
.chip = {
.base = S5P6450_GPH(0),
.ngpio = S5P6450_GPIO_H_NR,
.label = "GPH",
},
},
};
static struct s3c_gpio_chip s5p6450_gpio_rbank_4bit2[] = {
{
.base = S5P64X0_GPR_BASE + 0x4,
.config = &s5p64x0_gpio_cfgs[2],
.chip = {
.base = S5P6450_GPR(0),
.ngpio = S5P6450_GPIO_R_NR,
.label = "GPR",
},
},
};
static struct s3c_gpio_chip s5p6450_gpio_2bit[] = {
{
.base = S5P64X0_GPF_BASE,
.config = &s5p64x0_gpio_cfgs[5],
.chip = {
.base = S5P6450_GPF(0),
.ngpio = S5P6450_GPIO_F_NR,
.label = "GPF",
},
}, {
.base = S5P64X0_GPI_BASE,
.config = &s5p64x0_gpio_cfgs[3],
.chip = {
.base = S5P6450_GPI(0),
.ngpio = S5P6450_GPIO_I_NR,
.label = "GPI",
},
}, {
.base = S5P64X0_GPJ_BASE,
.config = &s5p64x0_gpio_cfgs[3],
.chip = {
.base = S5P6450_GPJ(0),
.ngpio = S5P6450_GPIO_J_NR,
.label = "GPJ",
},
}, {
.base = S5P64X0_GPN_BASE,
.config = &s5p64x0_gpio_cfgs[4],
.chip = {
.base = S5P6450_GPN(0),
.ngpio = S5P6450_GPIO_N_NR,
.label = "GPN",
},
}, {
.base = S5P64X0_GPP_BASE,
.config = &s5p64x0_gpio_cfgs[5],
.chip = {
.base = S5P6450_GPP(0),
.ngpio = S5P6450_GPIO_P_NR,
.label = "GPP",
},
}, {
.base = S5P6450_GPQ_BASE,
.config = &s5p64x0_gpio_cfgs[4],
.chip = {
.base = S5P6450_GPQ(0),
.ngpio = S5P6450_GPIO_Q_NR,
.label = "GPQ",
},
}, {
.base = S5P6450_GPS_BASE,
.config = &s5p64x0_gpio_cfgs[5],
.chip = {
.base = S5P6450_GPS(0),
.ngpio = S5P6450_GPIO_S_NR,
.label = "GPS",
},
},
};
void __init s5p64x0_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
{
for (; nr_chips > 0; nr_chips--, chipcfg++) {
......@@ -317,26 +471,41 @@ static void __init s5p64x0_gpio_add_rbank_4bit2(struct s3c_gpio_chip *chip,
}
}
static int __init s5p6440_gpiolib_init(void)
static int __init s5p64x0_gpiolib_init(void)
{
struct s3c_gpio_chip *chips = s5p6440_gpio_2bit;
int nr_chips = ARRAY_SIZE(s5p6440_gpio_2bit);
unsigned int chipid;
chipid = __raw_readl(S5P64X0_SYS_ID);
s5p64x0_gpiolib_set_cfg(s5p64x0_gpio_cfgs,
ARRAY_SIZE(s5p64x0_gpio_cfgs));
for (; nr_chips > 0; nr_chips--, chips++)
s3c_gpiolib_add(chips);
if ((chipid & 0xff000) == 0x50000) {
samsung_gpiolib_add_2bit_chips(s5p6450_gpio_2bit,
ARRAY_SIZE(s5p6450_gpio_2bit));
samsung_gpiolib_add_4bit_chips(s5p6450_gpio_4bit,
ARRAY_SIZE(s5p6450_gpio_4bit));
samsung_gpiolib_add_4bit_chips(s5p6440_gpio_4bit,
ARRAY_SIZE(s5p6440_gpio_4bit));
samsung_gpiolib_add_4bit2_chips(s5p6450_gpio_4bit2,
ARRAY_SIZE(s5p6450_gpio_4bit2));
samsung_gpiolib_add_4bit2_chips(s5p6440_gpio_4bit2,
ARRAY_SIZE(s5p6440_gpio_4bit2));
s5p64x0_gpio_add_rbank_4bit2(s5p6450_gpio_rbank_4bit2,
ARRAY_SIZE(s5p6450_gpio_rbank_4bit2));
} else {
samsung_gpiolib_add_2bit_chips(s5p6440_gpio_2bit,
ARRAY_SIZE(s5p6440_gpio_2bit));
s5p64x0_gpio_add_rbank_4bit2(s5p6440_gpio_rbank_4bit2,
ARRAY_SIZE(s5p6440_gpio_rbank_4bit2));
samsung_gpiolib_add_4bit_chips(s5p6440_gpio_4bit,
ARRAY_SIZE(s5p6440_gpio_4bit));
samsung_gpiolib_add_4bit2_chips(s5p6440_gpio_4bit2,
ARRAY_SIZE(s5p6440_gpio_4bit2));
s5p64x0_gpio_add_rbank_4bit2(s5p6440_gpio_rbank_4bit2,
ARRAY_SIZE(s5p6440_gpio_rbank_4bit2));
}
return 0;
}
arch_initcall(s5p6440_gpiolib_init);
core_initcall(s5p64x0_gpiolib_init);
......@@ -29,6 +29,9 @@
#define S5P64X0_PA_VIC0 (0xE4000000)
#define S5P64X0_PA_VIC1 (0xE4100000)
#define S5P64X0_PA_SROMC (0xE7000000)
#define S5P_PA_SROMC S5P64X0_PA_SROMC
#define S5P64X0_PA_PDMA (0xE9000000)
#define S5P64X0_PA_TIMER (0xEA000000)
......@@ -63,6 +66,8 @@
#define S5P64X0_PA_HSMMC(x) (0xED800000 + ((x) * 0x100000))
#define S5P64X0_PA_I2S (0xF2000000)
#define S5P6450_PA_I2S1 0xF2800000
#define S5P6450_PA_I2S2 0xF2900000
#define S5P64X0_PA_PCM (0xF2100000)
......
......@@ -15,48 +15,23 @@
#include <mach/map.h>
/* Will be implemented S5P6442 GPIOlib */
/* Base addresses for each of the banks */
#define S5P6440_GPA_BASE (S5P_VA_GPIO + 0x0000)
#define S5P6440_GPB_BASE (S5P_VA_GPIO + 0x0020)
#define S5P6440_GPC_BASE (S5P_VA_GPIO + 0x0040)
#define S5P6440_GPF_BASE (S5P_VA_GPIO + 0x00A0)
#define S5P6440_GPG_BASE (S5P_VA_GPIO + 0x00C0)
#define S5P6440_GPH_BASE (S5P_VA_GPIO + 0x00E0)
#define S5P6440_GPI_BASE (S5P_VA_GPIO + 0x0100)
#define S5P6440_GPJ_BASE (S5P_VA_GPIO + 0x0120)
#define S5P6440_GPN_BASE (S5P_VA_GPIO + 0x0830)
#define S5P6440_GPP_BASE (S5P_VA_GPIO + 0x0160)
#define S5P6440_GPR_BASE (S5P_VA_GPIO + 0x0290)
#define S5P6440_EINT0CON0 (S5P_VA_GPIO + 0x900)
#define S5P6440_EINT0FLTCON0 (S5P_VA_GPIO + 0x910)
#define S5P6440_EINT0FLTCON1 (S5P_VA_GPIO + 0x914)
#define S5P6440_EINT0MASK (S5P_VA_GPIO + 0x920)
#define S5P6440_EINT0PEND (S5P_VA_GPIO + 0x924)
/* for LCD */
#define S5P6440_SPCON_LCD_SEL_RGB (1 << 0)
#define S5P6440_SPCON_LCD_SEL_MASK (3 << 0)
/*
* These set of macros are not really useful for the
* GPF/GPI/GPJ/GPN/GPP, useful for others set of GPIO's (4 bit)
*/
#define S5P6440_GPIO_CONMASK(__gpio) (0xf << ((__gpio) * 4))
#define S5P6440_GPIO_INPUT(__gpio) (0x0 << ((__gpio) * 4))
#define S5P6440_GPIO_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
/*
* Use these macros for GPF/GPI/GPJ/GPN/GPP set of GPIO (2 bit)
*/
#define S5P6440_GPIO2_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
#define S5P6440_GPIO2_INPUT(__gpio) (0x0 << ((__gpio) * 2))
#define S5P6440_GPIO2_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
#define S5P64X0_GPA_BASE (S5P_VA_GPIO + 0x0000)
#define S5P64X0_GPB_BASE (S5P_VA_GPIO + 0x0020)
#define S5P64X0_GPC_BASE (S5P_VA_GPIO + 0x0040)
#define S5P64X0_GPF_BASE (S5P_VA_GPIO + 0x00A0)
#define S5P64X0_GPG_BASE (S5P_VA_GPIO + 0x00C0)
#define S5P64X0_GPH_BASE (S5P_VA_GPIO + 0x00E0)
#define S5P64X0_GPI_BASE (S5P_VA_GPIO + 0x0100)
#define S5P64X0_GPJ_BASE (S5P_VA_GPIO + 0x0120)
#define S5P64X0_GPN_BASE (S5P_VA_GPIO + 0x0830)
#define S5P64X0_GPP_BASE (S5P_VA_GPIO + 0x0160)
#define S5P64X0_GPR_BASE (S5P_VA_GPIO + 0x0290)
#define S5P6450_GPD_BASE (S5P_VA_GPIO + 0x0060)
#define S5P6450_GPK_BASE (S5P_VA_GPIO + 0x0140)
#define S5P6450_GPQ_BASE (S5P_VA_GPIO + 0x0180)
#define S5P6450_GPS_BASE (S5P_VA_GPIO + 0x0300)
#endif /* __ASM_ARCH_REGS_GPIO_H */
......@@ -117,6 +117,7 @@ static struct s3c2410_platform_i2c s5p6440_i2c1_data __initdata = {
static struct i2c_board_info smdk6440_i2c_devs0[] __initdata = {
{ I2C_BOARD_INFO("24c08", 0x50), },
{ I2C_BOARD_INFO("wm8580", 0x1b), },
};
static struct i2c_board_info smdk6440_i2c_devs1[] __initdata = {
......
......@@ -135,6 +135,7 @@ static struct s3c2410_platform_i2c s5p6450_i2c1_data __initdata = {
};
static struct i2c_board_info smdk6450_i2c_devs0[] __initdata = {
{ I2C_BOARD_INFO("wm8580", 0x1b), },
{ I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung KS24C080C EEPROM */
};
......
......@@ -396,7 +396,7 @@ static int s5pc100_sclk1_ctrl(struct clk *clk, int enable)
* recommended to keep the following clocks disabled until the driver requests
* for enabling the clock.
*/
static struct clk init_clocks_disable[] = {
static struct clk init_clocks_off[] = {
{
.name = "cssys",
.id = -1,
......@@ -1381,8 +1381,6 @@ static struct clk *clks[] __initdata = {
void __init s5pc100_register_clocks(void)
{
struct clk *clkp;
int ret;
int ptr;
s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
......@@ -1393,16 +1391,8 @@ void __init s5pc100_register_clocks(void)
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
clkp = init_clocks_disable;
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
ret = s3c24xx_register_clock(clkp);
if (ret < 0) {
printk(KERN_ERR "Failed to register clock %s (%d)\n",
clkp->name, ret);
}
(clkp->enable)(clkp, 0);
}
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_pwmclk_init();
}
......@@ -23,17 +23,14 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev)
{
/* configure GPIO for i2s port */
switch (pdev->id) {
case 0: /* Dedicated pins */
break;
case 1:
s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2));
break;
case 2:
s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4));
break;
case -1: /* Dedicated pins */
break;
default:
printk(KERN_ERR "Invalid Device %d\n", pdev->id);
return -EINVAL;
......@@ -42,8 +39,20 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev)
return 0;
}
static struct s3c_audio_pdata s3c_i2s_pdata = {
static const char *rclksrc_v5[] = {
[0] = "iis",
[1] = "i2sclkd2",
};
static struct s3c_audio_pdata i2sv5_pdata = {
.cfg_gpio = s5pc100_cfg_i2s,
.type = {
.i2s = {
.quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
| QUIRK_NEED_RSTCLR,
.src_clk = rclksrc_v5,
},
},
};
static struct resource s5pc100_iis0_resource[] = {
......@@ -62,15 +71,34 @@ static struct resource s5pc100_iis0_resource[] = {
.end = DMACH_I2S0_RX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = DMACH_I2S0S_TX,
.end = DMACH_I2S0S_TX,
.flags = IORESOURCE_DMA,
},
};
struct platform_device s5pc100_device_iis0 = {
.name = "s3c64xx-iis-v4",
.id = -1,
.name = "samsung-i2s",
.id = 0,
.num_resources = ARRAY_SIZE(s5pc100_iis0_resource),
.resource = s5pc100_iis0_resource,
.dev = {
.platform_data = &s3c_i2s_pdata,
.platform_data = &i2sv5_pdata,
},
};
static const char *rclksrc_v3[] = {
[0] = "iis",
[1] = "sclk_audio",
};
static struct s3c_audio_pdata i2sv3_pdata = {
.cfg_gpio = s5pc100_cfg_i2s,
.type = {
.i2s = {
.src_clk = rclksrc_v3,
},
},
};
......@@ -93,12 +121,12 @@ static struct resource s5pc100_iis1_resource[] = {
};
struct platform_device s5pc100_device_iis1 = {
.name = "s3c64xx-iis",
.name = "samsung-i2s",
.id = 1,
.num_resources = ARRAY_SIZE(s5pc100_iis1_resource),
.resource = s5pc100_iis1_resource,
.dev = {
.platform_data = &s3c_i2s_pdata,
.platform_data = &i2sv3_pdata,
},
};
......@@ -121,12 +149,12 @@ static struct resource s5pc100_iis2_resource[] = {
};
struct platform_device s5pc100_device_iis2 = {
.name = "s3c64xx-iis",
.name = "samsung-i2s",
.id = 2,
.num_resources = ARRAY_SIZE(s5pc100_iis2_resource),
.resource = s5pc100_iis2_resource,
.dev = {
.platform_data = &s3c_i2s_pdata,
.platform_data = &i2sv3_pdata,
},
};
......
......@@ -55,6 +55,8 @@
#define S5PC100_VA_VIC_OFFSET 0x10000
#define S5PC1XX_VA_VIC(x) (S5PC100_VA_VIC + ((x) * S5PC100_VA_VIC_OFFSET))
#define S5PC100_PA_SROMC (0xE7000000)
#define S5P_PA_SROMC S5PC100_PA_SROMC
#define S5PC100_PA_ONENAND (0xE7100000)
......
......@@ -118,6 +118,7 @@ menu "S5PV210 Machines"
config MACH_SMDKV210
bool "SMDKV210"
select CPU_S5PV210
select S3C_DEV_FB
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
......@@ -130,6 +131,7 @@ config MACH_SMDKV210
select SAMSUNG_DEV_IDE
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_TS
select S5PV210_SETUP_FB_24BPP
select S5PV210_SETUP_I2C1
select S5PV210_SETUP_I2C2
select S5PV210_SETUP_IDE
......
......@@ -309,7 +309,7 @@ static struct clk_ops clk_fout_apll_ops = {
.get_rate = s5pv210_clk_fout_apll_get_rate,
};
static struct clk init_clocks_disable[] = {
static struct clk init_clocks_off[] = {
{
.name = "pdma",
.id = 0,
......@@ -467,20 +467,20 @@ static struct clk init_clocks_disable[] = {
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1<<21),
}, {
.name = "i2s_v50",
.name = "iis",
.id = 0,
.parent = &clk_p,
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1<<4),
}, {
.name = "i2s_v32",
.id = 0,
.name = "iis",
.id = 1,
.parent = &clk_p,
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1 << 5),
}, {
.name = "i2s_v32",
.id = 1,
.name = "iis",
.id = 2,
.parent = &clk_p,
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1 << 6),
......@@ -525,6 +525,12 @@ static struct clk init_clocks[] = {
.parent = &clk_pclk_psys.clk,
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1 << 20),
}, {
.name = "sromc",
.id = -1,
.parent = &clk_hclk_psys.clk,
.enable = s5pv210_clk_ip1_ctrl,
.ctrlbit = (1 << 26),
},
};
......@@ -1220,13 +1226,9 @@ static struct clk *clks[] __initdata = {
void __init s5pv210_register_clocks(void)
{
struct clk *clkp;
int ret;
int ptr;
ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
if (ret > 0)
printk(KERN_ERR "Failed to register %u clocks\n", ret);
s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
s3c_register_clksrc(sysclks[ptr], 1);
......@@ -1234,15 +1236,8 @@ void __init s5pv210_register_clocks(void)
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
clkp = init_clocks_disable;
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
ret = s3c24xx_register_clock(clkp);
if (ret < 0) {
printk(KERN_ERR "Failed to register clock %s (%d)\n",
clkp->name, ret);
}
(clkp->enable)(clkp, 0);
}
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_pwmclk_init();
}
......@@ -80,11 +80,6 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
.pfn = __phys_to_pfn(S3C_PA_UART),
.length = SZ_512K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_SROMC,
.pfn = __phys_to_pfn(S5PV210_PA_SROMC),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_DMC0,
.pfn = __phys_to_pfn(S5PV210_PA_DMC0),
......
......@@ -19,22 +19,24 @@
#include <mach/dma.h>
#include <mach/irqs.h>
static const char *rclksrc[] = {
[0] = "busclk",
[1] = "i2sclk",
};
static int s5pv210_cfg_i2s(struct platform_device *pdev)
{
/* configure GPIO for i2s port */
switch (pdev->id) {
case 0:
s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2));
break;
case 1:
s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2));
break;
case 2:
s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4));
break;
case -1:
s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2));
break;
default:
printk(KERN_ERR "Invalid Device %d\n", pdev->id);
return -EINVAL;
......@@ -43,8 +45,15 @@ static int s5pv210_cfg_i2s(struct platform_device *pdev)
return 0;
}
static struct s3c_audio_pdata s3c_i2s_pdata = {
static struct s3c_audio_pdata i2sv5_pdata = {
.cfg_gpio = s5pv210_cfg_i2s,
.type = {
.i2s = {
.quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
| QUIRK_NEED_RSTCLR,
.src_clk = rclksrc,
},
},
};
static struct resource s5pv210_iis0_resource[] = {
......@@ -63,15 +72,34 @@ static struct resource s5pv210_iis0_resource[] = {
.end = DMACH_I2S0_RX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = DMACH_I2S0S_TX,
.end = DMACH_I2S0S_TX,
.flags = IORESOURCE_DMA,
},
};
struct platform_device s5pv210_device_iis0 = {
.name = "s3c64xx-iis-v4",
.id = -1,
.name = "samsung-i2s",
.id = 0,
.num_resources = ARRAY_SIZE(s5pv210_iis0_resource),
.resource = s5pv210_iis0_resource,
.dev = {
.platform_data = &s3c_i2s_pdata,
.platform_data = &i2sv5_pdata,
},
};
static const char *rclksrc_v3[] = {
[0] = "iis",
[1] = "audio-bus",
};
static struct s3c_audio_pdata i2sv3_pdata = {
.cfg_gpio = s5pv210_cfg_i2s,
.type = {
.i2s = {
.src_clk = rclksrc_v3,
},
},
};
......@@ -94,12 +122,12 @@ static struct resource s5pv210_iis1_resource[] = {
};
struct platform_device s5pv210_device_iis1 = {
.name = "s3c64xx-iis",
.name = "samsung-i2s",
.id = 1,
.num_resources = ARRAY_SIZE(s5pv210_iis1_resource),
.resource = s5pv210_iis1_resource,
.dev = {
.platform_data = &s3c_i2s_pdata,
.platform_data = &i2sv3_pdata,
},
};
......@@ -122,12 +150,12 @@ static struct resource s5pv210_iis2_resource[] = {
};
struct platform_device s5pv210_device_iis2 = {
.name = "s3c64xx-iis",
.name = "samsung-i2s",
.id = 2,
.num_resources = ARRAY_SIZE(s5pv210_iis2_resource),
.resource = s5pv210_iis2_resource,
.dev = {
.platform_data = &s3c_i2s_pdata,
.platform_data = &i2sv3_pdata,
},
};
......
......@@ -65,7 +65,7 @@
#define IRQ_HSMMC0 S5P_IRQ_VIC1(26)
#define IRQ_HSMMC1 S5P_IRQ_VIC1(27)
#define IRQ_HSMMC2 S5P_IRQ_VIC1(28)
#define IRQ_MIPICSI S5P_IRQ_VIC1(29)
#define IRQ_MIPI_CSIS S5P_IRQ_VIC1(29)
#define IRQ_MIPIDSI S5P_IRQ_VIC1(30)
#define IRQ_ONENAND_AUDI S5P_IRQ_VIC1(31)
......@@ -132,5 +132,6 @@
#define IRQ_LCD_FIFO IRQ_LCD0
#define IRQ_LCD_VSYNC IRQ_LCD1
#define IRQ_LCD_SYSTEM IRQ_LCD2
#define IRQ_MIPI_CSIS0 IRQ_MIPI_CSIS
#endif /* ASM_ARCH_IRQS_H */
......@@ -16,6 +16,8 @@
#include <plat/map-base.h>
#include <plat/map-s5p.h>
#define S5PV210_PA_SROM_BANK5 (0xA8000000)
#define S5PC110_PA_ONENAND (0xB0000000)
#define S5P_PA_ONENAND S5PC110_PA_ONENAND
......@@ -60,6 +62,7 @@
#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
#define S5PV210_PA_SROMC (0xE8000000)
#define S5P_PA_SROMC S5PV210_PA_SROMC
#define S5PV210_PA_CFCON (0xE8200000)
......@@ -107,6 +110,8 @@
#define S5PV210_PA_DMC0 (0xF0000000)
#define S5PV210_PA_DMC1 (0xF1400000)
#define S5PV210_PA_MIPI_CSIS 0xFA600000
/* compatibiltiy defines. */
#define S3C_PA_UART S5PV210_PA_UART
#define S3C_PA_HSMMC0 S5PV210_PA_HSMMC(0)
......@@ -123,6 +128,7 @@
#define S5P_PA_FIMC0 S5PV210_PA_FIMC0
#define S5P_PA_FIMC1 S5PV210_PA_FIMC1
#define S5P_PA_FIMC2 S5PV210_PA_FIMC2
#define S5P_PA_MIPI_CSIS0 S5PV210_PA_MIPI_CSIS
#define SAMSUNG_PA_ADC S5PV210_PA_ADC
#define SAMSUNG_PA_CFCON S5PV210_PA_CFCON
......
......@@ -161,7 +161,7 @@
#define S5P_MDNIE_SEL S5P_CLKREG(0x7008)
#define S5P_MIPI_PHY_CON0 S5P_CLKREG(0x7200)
#define S5P_MIPI_PHY_CON1 S5P_CLKREG(0x7204)
#define S5P_MIPI_CONTROL S5P_CLKREG(0xE814)
#define S5P_MIPI_DPHY_CONTROL S5P_CLKREG(0xE814)
#define S5P_IDLE_CFG_TL_MASK (3 << 30)
#define S5P_IDLE_CFG_TM_MASK (3 << 28)
......@@ -195,9 +195,6 @@
#define S5P_OTHERS_RET_UART (1 << 28)
#define S5P_OTHERS_USB_SIG_MASK (1 << 16)
/* MIPI */
#define S5P_MIPI_DPHY_EN (3)
/* S5P_DAC_CONTROL */
#define S5P_DAC_ENABLE (1)
#define S5P_DAC_DISABLE (0)
......
......@@ -94,6 +94,7 @@ static struct platform_device *smdkc110_devices[] __initdata = {
static struct i2c_board_info smdkc110_i2c_devs0[] __initdata = {
{ I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */
{ I2C_BOARD_INFO("wm8580", 0x1b), },
};
static struct i2c_board_info smdkc110_i2c_devs1[] __initdata = {
......
......@@ -14,16 +14,25 @@
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/sysdev.h>
#include <linux/dm9000.h>
#include <linux/fb.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <video/platform_lcd.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-fb.h>
#include <plat/regs-serial.h>
#include <plat/regs-srom.h>
#include <plat/gpio-cfg.h>
#include <plat/s5pv210.h>
#include <plat/devs.h>
#include <plat/cpu.h>
......@@ -33,6 +42,7 @@
#include <plat/iic.h>
#include <plat/keypad.h>
#include <plat/pm.h>
#include <plat/fb.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
......@@ -102,12 +112,106 @@ static struct samsung_keypad_platdata smdkv210_keypad_data __initdata = {
.cols = 8,
};
static struct resource smdkv210_dm9000_resources[] = {
[0] = {
.start = S5PV210_PA_SROM_BANK5,
.end = S5PV210_PA_SROM_BANK5,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = S5PV210_PA_SROM_BANK5 + 2,
.end = S5PV210_PA_SROM_BANK5 + 2,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = IRQ_EINT(9),
.end = IRQ_EINT(9),
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
},
};
static struct dm9000_plat_data smdkv210_dm9000_platdata = {
.flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM,
.dev_addr = { 0x00, 0x09, 0xc0, 0xff, 0xec, 0x48 },
};
struct platform_device smdkv210_dm9000 = {
.name = "dm9000",
.id = -1,
.num_resources = ARRAY_SIZE(smdkv210_dm9000_resources),
.resource = smdkv210_dm9000_resources,
.dev = {
.platform_data = &smdkv210_dm9000_platdata,
},
};
static void smdkv210_lte480wv_set_power(struct plat_lcd_data *pd,
unsigned int power)
{
if (power) {
#if !defined(CONFIG_BACKLIGHT_PWM)
gpio_request(S5PV210_GPD0(3), "GPD0");
gpio_direction_output(S5PV210_GPD0(3), 1);
gpio_free(S5PV210_GPD0(3));
#endif
/* fire nRESET on power up */
gpio_request(S5PV210_GPH0(6), "GPH0");
gpio_direction_output(S5PV210_GPH0(6), 1);
gpio_set_value(S5PV210_GPH0(6), 0);
mdelay(10);
gpio_set_value(S5PV210_GPH0(6), 1);
mdelay(10);
gpio_free(S5PV210_GPH0(6));
} else {
#if !defined(CONFIG_BACKLIGHT_PWM)
gpio_request(S5PV210_GPD0(3), "GPD0");
gpio_direction_output(S5PV210_GPD0(3), 0);
gpio_free(S5PV210_GPD0(3));
#endif
}
}
static struct plat_lcd_data smdkv210_lcd_lte480wv_data = {
.set_power = smdkv210_lte480wv_set_power,
};
static struct platform_device smdkv210_lcd_lte480wv = {
.name = "platform-lcd",
.dev.parent = &s3c_device_fb.dev,
.dev.platform_data = &smdkv210_lcd_lte480wv_data,
};
static struct s3c_fb_pd_win smdkv210_fb_win0 = {
.win_mode = {
.left_margin = 13,
.right_margin = 8,
.upper_margin = 7,
.lower_margin = 5,
.hsync_len = 3,
.vsync_len = 1,
.xres = 800,
.yres = 480,
},
.max_bpp = 32,
.default_bpp = 24,
};
static struct s3c_fb_platdata smdkv210_lcd0_pdata __initdata = {
.win[0] = &smdkv210_fb_win0,
.vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
.vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
.setup_gpio = s5pv210_fb_gpio_setup_24bpp,
};
static struct platform_device *smdkv210_devices[] __initdata = {
&s5pv210_device_iis0,
&s5pv210_device_ac97,
&s5pv210_device_spdif,
&s3c_device_adc,
&s3c_device_cfcon,
&s3c_device_fb,
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&s3c_device_hsmmc2,
......@@ -115,14 +219,37 @@ static struct platform_device *smdkv210_devices[] __initdata = {
&s3c_device_i2c0,
&s3c_device_i2c1,
&s3c_device_i2c2,
&samsung_device_keypad,
&s3c_device_rtc,
&s3c_device_ts,
&s3c_device_wdt,
&s5pv210_device_ac97,
&s5pv210_device_iis0,
&s5pv210_device_spdif,
&samsung_device_keypad,
&smdkv210_dm9000,
&smdkv210_lcd_lte480wv,
};
static void __init smdkv210_dm9000_init(void)
{
unsigned int tmp;
gpio_request(S5PV210_MP01(5), "nCS5");
s3c_gpio_cfgpin(S5PV210_MP01(5), S3C_GPIO_SFN(2));
gpio_free(S5PV210_MP01(5));
tmp = (5 << S5P_SROM_BCX__TACC__SHIFT);
__raw_writel(tmp, S5P_SROM_BC5);
tmp = __raw_readl(S5P_SROM_BW);
tmp &= (S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS5__SHIFT);
tmp |= (1 << S5P_SROM_BW__NCS5__SHIFT);
__raw_writel(tmp, S5P_SROM_BW);
}
static struct i2c_board_info smdkv210_i2c_devs0[] __initdata = {
{ I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */
{ I2C_BOARD_INFO("wm8580", 0x1b), },
};
static struct i2c_board_info smdkv210_i2c_devs1[] __initdata = {
......@@ -150,6 +277,8 @@ static void __init smdkv210_machine_init(void)
{
s3c_pm_init();
smdkv210_dm9000_init();
samsung_keypad_set_platdata(&smdkv210_keypad_data);
s3c24xx_ts_set_platdata(&s3c_ts_platform);
......@@ -165,6 +294,8 @@ static void __init smdkv210_machine_init(void)
s3c_ide_set_platdata(&smdkv210_ide_pdata);
s3c_fb_set_platdata(&smdkv210_lcd0_pdata);
platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices));
}
......
......@@ -11,9 +11,15 @@ if ARCH_S5PV310
config CPU_S5PV310
bool
select S3C_PL330_DMA
help
Enable S5PV310 CPU support
config S5PV310_DEV_PD
bool
help
Compile in platform device definitions for Power Domain
config S5PV310_SETUP_I2C1
bool
help
......@@ -60,6 +66,11 @@ config S5PV310_SETUP_SDHCI_GPIO
help
Common setup code for SDHCI gpio.
config S5PV310_DEV_SYSMMU
bool
help
Common setup code for SYSTEM MMU in S5PV310
# machine support
menu "S5PC210 Machines"
......@@ -69,11 +80,15 @@ config MACH_SMDKC210
select CPU_S5PV310
select S3C_DEV_RTC
select S3C_DEV_WDT
select S3C_DEV_I2C1
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3
select S5PV310_DEV_PD
select S5PV310_SETUP_I2C1
select S5PV310_SETUP_SDHCI
select S5PV310_DEV_SYSMMU
help
Machine support for Samsung SMDKC210
S5PC210(MCP) is one of package option of S5PV310
......@@ -82,6 +97,10 @@ config MACH_UNIVERSAL_C210
bool "Mobile UNIVERSAL_C210 Board"
select CPU_S5PV310
select S5P_DEV_ONENAND
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3
select S5PV310_SETUP_SDHCI
select S3C_DEV_I2C1
select S5PV310_SETUP_I2C1
help
......@@ -97,10 +116,13 @@ config MACH_SMDKV310
select CPU_S5PV310
select S3C_DEV_RTC
select S3C_DEV_WDT
select S3C_DEV_I2C1
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3
select S5PV310_DEV_PD
select S5PV310_SETUP_I2C1
select S5PV310_SETUP_SDHCI
help
Machine support for Samsung SMDKV310
......
......@@ -13,7 +13,8 @@ obj- :=
# Core support for S5PV310 system
obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o
obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o
obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o dma.o
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
......@@ -27,6 +28,10 @@ obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o
# device support
obj-y += dev-audio.o
obj-$(CONFIG_S5PV310_DEV_PD) += dev-pd.o
obj-$(CONFIG_S5PV310_DEV_SYSMMU) += dev-sysmmu.o
obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o
obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o
obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o
......
......@@ -244,7 +244,7 @@ static struct clksrc_clk clk_mout_corebus = {
.id = -1,
},
.sources = &clkset_mout_corebus,
.reg_src = { .reg = S5P_CLKSRC_CORE, .shift = 4, .size = 1 },
.reg_src = { .reg = S5P_CLKSRC_DMC, .shift = 4, .size = 1 },
};
static struct clksrc_clk clk_sclk_dmc = {
......@@ -253,7 +253,7 @@ static struct clksrc_clk clk_sclk_dmc = {
.id = -1,
.parent = &clk_mout_corebus.clk,
},
.reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 12, .size = 3 },
.reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 12, .size = 3 },
};
static struct clksrc_clk clk_aclk_cored = {
......@@ -262,7 +262,7 @@ static struct clksrc_clk clk_aclk_cored = {
.id = -1,
.parent = &clk_sclk_dmc.clk,
},
.reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 16, .size = 3 },
.reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 16, .size = 3 },
};
static struct clksrc_clk clk_aclk_corep = {
......@@ -271,7 +271,7 @@ static struct clksrc_clk clk_aclk_corep = {
.id = -1,
.parent = &clk_aclk_cored.clk,
},
.reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 20, .size = 3 },
.reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 20, .size = 3 },
};
static struct clksrc_clk clk_aclk_acp = {
......@@ -280,7 +280,7 @@ static struct clksrc_clk clk_aclk_acp = {
.id = -1,
.parent = &clk_mout_corebus.clk,
},
.reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 0, .size = 3 },
.reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 0, .size = 3 },
};
static struct clksrc_clk clk_pclk_acp = {
......@@ -289,7 +289,7 @@ static struct clksrc_clk clk_pclk_acp = {
.id = -1,
.parent = &clk_aclk_acp.clk,
},
.reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 4, .size = 3 },
.reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 4, .size = 3 },
};
/* Core list of CMU_TOP side */
......@@ -384,7 +384,7 @@ static struct clksrc_clk clk_sclk_vpll = {
.reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 },
};
static struct clk init_clocks_disable[] = {
static struct clk init_clocks_off[] = {
{
.name = "timers",
.id = -1,
......@@ -466,6 +466,16 @@ static struct clk init_clocks_disable[] = {
.id = -1,
.enable = s5pv310_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 10),
}, {
.name = "pdma",
.id = 0,
.enable = s5pv310_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 0),
}, {
.name = "pdma",
.id = 1,
.enable = s5pv310_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 1),
}, {
.name = "adc",
.id = -1,
......@@ -506,6 +516,26 @@ static struct clk init_clocks_disable[] = {
.id = 2,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 18),
}, {
.name = "iis",
.id = 0,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 19),
}, {
.name = "iis",
.id = 1,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 20),
}, {
.name = "iis",
.id = 2,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 21),
}, {
.name = "ac97",
.id = -1,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 27),
}, {
.name = "fimg2d",
.id = -1,
......@@ -990,6 +1020,17 @@ static struct clksrc_clk *sysclks[] = {
&clk_dout_mmc4,
};
static int xtal_rate;
static unsigned long s5pv310_fout_apll_get_rate(struct clk *clk)
{
return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0), pll_4508);
}
static struct clk_ops s5pv310_fout_apll_ops = {
.get_rate = s5pv310_fout_apll_get_rate,
};
void __init_or_cpufreq s5pv310_setup_clocks(void)
{
struct clk *xtal_clk;
......@@ -1013,6 +1054,9 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
BUG_ON(IS_ERR(xtal_clk));
xtal = clk_get_rate(xtal_clk);
xtal_rate = xtal;
clk_put(xtal_clk);
printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
......@@ -1026,7 +1070,7 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
__raw_readl(S5P_VPLL_CON1), pll_4650);
clk_fout_apll.rate = apll;
clk_fout_apll.ops = &s5pv310_fout_apll_ops;
clk_fout_mpll.rate = mpll;
clk_fout_epll.rate = epll;
clk_fout_vpll.rate = vpll;
......@@ -1061,13 +1105,9 @@ static struct clk *clks[] __initdata = {
void __init s5pv310_register_clocks(void)
{
struct clk *clkp;
int ret;
int ptr;
ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
if (ret > 0)
printk(KERN_ERR "Failed to register %u clocks\n", ret);
s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
s3c_register_clksrc(sysclks[ptr], 1);
......@@ -1075,15 +1115,8 @@ void __init s5pv310_register_clocks(void)
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
clkp = init_clocks_disable;
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
ret = s3c24xx_register_clock(clkp);
if (ret < 0) {
printk(KERN_ERR "Failed to register clock %s (%d)\n",
clkp->name, ret);
}
(clkp->enable)(clkp, 0);
}
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_pwmclk_init();
}
......@@ -40,6 +40,11 @@ static struct map_desc s5pv310_iodesc[] __initdata = {
.pfn = __phys_to_pfn(S5PV310_PA_CMU),
.length = SZ_128K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_PMU,
.pfn = __phys_to_pfn(S5PV310_PA_PMU),
.length = SZ_64K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_COMBINER_BASE,
.pfn = __phys_to_pfn(S5PV310_PA_COMBINER),
......@@ -70,6 +75,11 @@ static struct map_desc s5pv310_iodesc[] __initdata = {
.pfn = __phys_to_pfn(S5PV310_PA_GPIO3),
.length = SZ_256,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_DMC0,
.pfn = __phys_to_pfn(S5PV310_PA_DMC0),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C_VA_UART,
.pfn = __phys_to_pfn(S3C_PA_UART),
......@@ -123,6 +133,15 @@ void __init s5pv310_init_irq(void)
gic_init(0, IRQ_LOCALTIMER, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
/*
* From SPI(0) to SPI(39) and SPI(51), SPI(53) are
* connected to the interrupt combiner. These irqs
* should be initialized to support cascade interrupt.
*/
if ((irq >= 40) && !(irq == 51) && !(irq == 53))
continue;
combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
COMBINER_IRQ(irq, 0));
combiner_cascade_irq(irq, IRQ_SPI(irq));
......@@ -164,7 +183,7 @@ static int __init s5pv310_l2x0_cache_init(void)
__raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
S5P_VA_L2CC + L2X0_POWER_CTRL);
l2x0_init(S5P_VA_L2CC, 0x7C070001, 0xC200ffff);
l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff);
return 0;
}
......
/* linux/arch/arm/mach-s5pv310/cpufreq.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S5PV310 - CPU frequency scaling 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/types.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/regulator/consumer.h>
#include <linux/cpufreq.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-mem.h>
#include <plat/clock.h>
#include <plat/pm.h>
static struct clk *cpu_clk;
static struct clk *moutcore;
static struct clk *mout_mpll;
static struct clk *mout_apll;
#ifdef CONFIG_REGULATOR
static struct regulator *arm_regulator;
static struct regulator *int_regulator;
#endif
static struct cpufreq_freqs freqs;
static unsigned int memtype;
enum s5pv310_memory_type {
DDR2 = 4,
LPDDR2,
DDR3,
};
enum cpufreq_level_index {
L0, L1, L2, L3, CPUFREQ_LEVEL_END,
};
static struct cpufreq_frequency_table s5pv310_freq_table[] = {
{L0, 1000*1000},
{L1, 800*1000},
{L2, 400*1000},
{L3, 100*1000},
{0, CPUFREQ_TABLE_END},
};
static unsigned int clkdiv_cpu0[CPUFREQ_LEVEL_END][7] = {
/*
* Clock divider value for following
* { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH,
* DIVATB, DIVPCLK_DBG, DIVAPLL }
*/
/* ARM L0: 1000MHz */
{ 0, 3, 7, 3, 3, 0, 1 },
/* ARM L1: 800MHz */
{ 0, 3, 7, 3, 3, 0, 1 },
/* ARM L2: 400MHz */
{ 0, 1, 3, 1, 3, 0, 1 },
/* ARM L3: 100MHz */
{ 0, 0, 1, 0, 3, 1, 1 },
};
static unsigned int clkdiv_cpu1[CPUFREQ_LEVEL_END][2] = {
/*
* Clock divider value for following
* { DIVCOPY, DIVHPM }
*/
/* ARM L0: 1000MHz */
{ 3, 0 },
/* ARM L1: 800MHz */
{ 3, 0 },
/* ARM L2: 400MHz */
{ 3, 0 },
/* ARM L3: 100MHz */
{ 3, 0 },
};
static unsigned int clkdiv_dmc0[CPUFREQ_LEVEL_END][8] = {
/*
* Clock divider value for following
* { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
* DIVDMCP, DIVCOPY2, DIVCORE_TIMERS }
*/
/* DMC L0: 400MHz */
{ 3, 1, 1, 1, 1, 1, 3, 1 },
/* DMC L1: 400MHz */
{ 3, 1, 1, 1, 1, 1, 3, 1 },
/* DMC L2: 266.7MHz */
{ 7, 1, 1, 2, 1, 1, 3, 1 },
/* DMC L3: 200MHz */
{ 7, 1, 1, 3, 1, 1, 3, 1 },
};
static unsigned int clkdiv_top[CPUFREQ_LEVEL_END][5] = {
/*
* Clock divider value for following
* { DIVACLK200, DIVACLK100, DIVACLK160, DIVACLK133, DIVONENAND }
*/
/* ACLK200 L0: 200MHz */
{ 3, 7, 4, 5, 1 },
/* ACLK200 L1: 200MHz */
{ 3, 7, 4, 5, 1 },
/* ACLK200 L2: 160MHz */
{ 4, 7, 5, 7, 1 },
/* ACLK200 L3: 133.3MHz */
{ 5, 7, 7, 7, 1 },
};
static unsigned int clkdiv_lr_bus[CPUFREQ_LEVEL_END][2] = {
/*
* Clock divider value for following
* { DIVGDL/R, DIVGPL/R }
*/
/* ACLK_GDL/R L0: 200MHz */
{ 3, 1 },
/* ACLK_GDL/R L1: 200MHz */
{ 3, 1 },
/* ACLK_GDL/R L2: 160MHz */
{ 4, 1 },
/* ACLK_GDL/R L3: 133.3MHz */
{ 5, 1 },
};
struct cpufreq_voltage_table {
unsigned int index; /* any */
unsigned int arm_volt; /* uV */
unsigned int int_volt;
};
static struct cpufreq_voltage_table s5pv310_volt_table[CPUFREQ_LEVEL_END] = {
{
.index = L0,
.arm_volt = 1200000,
.int_volt = 1100000,
}, {
.index = L1,
.arm_volt = 1100000,
.int_volt = 1100000,
}, {
.index = L2,
.arm_volt = 1000000,
.int_volt = 1000000,
}, {
.index = L3,
.arm_volt = 900000,
.int_volt = 1000000,
},
};
static unsigned int s5pv310_apll_pms_table[CPUFREQ_LEVEL_END] = {
/* APLL FOUT L0: 1000MHz */
((250 << 16) | (6 << 8) | 1),
/* APLL FOUT L1: 800MHz */
((200 << 16) | (6 << 8) | 1),
/* APLL FOUT L2 : 400MHz */
((200 << 16) | (6 << 8) | 2),
/* APLL FOUT L3: 100MHz */
((200 << 16) | (6 << 8) | 4),
};
int s5pv310_verify_speed(struct cpufreq_policy *policy)
{
return cpufreq_frequency_table_verify(policy, s5pv310_freq_table);
}
unsigned int s5pv310_getspeed(unsigned int cpu)
{
return clk_get_rate(cpu_clk) / 1000;
}
void s5pv310_set_clkdiv(unsigned int div_index)
{
unsigned int tmp;
/* Change Divider - CPU0 */
tmp = __raw_readl(S5P_CLKDIV_CPU);
tmp &= ~(S5P_CLKDIV_CPU0_CORE_MASK | S5P_CLKDIV_CPU0_COREM0_MASK |
S5P_CLKDIV_CPU0_COREM1_MASK | S5P_CLKDIV_CPU0_PERIPH_MASK |
S5P_CLKDIV_CPU0_ATB_MASK | S5P_CLKDIV_CPU0_PCLKDBG_MASK |
S5P_CLKDIV_CPU0_APLL_MASK);
tmp |= ((clkdiv_cpu0[div_index][0] << S5P_CLKDIV_CPU0_CORE_SHIFT) |
(clkdiv_cpu0[div_index][1] << S5P_CLKDIV_CPU0_COREM0_SHIFT) |
(clkdiv_cpu0[div_index][2] << S5P_CLKDIV_CPU0_COREM1_SHIFT) |
(clkdiv_cpu0[div_index][3] << S5P_CLKDIV_CPU0_PERIPH_SHIFT) |
(clkdiv_cpu0[div_index][4] << S5P_CLKDIV_CPU0_ATB_SHIFT) |
(clkdiv_cpu0[div_index][5] << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT) |
(clkdiv_cpu0[div_index][6] << S5P_CLKDIV_CPU0_APLL_SHIFT));
__raw_writel(tmp, S5P_CLKDIV_CPU);
do {
tmp = __raw_readl(S5P_CLKDIV_STATCPU);
} while (tmp & 0x1111111);
/* Change Divider - CPU1 */
tmp = __raw_readl(S5P_CLKDIV_CPU1);
tmp &= ~((0x7 << 4) | 0x7);
tmp |= ((clkdiv_cpu1[div_index][0] << 4) |
(clkdiv_cpu1[div_index][1] << 0));
__raw_writel(tmp, S5P_CLKDIV_CPU1);
do {
tmp = __raw_readl(S5P_CLKDIV_STATCPU1);
} while (tmp & 0x11);
/* Change Divider - DMC0 */
tmp = __raw_readl(S5P_CLKDIV_DMC0);
tmp &= ~(S5P_CLKDIV_DMC0_ACP_MASK | S5P_CLKDIV_DMC0_ACPPCLK_MASK |
S5P_CLKDIV_DMC0_DPHY_MASK | S5P_CLKDIV_DMC0_DMC_MASK |
S5P_CLKDIV_DMC0_DMCD_MASK | S5P_CLKDIV_DMC0_DMCP_MASK |
S5P_CLKDIV_DMC0_COPY2_MASK | S5P_CLKDIV_DMC0_CORETI_MASK);
tmp |= ((clkdiv_dmc0[div_index][0] << S5P_CLKDIV_DMC0_ACP_SHIFT) |
(clkdiv_dmc0[div_index][1] << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT) |
(clkdiv_dmc0[div_index][2] << S5P_CLKDIV_DMC0_DPHY_SHIFT) |
(clkdiv_dmc0[div_index][3] << S5P_CLKDIV_DMC0_DMC_SHIFT) |
(clkdiv_dmc0[div_index][4] << S5P_CLKDIV_DMC0_DMCD_SHIFT) |
(clkdiv_dmc0[div_index][5] << S5P_CLKDIV_DMC0_DMCP_SHIFT) |
(clkdiv_dmc0[div_index][6] << S5P_CLKDIV_DMC0_COPY2_SHIFT) |
(clkdiv_dmc0[div_index][7] << S5P_CLKDIV_DMC0_CORETI_SHIFT));
__raw_writel(tmp, S5P_CLKDIV_DMC0);
do {
tmp = __raw_readl(S5P_CLKDIV_STAT_DMC0);
} while (tmp & 0x11111111);
/* Change Divider - TOP */
tmp = __raw_readl(S5P_CLKDIV_TOP);
tmp &= ~(S5P_CLKDIV_TOP_ACLK200_MASK | S5P_CLKDIV_TOP_ACLK100_MASK |
S5P_CLKDIV_TOP_ACLK160_MASK | S5P_CLKDIV_TOP_ACLK133_MASK |
S5P_CLKDIV_TOP_ONENAND_MASK);
tmp |= ((clkdiv_top[div_index][0] << S5P_CLKDIV_TOP_ACLK200_SHIFT) |
(clkdiv_top[div_index][1] << S5P_CLKDIV_TOP_ACLK100_SHIFT) |
(clkdiv_top[div_index][2] << S5P_CLKDIV_TOP_ACLK160_SHIFT) |
(clkdiv_top[div_index][3] << S5P_CLKDIV_TOP_ACLK133_SHIFT) |
(clkdiv_top[div_index][4] << S5P_CLKDIV_TOP_ONENAND_SHIFT));
__raw_writel(tmp, S5P_CLKDIV_TOP);
do {
tmp = __raw_readl(S5P_CLKDIV_STAT_TOP);
} while (tmp & 0x11111);
/* Change Divider - LEFTBUS */
tmp = __raw_readl(S5P_CLKDIV_LEFTBUS);
tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
tmp |= ((clkdiv_lr_bus[div_index][0] << S5P_CLKDIV_BUS_GDLR_SHIFT) |
(clkdiv_lr_bus[div_index][1] << S5P_CLKDIV_BUS_GPLR_SHIFT));
__raw_writel(tmp, S5P_CLKDIV_LEFTBUS);
do {
tmp = __raw_readl(S5P_CLKDIV_STAT_LEFTBUS);
} while (tmp & 0x11);
/* Change Divider - RIGHTBUS */
tmp = __raw_readl(S5P_CLKDIV_RIGHTBUS);
tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
tmp |= ((clkdiv_lr_bus[div_index][0] << S5P_CLKDIV_BUS_GDLR_SHIFT) |
(clkdiv_lr_bus[div_index][1] << S5P_CLKDIV_BUS_GPLR_SHIFT));
__raw_writel(tmp, S5P_CLKDIV_RIGHTBUS);
do {
tmp = __raw_readl(S5P_CLKDIV_STAT_RIGHTBUS);
} while (tmp & 0x11);
}
static void s5pv310_set_apll(unsigned int index)
{
unsigned int tmp;
/* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
clk_set_parent(moutcore, mout_mpll);
do {
tmp = (__raw_readl(S5P_CLKMUX_STATCPU)
>> S5P_CLKSRC_CPU_MUXCORE_SHIFT);
tmp &= 0x7;
} while (tmp != 0x2);
/* 2. Set APLL Lock time */
__raw_writel(S5P_APLL_LOCKTIME, S5P_APLL_LOCK);
/* 3. Change PLL PMS values */
tmp = __raw_readl(S5P_APLL_CON0);
tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
tmp |= s5pv310_apll_pms_table[index];
__raw_writel(tmp, S5P_APLL_CON0);
/* 4. wait_lock_time */
do {
tmp = __raw_readl(S5P_APLL_CON0);
} while (!(tmp & (0x1 << S5P_APLLCON0_LOCKED_SHIFT)));
/* 5. MUX_CORE_SEL = APLL */
clk_set_parent(moutcore, mout_apll);
do {
tmp = __raw_readl(S5P_CLKMUX_STATCPU);
tmp &= S5P_CLKMUX_STATCPU_MUXCORE_MASK;
} while (tmp != (0x1 << S5P_CLKSRC_CPU_MUXCORE_SHIFT));
}
static void s5pv310_set_frequency(unsigned int old_index, unsigned int new_index)
{
unsigned int tmp;
if (old_index > new_index) {
/* The frequency changing to L0 needs to change apll */
if (freqs.new == s5pv310_freq_table[L0].frequency) {
/* 1. Change the system clock divider values */
s5pv310_set_clkdiv(new_index);
/* 2. Change the apll m,p,s value */
s5pv310_set_apll(new_index);
} else {
/* 1. Change the system clock divider values */
s5pv310_set_clkdiv(new_index);
/* 2. Change just s value in apll m,p,s value */
tmp = __raw_readl(S5P_APLL_CON0);
tmp &= ~(0x7 << 0);
tmp |= (s5pv310_apll_pms_table[new_index] & 0x7);
__raw_writel(tmp, S5P_APLL_CON0);
}
}
else if (old_index < new_index) {
/* The frequency changing from L0 needs to change apll */
if (freqs.old == s5pv310_freq_table[L0].frequency) {
/* 1. Change the apll m,p,s value */
s5pv310_set_apll(new_index);
/* 2. Change the system clock divider values */
s5pv310_set_clkdiv(new_index);
} else {
/* 1. Change just s value in apll m,p,s value */
tmp = __raw_readl(S5P_APLL_CON0);
tmp &= ~(0x7 << 0);
tmp |= (s5pv310_apll_pms_table[new_index] & 0x7);
__raw_writel(tmp, S5P_APLL_CON0);
/* 2. Change the system clock divider values */
s5pv310_set_clkdiv(new_index);
}
}
}
static int s5pv310_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
unsigned int index, old_index;
unsigned int arm_volt, int_volt;
freqs.old = s5pv310_getspeed(policy->cpu);
if (cpufreq_frequency_table_target(policy, s5pv310_freq_table,
freqs.old, relation, &old_index))
return -EINVAL;
if (cpufreq_frequency_table_target(policy, s5pv310_freq_table,
target_freq, relation, &index))
return -EINVAL;
freqs.new = s5pv310_freq_table[index].frequency;
freqs.cpu = policy->cpu;
if (freqs.new == freqs.old)
return 0;
/* get the voltage value */
arm_volt = s5pv310_volt_table[index].arm_volt;
int_volt = s5pv310_volt_table[index].int_volt;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
/* control regulator */
if (freqs.new > freqs.old) {
/* Voltage up */
#ifdef CONFIG_REGULATOR
regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
regulator_set_voltage(int_regulator, int_volt, int_volt);
#endif
}
/* Clock Configuration Procedure */
s5pv310_set_frequency(old_index, index);
/* control regulator */
if (freqs.new < freqs.old) {
/* Voltage down */
#ifdef CONFIG_REGULATOR
regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
regulator_set_voltage(int_regulator, int_volt, int_volt);
#endif
}
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return 0;
}
#ifdef CONFIG_PM
static int s5pv310_cpufreq_suspend(struct cpufreq_policy *policy,
pm_message_t pmsg)
{
return 0;
}
static int s5pv310_cpufreq_resume(struct cpufreq_policy *policy)
{
return 0;
}
#endif
static int s5pv310_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
policy->cur = policy->min = policy->max = s5pv310_getspeed(policy->cpu);
cpufreq_frequency_table_get_attr(s5pv310_freq_table, policy->cpu);
/* set the transition latency value */
policy->cpuinfo.transition_latency = 100000;
/*
* S5PV310 multi-core processors has 2 cores
* that the frequency cannot be set independently.
* Each cpu is bound to the same speed.
* So the affected cpu is all of the cpus.
*/
cpumask_setall(policy->cpus);
return cpufreq_frequency_table_cpuinfo(policy, s5pv310_freq_table);
}
static struct cpufreq_driver s5pv310_driver = {
.flags = CPUFREQ_STICKY,
.verify = s5pv310_verify_speed,
.target = s5pv310_target,
.get = s5pv310_getspeed,
.init = s5pv310_cpufreq_cpu_init,
.name = "s5pv310_cpufreq",
#ifdef CONFIG_PM
.suspend = s5pv310_cpufreq_suspend,
.resume = s5pv310_cpufreq_resume,
#endif
};
static int __init s5pv310_cpufreq_init(void)
{
cpu_clk = clk_get(NULL, "armclk");
if (IS_ERR(cpu_clk))
return PTR_ERR(cpu_clk);
moutcore = clk_get(NULL, "moutcore");
if (IS_ERR(moutcore))
goto out;
mout_mpll = clk_get(NULL, "mout_mpll");
if (IS_ERR(mout_mpll))
goto out;
mout_apll = clk_get(NULL, "mout_apll");
if (IS_ERR(mout_apll))
goto out;
#ifdef CONFIG_REGULATOR
arm_regulator = regulator_get(NULL, "vdd_arm");
if (IS_ERR(arm_regulator)) {
printk(KERN_ERR "failed to get resource %s\n", "vdd_arm");
goto out;
}
int_regulator = regulator_get(NULL, "vdd_int");
if (IS_ERR(int_regulator)) {
printk(KERN_ERR "failed to get resource %s\n", "vdd_int");
goto out;
}
#endif
/*
* Check DRAM type.
* Because DVFS level is different according to DRAM type.
*/
memtype = __raw_readl(S5P_VA_DMC0 + S5P_DMC0_MEMCON_OFFSET);
memtype = (memtype >> S5P_DMC0_MEMTYPE_SHIFT);
memtype &= S5P_DMC0_MEMTYPE_MASK;
if ((memtype < DDR2) && (memtype > DDR3)) {
printk(KERN_ERR "%s: wrong memtype= 0x%x\n", __func__, memtype);
goto out;
} else {
printk(KERN_DEBUG "%s: memtype= 0x%x\n", __func__, memtype);
}
return cpufreq_register_driver(&s5pv310_driver);
out:
if (!IS_ERR(cpu_clk))
clk_put(cpu_clk);
if (!IS_ERR(moutcore))
clk_put(moutcore);
if (!IS_ERR(mout_mpll))
clk_put(mout_mpll);
if (!IS_ERR(mout_apll))
clk_put(mout_apll);
#ifdef CONFIG_REGULATOR
if (!IS_ERR(arm_regulator))
regulator_put(arm_regulator);
if (!IS_ERR(int_regulator))
regulator_put(int_regulator);
#endif
printk(KERN_ERR "%s: failed initialization\n", __func__);
return -EINVAL;
}
late_initcall(s5pv310_cpufreq_init);
/* linux/arch/arm/mach-s5pv310/dev-audio.c
*
* Copyright (c) 2010 Samsung Electronics Co. Ltd
* Jaswinder Singh <jassi.brar@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <plat/gpio-cfg.h>
#include <plat/audio.h>
#include <mach/map.h>
#include <mach/dma.h>
#include <mach/irqs.h>
static const char *rclksrc[] = {
[0] = "busclk",
[1] = "i2sclk",
};
static int s5pv310_cfg_i2s(struct platform_device *pdev)
{
/* configure GPIO for i2s port */
switch (pdev->id) {
case 0:
s3c_gpio_cfgpin_range(S5PV310_GPZ(0), 7, S3C_GPIO_SFN(2));
break;
case 1:
s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(2));
break;
case 2:
s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 5, S3C_GPIO_SFN(4));
break;
default:
printk(KERN_ERR "Invalid Device %d\n", pdev->id);
return -EINVAL;
}
return 0;
}
static struct s3c_audio_pdata i2sv5_pdata = {
.cfg_gpio = s5pv310_cfg_i2s,
.type = {
.i2s = {
.quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
| QUIRK_NEED_RSTCLR,
.src_clk = rclksrc,
},
},
};
static struct resource s5pv310_i2s0_resource[] = {
[0] = {
.start = S5PV310_PA_I2S0,
.end = S5PV310_PA_I2S0 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_I2S0_TX,
.end = DMACH_I2S0_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_I2S0_RX,
.end = DMACH_I2S0_RX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = DMACH_I2S0S_TX,
.end = DMACH_I2S0S_TX,
.flags = IORESOURCE_DMA,
},
};
struct platform_device s5pv310_device_i2s0 = {
.name = "samsung-i2s",
.id = 0,
.num_resources = ARRAY_SIZE(s5pv310_i2s0_resource),
.resource = s5pv310_i2s0_resource,
.dev = {
.platform_data = &i2sv5_pdata,
},
};
static const char *rclksrc_v3[] = {
[0] = "sclk_i2s",
[1] = "no_such_clock",
};
static struct s3c_audio_pdata i2sv3_pdata = {
.cfg_gpio = s5pv310_cfg_i2s,
.type = {
.i2s = {
.quirks = QUIRK_NO_MUXPSR,
.src_clk = rclksrc_v3,
},
},
};
static struct resource s5pv310_i2s1_resource[] = {
[0] = {
.start = S5PV310_PA_I2S1,
.end = S5PV310_PA_I2S1 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_I2S1_TX,
.end = DMACH_I2S1_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_I2S1_RX,
.end = DMACH_I2S1_RX,
.flags = IORESOURCE_DMA,
},
};
struct platform_device s5pv310_device_i2s1 = {
.name = "samsung-i2s",
.id = 1,
.num_resources = ARRAY_SIZE(s5pv310_i2s1_resource),
.resource = s5pv310_i2s1_resource,
.dev = {
.platform_data = &i2sv3_pdata,
},
};
static struct resource s5pv310_i2s2_resource[] = {
[0] = {
.start = S5PV310_PA_I2S2,
.end = S5PV310_PA_I2S2 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_I2S2_TX,
.end = DMACH_I2S2_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_I2S2_RX,
.end = DMACH_I2S2_RX,
.flags = IORESOURCE_DMA,
},
};
struct platform_device s5pv310_device_i2s2 = {
.name = "samsung-i2s",
.id = 2,
.num_resources = ARRAY_SIZE(s5pv310_i2s2_resource),
.resource = s5pv310_i2s2_resource,
.dev = {
.platform_data = &i2sv3_pdata,
},
};
/* PCM Controller platform_devices */
static int s5pv310_pcm_cfg_gpio(struct platform_device *pdev)
{
switch (pdev->id) {
case 0:
s3c_gpio_cfgpin_range(S5PV310_GPZ(0), 5, S3C_GPIO_SFN(3));
break;
case 1:
s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(3));
break;
case 2:
s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 5, S3C_GPIO_SFN(3));
break;
default:
printk(KERN_DEBUG "Invalid PCM Controller number!");
return -EINVAL;
}
return 0;
}
static struct s3c_audio_pdata s3c_pcm_pdata = {
.cfg_gpio = s5pv310_pcm_cfg_gpio,
};
static struct resource s5pv310_pcm0_resource[] = {
[0] = {
.start = S5PV310_PA_PCM0,
.end = S5PV310_PA_PCM0 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_PCM0_TX,
.end = DMACH_PCM0_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_PCM0_RX,
.end = DMACH_PCM0_RX,
.flags = IORESOURCE_DMA,
},
};
struct platform_device s5pv310_device_pcm0 = {
.name = "samsung-pcm",
.id = 0,
.num_resources = ARRAY_SIZE(s5pv310_pcm0_resource),
.resource = s5pv310_pcm0_resource,
.dev = {
.platform_data = &s3c_pcm_pdata,
},
};
static struct resource s5pv310_pcm1_resource[] = {
[0] = {
.start = S5PV310_PA_PCM1,
.end = S5PV310_PA_PCM1 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_PCM1_TX,
.end = DMACH_PCM1_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_PCM1_RX,
.end = DMACH_PCM1_RX,
.flags = IORESOURCE_DMA,
},
};
struct platform_device s5pv310_device_pcm1 = {
.name = "samsung-pcm",
.id = 1,
.num_resources = ARRAY_SIZE(s5pv310_pcm1_resource),
.resource = s5pv310_pcm1_resource,
.dev = {
.platform_data = &s3c_pcm_pdata,
},
};
static struct resource s5pv310_pcm2_resource[] = {
[0] = {
.start = S5PV310_PA_PCM2,
.end = S5PV310_PA_PCM2 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_PCM2_TX,
.end = DMACH_PCM2_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_PCM2_RX,
.end = DMACH_PCM2_RX,
.flags = IORESOURCE_DMA,
},
};
struct platform_device s5pv310_device_pcm2 = {
.name = "samsung-pcm",
.id = 2,
.num_resources = ARRAY_SIZE(s5pv310_pcm2_resource),
.resource = s5pv310_pcm2_resource,
.dev = {
.platform_data = &s3c_pcm_pdata,
},
};
/* AC97 Controller platform devices */
static int s5pv310_ac97_cfg_gpio(struct platform_device *pdev)
{
return s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(4));
}
static struct resource s5pv310_ac97_resource[] = {
[0] = {
.start = S5PV310_PA_AC97,
.end = S5PV310_PA_AC97 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_AC97_PCMOUT,
.end = DMACH_AC97_PCMOUT,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_AC97_PCMIN,
.end = DMACH_AC97_PCMIN,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = DMACH_AC97_MICIN,
.end = DMACH_AC97_MICIN,
.flags = IORESOURCE_DMA,
},
[4] = {
.start = IRQ_AC97,
.end = IRQ_AC97,
.flags = IORESOURCE_IRQ,
},
};
static struct s3c_audio_pdata s3c_ac97_pdata = {
.cfg_gpio = s5pv310_ac97_cfg_gpio,
};
static u64 s5pv310_ac97_dmamask = DMA_BIT_MASK(32);
struct platform_device s5pv310_device_ac97 = {
.name = "samsung-ac97",
.id = -1,
.num_resources = ARRAY_SIZE(s5pv310_ac97_resource),
.resource = s5pv310_ac97_resource,
.dev = {
.platform_data = &s3c_ac97_pdata,
.dma_mask = &s5pv310_ac97_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
/* S/PDIF Controller platform_device */
static int s5pv310_spdif_cfg_gpio(struct platform_device *pdev)
{
s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 2, S3C_GPIO_SFN(3));
return 0;
}
static struct resource s5pv310_spdif_resource[] = {
[0] = {
.start = S5PV310_PA_SPDIF,
.end = S5PV310_PA_SPDIF + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_SPDIF,
.end = DMACH_SPDIF,
.flags = IORESOURCE_DMA,
},
};
static struct s3c_audio_pdata samsung_spdif_pdata = {
.cfg_gpio = s5pv310_spdif_cfg_gpio,
};
static u64 s5pv310_spdif_dmamask = DMA_BIT_MASK(32);
struct platform_device s5pv310_device_spdif = {
.name = "samsung-spdif",
.id = -1,
.num_resources = ARRAY_SIZE(s5pv310_spdif_resource),
.resource = s5pv310_spdif_resource,
.dev = {
.platform_data = &samsung_spdif_pdata,
.dma_mask = &s5pv310_spdif_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
/* linux/arch/arm/mach-s5pv310/dev-pd.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S5PV310 - Power Domain support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <mach/regs-pmu.h>
#include <plat/pd.h>
static int s5pv310_pd_enable(struct device *dev)
{
struct samsung_pd_info *pdata = dev->platform_data;
u32 timeout;
__raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base);
/* Wait max 1ms */
timeout = 10;
while ((__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN)
!= S5P_INT_LOCAL_PWR_EN) {
if (timeout == 0) {
printk(KERN_ERR "Power domain %s enable failed.\n",
dev_name(dev));
return -ETIMEDOUT;
}
timeout--;
udelay(100);
}
return 0;
}
static int s5pv310_pd_disable(struct device *dev)
{
struct samsung_pd_info *pdata = dev->platform_data;
u32 timeout;
__raw_writel(0, pdata->base);
/* Wait max 1ms */
timeout = 10;
while (__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) {
if (timeout == 0) {
printk(KERN_ERR "Power domain %s disable failed.\n",
dev_name(dev));
return -ETIMEDOUT;
}
timeout--;
udelay(100);
}
return 0;
}
struct platform_device s5pv310_device_pd[] = {
{
.name = "samsung-pd",
.id = 0,
.dev = {
.platform_data = &(struct samsung_pd_info) {
.enable = s5pv310_pd_enable,
.disable = s5pv310_pd_disable,
.base = S5P_PMU_MFC_CONF,
},
},
}, {
.name = "samsung-pd",
.id = 1,
.dev = {
.platform_data = &(struct samsung_pd_info) {
.enable = s5pv310_pd_enable,
.disable = s5pv310_pd_disable,
.base = S5P_PMU_G3D_CONF,
},
},
}, {
.name = "samsung-pd",
.id = 2,
.dev = {
.platform_data = &(struct samsung_pd_info) {
.enable = s5pv310_pd_enable,
.disable = s5pv310_pd_disable,
.base = S5P_PMU_LCD0_CONF,
},
},
}, {
.name = "samsung-pd",
.id = 3,
.dev = {
.platform_data = &(struct samsung_pd_info) {
.enable = s5pv310_pd_enable,
.disable = s5pv310_pd_disable,
.base = S5P_PMU_LCD1_CONF,
},
},
}, {
.name = "samsung-pd",
.id = 4,
.dev = {
.platform_data = &(struct samsung_pd_info) {
.enable = s5pv310_pd_enable,
.disable = s5pv310_pd_disable,
.base = S5P_PMU_TV_CONF,
},
},
}, {
.name = "samsung-pd",
.id = 5,
.dev = {
.platform_data = &(struct samsung_pd_info) {
.enable = s5pv310_pd_enable,
.disable = s5pv310_pd_disable,
.base = S5P_PMU_CAM_CONF,
},
},
}, {
.name = "samsung-pd",
.id = 6,
.dev = {
.platform_data = &(struct samsung_pd_info) {
.enable = s5pv310_pd_enable,
.disable = s5pv310_pd_disable,
.base = S5P_PMU_GPS_CONF,
},
},
},
};
/* linux/arch/arm/mach-s5pv310/dev-sysmmu.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <mach/map.h>
#include <mach/irqs.h>
static struct resource s5pv310_sysmmu_resource[] = {
[0] = {
.start = S5PV310_PA_SYSMMU_MDMA,
.end = S5PV310_PA_SYSMMU_MDMA + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_SYSMMU_MDMA0_0,
.end = IRQ_SYSMMU_MDMA0_0,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = S5PV310_PA_SYSMMU_SSS,
.end = S5PV310_PA_SYSMMU_SSS + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[3] = {
.start = IRQ_SYSMMU_SSS_0,
.end = IRQ_SYSMMU_SSS_0,
.flags = IORESOURCE_IRQ,
},
[4] = {
.start = S5PV310_PA_SYSMMU_FIMC0,
.end = S5PV310_PA_SYSMMU_FIMC0 + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[5] = {
.start = IRQ_SYSMMU_FIMC0_0,
.end = IRQ_SYSMMU_FIMC0_0,
.flags = IORESOURCE_IRQ,
},
[6] = {
.start = S5PV310_PA_SYSMMU_FIMC1,
.end = S5PV310_PA_SYSMMU_FIMC1 + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[7] = {
.start = IRQ_SYSMMU_FIMC1_0,
.end = IRQ_SYSMMU_FIMC1_0,
.flags = IORESOURCE_IRQ,
},
[8] = {
.start = S5PV310_PA_SYSMMU_FIMC2,
.end = S5PV310_PA_SYSMMU_FIMC2 + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[9] = {
.start = IRQ_SYSMMU_FIMC2_0,
.end = IRQ_SYSMMU_FIMC2_0,
.flags = IORESOURCE_IRQ,
},
[10] = {
.start = S5PV310_PA_SYSMMU_FIMC3,
.end = S5PV310_PA_SYSMMU_FIMC3 + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[11] = {
.start = IRQ_SYSMMU_FIMC3_0,
.end = IRQ_SYSMMU_FIMC3_0,
.flags = IORESOURCE_IRQ,
},
[12] = {
.start = S5PV310_PA_SYSMMU_JPEG,
.end = S5PV310_PA_SYSMMU_JPEG + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[13] = {
.start = IRQ_SYSMMU_JPEG_0,
.end = IRQ_SYSMMU_JPEG_0,
.flags = IORESOURCE_IRQ,
},
[14] = {
.start = S5PV310_PA_SYSMMU_FIMD0,
.end = S5PV310_PA_SYSMMU_FIMD0 + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[15] = {
.start = IRQ_SYSMMU_LCD0_M0_0,
.end = IRQ_SYSMMU_LCD0_M0_0,
.flags = IORESOURCE_IRQ,
},
[16] = {
.start = S5PV310_PA_SYSMMU_FIMD1,
.end = S5PV310_PA_SYSMMU_FIMD1 + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[17] = {
.start = IRQ_SYSMMU_LCD1_M1_0,
.end = IRQ_SYSMMU_LCD1_M1_0,
.flags = IORESOURCE_IRQ,
},
[18] = {
.start = S5PV310_PA_SYSMMU_PCIe,
.end = S5PV310_PA_SYSMMU_PCIe + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[19] = {
.start = IRQ_SYSMMU_PCIE_0,
.end = IRQ_SYSMMU_PCIE_0,
.flags = IORESOURCE_IRQ,
},
[20] = {
.start = S5PV310_PA_SYSMMU_G2D,
.end = S5PV310_PA_SYSMMU_G2D + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[21] = {
.start = IRQ_SYSMMU_2D_0,
.end = IRQ_SYSMMU_2D_0,
.flags = IORESOURCE_IRQ,
},
[22] = {
.start = S5PV310_PA_SYSMMU_ROTATOR,
.end = S5PV310_PA_SYSMMU_ROTATOR + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[23] = {
.start = IRQ_SYSMMU_ROTATOR_0,
.end = IRQ_SYSMMU_ROTATOR_0,
.flags = IORESOURCE_IRQ,
},
[24] = {
.start = S5PV310_PA_SYSMMU_MDMA2,
.end = S5PV310_PA_SYSMMU_MDMA2 + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[25] = {
.start = IRQ_SYSMMU_MDMA1_0,
.end = IRQ_SYSMMU_MDMA1_0,
.flags = IORESOURCE_IRQ,
},
[26] = {
.start = S5PV310_PA_SYSMMU_TV,
.end = S5PV310_PA_SYSMMU_TV + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[27] = {
.start = IRQ_SYSMMU_TV_M0_0,
.end = IRQ_SYSMMU_TV_M0_0,
.flags = IORESOURCE_IRQ,
},
[28] = {
.start = S5PV310_PA_SYSMMU_MFC_L,
.end = S5PV310_PA_SYSMMU_MFC_L + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[29] = {
.start = IRQ_SYSMMU_MFC_M0_0,
.end = IRQ_SYSMMU_MFC_M0_0,
.flags = IORESOURCE_IRQ,
},
[30] = {
.start = S5PV310_PA_SYSMMU_MFC_R,
.end = S5PV310_PA_SYSMMU_MFC_R + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[31] = {
.start = IRQ_SYSMMU_MFC_M1_0,
.end = IRQ_SYSMMU_MFC_M1_0,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device s5pv310_device_sysmmu = {
.name = "s5p-sysmmu",
.id = 32,
.num_resources = ARRAY_SIZE(s5pv310_sysmmu_resource),
.resource = s5pv310_sysmmu_resource,
};
EXPORT_SYMBOL(s5pv310_device_sysmmu);
/*
* Copyright (C) 2010 Samsung Electronics Co. Ltd.
* Jaswinder Singh <jassi.brar@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <plat/devs.h>
#include <plat/irqs.h>
#include <mach/map.h>
#include <mach/irqs.h>
#include <plat/s3c-pl330-pdata.h>
static u64 dma_dmamask = DMA_BIT_MASK(32);
static struct resource s5pv310_pdma0_resource[] = {
[0] = {
.start = S5PV310_PA_PDMA0,
.end = S5PV310_PA_PDMA0 + SZ_4K,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_PDMA0,
.end = IRQ_PDMA0,
.flags = IORESOURCE_IRQ,
},
};
static struct s3c_pl330_platdata s5pv310_pdma0_pdata = {
.peri = {
[0] = DMACH_PCM0_RX,
[1] = DMACH_PCM0_TX,
[2] = DMACH_PCM2_RX,
[3] = DMACH_PCM2_TX,
[4] = DMACH_MSM_REQ0,
[5] = DMACH_MSM_REQ2,
[6] = DMACH_SPI0_RX,
[7] = DMACH_SPI0_TX,
[8] = DMACH_SPI2_RX,
[9] = DMACH_SPI2_TX,
[10] = DMACH_I2S0S_TX,
[11] = DMACH_I2S0_RX,
[12] = DMACH_I2S0_TX,
[13] = DMACH_I2S2_RX,
[14] = DMACH_I2S2_TX,
[15] = DMACH_UART0_RX,
[16] = DMACH_UART0_TX,
[17] = DMACH_UART2_RX,
[18] = DMACH_UART2_TX,
[19] = DMACH_UART4_RX,
[20] = DMACH_UART4_TX,
[21] = DMACH_SLIMBUS0_RX,
[22] = DMACH_SLIMBUS0_TX,
[23] = DMACH_SLIMBUS2_RX,
[24] = DMACH_SLIMBUS2_TX,
[25] = DMACH_SLIMBUS4_RX,
[26] = DMACH_SLIMBUS4_TX,
[27] = DMACH_AC97_MICIN,
[28] = DMACH_AC97_PCMIN,
[29] = DMACH_AC97_PCMOUT,
[30] = DMACH_MAX,
[31] = DMACH_MAX,
},
};
static struct platform_device s5pv310_device_pdma0 = {
.name = "s3c-pl330",
.id = 0,
.num_resources = ARRAY_SIZE(s5pv310_pdma0_resource),
.resource = s5pv310_pdma0_resource,
.dev = {
.dma_mask = &dma_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &s5pv310_pdma0_pdata,
},
};
static struct resource s5pv310_pdma1_resource[] = {
[0] = {
.start = S5PV310_PA_PDMA1,
.end = S5PV310_PA_PDMA1 + SZ_4K,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_PDMA1,
.end = IRQ_PDMA1,
.flags = IORESOURCE_IRQ,
},
};
static struct s3c_pl330_platdata s5pv310_pdma1_pdata = {
.peri = {
[0] = DMACH_PCM0_RX,
[1] = DMACH_PCM0_TX,
[2] = DMACH_PCM1_RX,
[3] = DMACH_PCM1_TX,
[4] = DMACH_MSM_REQ1,
[5] = DMACH_MSM_REQ3,
[6] = DMACH_SPI1_RX,
[7] = DMACH_SPI1_TX,
[8] = DMACH_I2S0S_TX,
[9] = DMACH_I2S0_RX,
[10] = DMACH_I2S0_TX,
[11] = DMACH_I2S1_RX,
[12] = DMACH_I2S1_TX,
[13] = DMACH_UART0_RX,
[14] = DMACH_UART0_TX,
[15] = DMACH_UART1_RX,
[16] = DMACH_UART1_TX,
[17] = DMACH_UART3_RX,
[18] = DMACH_UART3_TX,
[19] = DMACH_SLIMBUS1_RX,
[20] = DMACH_SLIMBUS1_TX,
[21] = DMACH_SLIMBUS3_RX,
[22] = DMACH_SLIMBUS3_TX,
[23] = DMACH_SLIMBUS5_RX,
[24] = DMACH_SLIMBUS5_TX,
[25] = DMACH_SLIMBUS0AUX_RX,
[26] = DMACH_SLIMBUS0AUX_TX,
[27] = DMACH_SPDIF,
[28] = DMACH_MAX,
[29] = DMACH_MAX,
[30] = DMACH_MAX,
[31] = DMACH_MAX,
},
};
static struct platform_device s5pv310_device_pdma1 = {
.name = "s3c-pl330",
.id = 1,
.num_resources = ARRAY_SIZE(s5pv310_pdma1_resource),
.resource = s5pv310_pdma1_resource,
.dev = {
.dma_mask = &dma_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &s5pv310_pdma1_pdata,
},
};
static struct platform_device *s5pv310_dmacs[] __initdata = {
&s5pv310_device_pdma0,
&s5pv310_device_pdma1,
};
static int __init s5pv310_dma_init(void)
{
platform_add_devices(s5pv310_dmacs, ARRAY_SIZE(s5pv310_dmacs));
return 0;
}
arch_initcall(s5pv310_dma_init);
/*
* Copyright (C) 2010 Samsung Electronics Co. Ltd.
* Jaswinder Singh <jassi.brar@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __MACH_DMA_H
#define __MACH_DMA_H
/* This platform uses the common S3C DMA API driver for PL330 */
#include <plat/s3c-dma-pl330.h>
#endif /* __MACH_DMA_H */
......@@ -25,6 +25,8 @@
#define IRQ_SPI(x) S5P_IRQ(x+32)
#define IRQ_MCT1 IRQ_SPI(35)
#define IRQ_EINT0 IRQ_SPI(40)
#define IRQ_EINT1 IRQ_SPI(41)
#define IRQ_EINT2 IRQ_SPI(42)
......@@ -36,9 +38,8 @@
#define IRQ_JPEG IRQ_SPI(48)
#define IRQ_2D IRQ_SPI(49)
#define IRQ_PCIE IRQ_SPI(50)
#define IRQ_SYSTEM_TIMER IRQ_SPI(51)
#define IRQ_MCT0 IRQ_SPI(51)
#define IRQ_MFC IRQ_SPI(52)
#define IRQ_WDT IRQ_SPI(53)
#define IRQ_AUDIO_SS IRQ_SPI(54)
#define IRQ_AC97 IRQ_SPI(55)
#define IRQ_SPDIF IRQ_SPI(56)
......@@ -54,6 +55,27 @@
#define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(64))
#define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y)
#define IRQ_SYSMMU_MDMA0_0 COMBINER_IRQ(4, 0)
#define IRQ_SYSMMU_SSS_0 COMBINER_IRQ(4, 1)
#define IRQ_SYSMMU_FIMC0_0 COMBINER_IRQ(4, 2)
#define IRQ_SYSMMU_FIMC1_0 COMBINER_IRQ(4, 3)
#define IRQ_SYSMMU_FIMC2_0 COMBINER_IRQ(4, 4)
#define IRQ_SYSMMU_FIMC3_0 COMBINER_IRQ(4, 5)
#define IRQ_SYSMMU_JPEG_0 COMBINER_IRQ(4, 6)
#define IRQ_SYSMMU_2D_0 COMBINER_IRQ(4, 7)
#define IRQ_SYSMMU_ROTATOR_0 COMBINER_IRQ(5, 0)
#define IRQ_SYSMMU_MDMA1_0 COMBINER_IRQ(5, 1)
#define IRQ_SYSMMU_LCD0_M0_0 COMBINER_IRQ(5, 2)
#define IRQ_SYSMMU_LCD1_M1_0 COMBINER_IRQ(5, 3)
#define IRQ_SYSMMU_TV_M0_0 COMBINER_IRQ(5, 4)
#define IRQ_SYSMMU_MFC_M0_0 COMBINER_IRQ(5, 5)
#define IRQ_SYSMMU_MFC_M1_0 COMBINER_IRQ(5, 6)
#define IRQ_SYSMMU_PCIE_0 COMBINER_IRQ(5, 7)
#define IRQ_PDMA0 COMBINER_IRQ(21, 0)
#define IRQ_PDMA1 COMBINER_IRQ(21, 1)
#define IRQ_TIMER0_VIC COMBINER_IRQ(22, 0)
#define IRQ_TIMER1_VIC COMBINER_IRQ(22, 1)
#define IRQ_TIMER2_VIC COMBINER_IRQ(22, 2)
......@@ -83,8 +105,13 @@
#define IRQ_HSMMC2 COMBINER_IRQ(29, 2)
#define IRQ_HSMMC3 COMBINER_IRQ(29, 3)
#define IRQ_MIPI_CSIS0 COMBINER_IRQ(30, 0)
#define IRQ_MIPI_CSIS1 COMBINER_IRQ(30, 1)
#define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0)
#define IRQ_MCT_L1 COMBINER_IRQ(35, 3)
#define IRQ_EINT4 COMBINER_IRQ(37, 0)
#define IRQ_EINT5 COMBINER_IRQ(37, 1)
#define IRQ_EINT6 COMBINER_IRQ(37, 2)
......@@ -101,7 +128,11 @@
#define IRQ_EINT16_31 COMBINER_IRQ(39, 0)
#define MAX_COMBINER_NR 40
#define IRQ_MCT_L0 COMBINER_IRQ(51, 0)
#define IRQ_WDT COMBINER_IRQ(53, 0)
#define MAX_COMBINER_NR 54
#define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0)
......
......@@ -39,11 +39,15 @@
#define S5PV310_PA_SYSCON (0x10010000)
#define S5P_PA_SYSCON S5PV310_PA_SYSCON
#define S5PV310_PA_PMU (0x10020000)
#define S5PV310_PA_CMU (0x10030000)
#define S5PV310_PA_WATCHDOG (0x10060000)
#define S5PV310_PA_RTC (0x10070000)
#define S5PV310_PA_DMC0 (0x10400000)
#define S5PV310_PA_COMBINER (0x10448000)
#define S5PV310_PA_COREPERI (0x10500000)
......@@ -52,13 +56,38 @@
#define S5PV310_PA_GIC_DIST (0x10501000)
#define S5PV310_PA_L2CC (0x10502000)
/* DMA */
#define S5PV310_PA_MDMA 0x10810000
#define S5PV310_PA_PDMA0 0x12680000
#define S5PV310_PA_PDMA1 0x12690000
#define S5PV310_PA_GPIO1 (0x11400000)
#define S5PV310_PA_GPIO2 (0x11000000)
#define S5PV310_PA_GPIO3 (0x03860000)
#define S5PV310_PA_MIPI_CSIS0 0x11880000
#define S5PV310_PA_MIPI_CSIS1 0x11890000
#define S5PV310_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000))
#define S5PV310_PA_SROMC (0x12570000)
#define S5P_PA_SROMC S5PV310_PA_SROMC
/* S/PDIF */
#define S5PV310_PA_SPDIF 0xE1100000
/* I2S */
#define S5PV310_PA_I2S0 0x03830000
#define S5PV310_PA_I2S1 0xE3100000
#define S5PV310_PA_I2S2 0xE2A00000
/* PCM */
#define S5PV310_PA_PCM0 0x03840000
#define S5PV310_PA_PCM1 0x13980000
#define S5PV310_PA_PCM2 0x13990000
/* AC97 */
#define S5PV310_PA_AC97 0x139A0000
#define S5PV310_PA_UART (0x13800000)
......@@ -79,6 +108,25 @@
#define S5PV310_PA_SDRAM (0x40000000)
#define S5P_PA_SDRAM S5PV310_PA_SDRAM
#define S5PV310_PA_SYSMMU_MDMA 0x10A40000
#define S5PV310_PA_SYSMMU_SSS 0x10A50000
#define S5PV310_PA_SYSMMU_FIMC0 0x11A20000
#define S5PV310_PA_SYSMMU_FIMC1 0x11A30000
#define S5PV310_PA_SYSMMU_FIMC2 0x11A40000
#define S5PV310_PA_SYSMMU_FIMC3 0x11A50000
#define S5PV310_PA_SYSMMU_JPEG 0x11A60000
#define S5PV310_PA_SYSMMU_FIMD0 0x11E20000
#define S5PV310_PA_SYSMMU_FIMD1 0x12220000
#define S5PV310_PA_SYSMMU_PCIe 0x12620000
#define S5PV310_PA_SYSMMU_G2D 0x12A20000
#define S5PV310_PA_SYSMMU_ROTATOR 0x12A30000
#define S5PV310_PA_SYSMMU_MDMA2 0x12A40000
#define S5PV310_PA_SYSMMU_TV 0x12E20000
#define S5PV310_PA_SYSMMU_MFC_L 0x13620000
#define S5PV310_PA_SYSMMU_MFC_R 0x13630000
#define S5PV310_SYSMMU_TOTAL_IPNUM 16
#define S5P_SYSMMU_TOTAL_IPNUM S5PV310_SYSMMU_TOTAL_IPNUM
/* compatibiltiy defines. */
#define S3C_PA_UART S5PV310_PA_UART
#define S3C_PA_HSMMC0 S5PV310_PA_HSMMC(0)
......@@ -95,5 +143,7 @@
#define S3C_PA_IIC7 S5PV310_PA_IIC(7)
#define S3C_PA_RTC S5PV310_PA_RTC
#define S3C_PA_WDT S5PV310_PA_WATCHDOG
#define S5P_PA_MIPI_CSIS0 S5PV310_PA_MIPI_CSIS0
#define S5P_PA_MIPI_CSIS1 S5PV310_PA_MIPI_CSIS1
#endif /* __ASM_ARCH_MAP_H */
......@@ -19,6 +19,12 @@
#define S5P_INFORM0 S5P_CLKREG(0x800)
#define S5P_CLKDIV_LEFTBUS S5P_CLKREG(0x04500)
#define S5P_CLKDIV_STAT_LEFTBUS S5P_CLKREG(0x04600)
#define S5P_CLKDIV_RIGHTBUS S5P_CLKREG(0x08500)
#define S5P_CLKDIV_STAT_RIGHTBUS S5P_CLKREG(0x08600)
#define S5P_EPLL_CON0 S5P_CLKREG(0x0C110)
#define S5P_EPLL_CON1 S5P_CLKREG(0x0C114)
#define S5P_VPLL_CON0 S5P_CLKREG(0x0C120)
......@@ -58,6 +64,8 @@
#define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350)
#define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354)
#define S5P_CLKDIV_STAT_TOP S5P_CLKREG(0x0C610)
#define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920)
#define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930)
#define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934)
......@@ -66,8 +74,9 @@
#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950)
#define S5P_CLKGATE_IP_PERIR S5P_CLKREG(0x0C960)
#define S5P_CLKSRC_CORE S5P_CLKREG(0x10200)
#define S5P_CLKDIV_CORE0 S5P_CLKREG(0x10500)
#define S5P_CLKSRC_DMC S5P_CLKREG(0x10200)
#define S5P_CLKDIV_DMC0 S5P_CLKREG(0x10500)
#define S5P_CLKDIV_STAT_DMC0 S5P_CLKREG(0x10600)
#define S5P_APLL_LOCK S5P_CLKREG(0x14000)
#define S5P_MPLL_LOCK S5P_CLKREG(0x14004)
......@@ -80,10 +89,77 @@
#define S5P_CLKMUX_STATCPU S5P_CLKREG(0x14400)
#define S5P_CLKDIV_CPU S5P_CLKREG(0x14500)
#define S5P_CLKDIV_CPU1 S5P_CLKREG(0x14504)
#define S5P_CLKDIV_STATCPU S5P_CLKREG(0x14600)
#define S5P_CLKDIV_STATCPU1 S5P_CLKREG(0x14604)
#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800)
/* APLL_LOCK */
#define S5P_APLL_LOCKTIME (0x1C20) /* 300us */
/* APLL_CON0 */
#define S5P_APLLCON0_ENABLE_SHIFT (31)
#define S5P_APLLCON0_LOCKED_SHIFT (29)
#define S5P_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1)
#define S5P_APLL_VAL_800 ((200 << 16) | (6 << 8) | 1)
/* CLK_SRC_CPU */
#define S5P_CLKSRC_CPU_MUXCORE_SHIFT (16)
#define S5P_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)
/* CLKDIV_CPU0 */
#define S5P_CLKDIV_CPU0_CORE_SHIFT (0)
#define S5P_CLKDIV_CPU0_CORE_MASK (0x7 << S5P_CLKDIV_CPU0_CORE_SHIFT)
#define S5P_CLKDIV_CPU0_COREM0_SHIFT (4)
#define S5P_CLKDIV_CPU0_COREM0_MASK (0x7 << S5P_CLKDIV_CPU0_COREM0_SHIFT)
#define S5P_CLKDIV_CPU0_COREM1_SHIFT (8)
#define S5P_CLKDIV_CPU0_COREM1_MASK (0x7 << S5P_CLKDIV_CPU0_COREM1_SHIFT)
#define S5P_CLKDIV_CPU0_PERIPH_SHIFT (12)
#define S5P_CLKDIV_CPU0_PERIPH_MASK (0x7 << S5P_CLKDIV_CPU0_PERIPH_SHIFT)
#define S5P_CLKDIV_CPU0_ATB_SHIFT (16)
#define S5P_CLKDIV_CPU0_ATB_MASK (0x7 << S5P_CLKDIV_CPU0_ATB_SHIFT)
#define S5P_CLKDIV_CPU0_PCLKDBG_SHIFT (20)
#define S5P_CLKDIV_CPU0_PCLKDBG_MASK (0x7 << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT)
#define S5P_CLKDIV_CPU0_APLL_SHIFT (24)
#define S5P_CLKDIV_CPU0_APLL_MASK (0x7 << S5P_CLKDIV_CPU0_APLL_SHIFT)
/* CLKDIV_DMC0 */
#define S5P_CLKDIV_DMC0_ACP_SHIFT (0)
#define S5P_CLKDIV_DMC0_ACP_MASK (0x7 << S5P_CLKDIV_DMC0_ACP_SHIFT)
#define S5P_CLKDIV_DMC0_ACPPCLK_SHIFT (4)
#define S5P_CLKDIV_DMC0_ACPPCLK_MASK (0x7 << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT)
#define S5P_CLKDIV_DMC0_DPHY_SHIFT (8)
#define S5P_CLKDIV_DMC0_DPHY_MASK (0x7 << S5P_CLKDIV_DMC0_DPHY_SHIFT)
#define S5P_CLKDIV_DMC0_DMC_SHIFT (12)
#define S5P_CLKDIV_DMC0_DMC_MASK (0x7 << S5P_CLKDIV_DMC0_DMC_SHIFT)
#define S5P_CLKDIV_DMC0_DMCD_SHIFT (16)
#define S5P_CLKDIV_DMC0_DMCD_MASK (0x7 << S5P_CLKDIV_DMC0_DMCD_SHIFT)
#define S5P_CLKDIV_DMC0_DMCP_SHIFT (20)
#define S5P_CLKDIV_DMC0_DMCP_MASK (0x7 << S5P_CLKDIV_DMC0_DMCP_SHIFT)
#define S5P_CLKDIV_DMC0_COPY2_SHIFT (24)
#define S5P_CLKDIV_DMC0_COPY2_MASK (0x7 << S5P_CLKDIV_DMC0_COPY2_SHIFT)
#define S5P_CLKDIV_DMC0_CORETI_SHIFT (28)
#define S5P_CLKDIV_DMC0_CORETI_MASK (0x7 << S5P_CLKDIV_DMC0_CORETI_SHIFT)
/* CLKDIV_TOP */
#define S5P_CLKDIV_TOP_ACLK200_SHIFT (0)
#define S5P_CLKDIV_TOP_ACLK200_MASK (0x7 << S5P_CLKDIV_TOP_ACLK200_SHIFT)
#define S5P_CLKDIV_TOP_ACLK100_SHIFT (4)
#define S5P_CLKDIV_TOP_ACLK100_MASK (0xf << S5P_CLKDIV_TOP_ACLK100_SHIFT)
#define S5P_CLKDIV_TOP_ACLK160_SHIFT (8)
#define S5P_CLKDIV_TOP_ACLK160_MASK (0x7 << S5P_CLKDIV_TOP_ACLK160_SHIFT)
#define S5P_CLKDIV_TOP_ACLK133_SHIFT (12)
#define S5P_CLKDIV_TOP_ACLK133_MASK (0x7 << S5P_CLKDIV_TOP_ACLK133_SHIFT)
#define S5P_CLKDIV_TOP_ONENAND_SHIFT (16)
#define S5P_CLKDIV_TOP_ONENAND_MASK (0x7 << S5P_CLKDIV_TOP_ONENAND_SHIFT)
/* CLKDIV_LEFTBUS / CLKDIV_RIGHTBUS*/
#define S5P_CLKDIV_BUS_GDLR_SHIFT (0)
#define S5P_CLKDIV_BUS_GDLR_MASK (0x7 << S5P_CLKDIV_BUS_GDLR_SHIFT)
#define S5P_CLKDIV_BUS_GPLR_SHIFT (4)
#define S5P_CLKDIV_BUS_GPLR_MASK (0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT)
/* Compatibility defines */
#define S5P_EPLL_CON S5P_EPLL_CON0
......
/* linux/arch/arm/mach-s5pv310/include/mach/regs-mem.h
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S5PV310 - SROMC and DMC register definitions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ASM_ARCH_REGS_MEM_H
#define __ASM_ARCH_REGS_MEM_H __FILE__
#include <mach/map.h>
#define S5P_DMC0_MEMCON_OFFSET 0x04
#define S5P_DMC0_MEMTYPE_SHIFT 8
#define S5P_DMC0_MEMTYPE_MASK 0xF
#endif /* __ASM_ARCH_REGS_MEM_H */
/* linux/arch/arm/mach-s5pv310/include/mach/regs-pmu.h
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S5PV310 - Power management unit definition
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ASM_ARCH_REGS_PMU_H
#define __ASM_ARCH_REGS_PMU_H __FILE__
#include <mach/map.h>
#define S5P_PMUREG(x) (S5P_VA_PMU + (x))
#define S5P_PMU_CAM_CONF S5P_PMUREG(0x3C00)
#define S5P_PMU_TV_CONF S5P_PMUREG(0x3C20)
#define S5P_PMU_MFC_CONF S5P_PMUREG(0x3C40)
#define S5P_PMU_G3D_CONF S5P_PMUREG(0x3C60)
#define S5P_PMU_LCD0_CONF S5P_PMUREG(0x3C80)
#define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0)
#define S5P_PMU_GPS_CONF S5P_PMUREG(0x3CE0)
#define S5P_INT_LOCAL_PWR_EN 0x7
#endif /* __ASM_ARCH_REGS_PMU_H */
/* linux/arch/arm/mach-s5pv310/include/mach/regs-srom.h
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S5PV310 - SROMC register definitions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ASM_ARCH_REGS_SROM_H
#define __ASM_ARCH_REGS_SROM_H __FILE__
#include <mach/map.h>
#define S5PV310_SROMREG(x) (S5P_VA_SROMC + (x))
#define S5PV310_SROM_BW S5PV310_SROMREG(0x0)
#define S5PV310_SROM_BC0 S5PV310_SROMREG(0x4)
#define S5PV310_SROM_BC1 S5PV310_SROMREG(0x8)
#define S5PV310_SROM_BC2 S5PV310_SROMREG(0xc)
#define S5PV310_SROM_BC3 S5PV310_SROMREG(0x10)
/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
#define S5PV310_SROM_BW__DATAWIDTH__SHIFT 0
#define S5PV310_SROM_BW__ADDRMODE__SHIFT 1
#define S5PV310_SROM_BW__WAITENABLE__SHIFT 2
#define S5PV310_SROM_BW__BYTEENABLE__SHIFT 3
#define S5PV310_SROM_BW__CS_MASK 0xf
#define S5PV310_SROM_BW__NCS0__SHIFT 0
#define S5PV310_SROM_BW__NCS1__SHIFT 4
#define S5PV310_SROM_BW__NCS2__SHIFT 8
#define S5PV310_SROM_BW__NCS3__SHIFT 12
/* applies to same to BCS0 - BCS3 */
#define S5PV310_SROM_BCX__PMC__SHIFT 0
#define S5PV310_SROM_BCX__TACP__SHIFT 4
#define S5PV310_SROM_BCX__TCAH__SHIFT 8
#define S5PV310_SROM_BCX__TCOH__SHIFT 12
#define S5PV310_SROM_BCX__TACC__SHIFT 16
#define S5PV310_SROM_BCX__TCOS__SHIFT 24
#define S5PV310_SROM_BCX__TACS__SHIFT 28
#endif /* __ASM_ARCH_REGS_SROM_H */
/* linux/arch/arm/mach-s5pv310/include/mach/regs-sysmmu.h
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S5PV310 - System MMU register
*
* 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_REGS_SYSMMU_H
#define __ASM_ARCH_REGS_SYSMMU_H __FILE__
#define S5P_MMU_CTRL 0x000
#define S5P_MMU_CFG 0x004
#define S5P_MMU_STATUS 0x008
#define S5P_MMU_FLUSH 0x00C
#define S5P_PT_BASE_ADDR 0x014
#define S5P_INT_STATUS 0x018
#define S5P_PAGE_FAULT_ADDR 0x024
#endif /* __ASM_ARCH_REGS_SYSMMU_H */
此差异已折叠。
......@@ -24,29 +24,32 @@ static DEFINE_SPINLOCK(irq_controller_lock);
struct combiner_chip_data {
unsigned int irq_offset;
unsigned int irq_mask;
void __iomem *base;
};
static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
static inline void __iomem *combiner_base(unsigned int irq)
static inline void __iomem *combiner_base(struct irq_data *data)
{
struct combiner_chip_data *combiner_data = get_irq_chip_data(irq);
struct combiner_chip_data *combiner_data =
irq_data_get_irq_chip_data(data);
return combiner_data->base;
}
static void combiner_mask_irq(unsigned int irq)
static void combiner_mask_irq(struct irq_data *data)
{
u32 mask = 1 << (irq % 32);
u32 mask = 1 << (data->irq % 32);
__raw_writel(mask, combiner_base(irq) + COMBINER_ENABLE_CLEAR);
__raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR);
}
static void combiner_unmask_irq(unsigned int irq)
static void combiner_unmask_irq(struct irq_data *data)
{
u32 mask = 1 << (irq % 32);
u32 mask = 1 << (data->irq % 32);
__raw_writel(mask, combiner_base(irq) + COMBINER_ENABLE_SET);
__raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET);
}
static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
......@@ -57,11 +60,12 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
unsigned long status;
/* primary controller ack'ing */
chip->ack(irq);
chip->irq_ack(&desc->irq_data);
spin_lock(&irq_controller_lock);
status = __raw_readl(chip_data->base + COMBINER_INT_STATUS);
spin_unlock(&irq_controller_lock);
status &= chip_data->irq_mask;
if (status == 0)
goto out;
......@@ -76,13 +80,13 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
out:
/* primary controller unmasking */
chip->unmask(irq);
chip->irq_unmask(&desc->irq_data);
}
static struct irq_chip combiner_chip = {
.name = "COMBINER",
.mask = combiner_mask_irq,
.unmask = combiner_unmask_irq,
.irq_mask = combiner_mask_irq,
.irq_unmask = combiner_unmask_irq,
};
void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
......@@ -104,10 +108,12 @@ void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
combiner_data[combiner_nr].base = base;
combiner_data[combiner_nr].irq_offset = irq_start;
combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
/* Disable all interrupts */
__raw_writel(0xffffffff, base + COMBINER_ENABLE_CLEAR);
__raw_writel(combiner_data[combiner_nr].irq_mask,
base + COMBINER_ENABLE_CLEAR);
/* Setup the Linux IRQ subsystem */
......
此差异已折叠。
......@@ -194,7 +194,6 @@ void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_
memcpy(&s3c2410ts_info, hard_s3c2410ts_info, sizeof(struct s3c2410_ts_mach_info));
s3c_device_ts.dev.platform_data = &s3c2410ts_info;
}
EXPORT_SYMBOL(s3c24xx_ts_set_platdata);
/* USB Device (Gadget)*/
......
......@@ -107,9 +107,9 @@ s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
/* exported for use in arch/arm/mach-s3c2410 */
#ifdef CONFIG_PM
extern int s3c_irq_wake(unsigned int irqno, unsigned int state);
extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
#else
#define s3c_irq_wake NULL
#endif
extern int s3c_irqext_type(unsigned int irq, unsigned int type);
extern int s3c_irqext_type(struct irq_data *d, unsigned int type);
此差异已折叠。
此差异已折叠。
......@@ -271,7 +271,7 @@ static struct clk init_clocks[] = {
.ctrlbit = S3C2443_HCLKCON_DMA5,
}, {
.name = "hsmmc",
.id = 0,
.id = 1,
.parent = &clk_h,
.enable = s3c2443_clkcon_enable_h,
.ctrlbit = S3C2443_HCLKCON_HSMMC,
......
此差异已折叠。
......@@ -28,3 +28,6 @@ obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o
obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o
obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o
obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o
obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o
obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o
obj-$(CONFIG_S5P_SYSMMU) += sysmmu.o
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册