Commit ae852749 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge branch 'samsung/cleanup' into next/cleanup2

* samsung/cleanup:
  ARM: S3C64XX: Modified according to SPI consolidation work
  ARM: S5PV210: Modified files for SPI consolidation work
  ARM: S5P64X0: Modified files for SPI consolidation work
  ARM: S5PC100: Modified files for SPI consolidation work
  ARM: S3C64XX: Modified files for SPI consolidation work
  ARM: SAMSUNG: Consolidation of SPI platform devices to plat-samsung
  ARM: SAMSUNG: Remove SPI bus clocks from platform data
  ARM: S5PV210: Add SPI clkdev support
  ARM: S5P64X0: Add SPI clkdev support
  ARM: S5PC100: Add SPI clkdev support
  ARM: S3C64XX: Add SPI clkdev support
  spi/s3c64xx: Use bus clocks created using clkdev
  mmc: sdhci-s3c: Use generic clock names for sdhci bus clock options
  ARM: SAMSUNG: Add lookup of sdhci-s3c clocks using generic names
  ARM: SAMSUNG: Remove SDHCI bus clocks from platform data
parents 4eb82199 8a44930a
......@@ -58,6 +58,5 @@ obj-$(CONFIG_EXYNOS4_SETUP_I2C5) += setup-i2c5.o
obj-$(CONFIG_EXYNOS4_SETUP_I2C6) += setup-i2c6.o
obj-$(CONFIG_EXYNOS4_SETUP_I2C7) += setup-i2c7.o
obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o
obj-$(CONFIG_EXYNOS4_SETUP_SDHCI) += setup-sdhci.o
obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY) += setup-usb-phy.o
......@@ -1154,42 +1154,6 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clkset_mout_mfc,
.reg_src = { .reg = S5P_CLKSRC_MFC, .shift = 8, .size = 1 },
.reg_div = { .reg = S5P_CLKDIV_MFC, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.0",
.parent = &clk_dout_mmc0.clk,
.enable = exynos4_clksrc_mask_fsys_ctrl,
.ctrlbit = (1 << 0),
},
.reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
}, {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.1",
.parent = &clk_dout_mmc1.clk,
.enable = exynos4_clksrc_mask_fsys_ctrl,
.ctrlbit = (1 << 4),
},
.reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
}, {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.2",
.parent = &clk_dout_mmc2.clk,
.enable = exynos4_clksrc_mask_fsys_ctrl,
.ctrlbit = (1 << 8),
},
.reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
}, {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.3",
.parent = &clk_dout_mmc3.clk,
.enable = exynos4_clksrc_mask_fsys_ctrl,
.ctrlbit = (1 << 12),
},
.reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
}, {
.clk = {
.name = "sclk_dwmmc",
......@@ -1249,6 +1213,50 @@ static struct clksrc_clk clk_sclk_uart3 = {
.reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
};
static struct clksrc_clk clk_sclk_mmc0 = {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.0",
.parent = &clk_dout_mmc0.clk,
.enable = exynos4_clksrc_mask_fsys_ctrl,
.ctrlbit = (1 << 0),
},
.reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
};
static struct clksrc_clk clk_sclk_mmc1 = {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.1",
.parent = &clk_dout_mmc1.clk,
.enable = exynos4_clksrc_mask_fsys_ctrl,
.ctrlbit = (1 << 4),
},
.reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
};
static struct clksrc_clk clk_sclk_mmc2 = {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.2",
.parent = &clk_dout_mmc2.clk,
.enable = exynos4_clksrc_mask_fsys_ctrl,
.ctrlbit = (1 << 8),
},
.reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
};
static struct clksrc_clk clk_sclk_mmc3 = {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.3",
.parent = &clk_dout_mmc3.clk,
.enable = exynos4_clksrc_mask_fsys_ctrl,
.ctrlbit = (1 << 12),
},
.reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
};
/* Clock initialization code */
static struct clksrc_clk *sysclks[] = {
&clk_mout_apll,
......@@ -1293,6 +1301,10 @@ static struct clksrc_clk *clksrc_cdev[] = {
&clk_sclk_uart1,
&clk_sclk_uart2,
&clk_sclk_uart3,
&clk_sclk_mmc0,
&clk_sclk_mmc1,
&clk_sclk_mmc2,
&clk_sclk_mmc3,
};
static struct clk_lookup exynos4_clk_lookup[] = {
......@@ -1300,6 +1312,10 @@ static struct clk_lookup exynos4_clk_lookup[] = {
CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &clk_sclk_uart1.clk),
CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &clk_sclk_uart2.clk),
CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &clk_sclk_uart3.clk),
CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk),
CLKDEV_INIT("dma-pl330.0", "apb_pclk", &clk_pdma0),
CLKDEV_INIT("dma-pl330.1", "apb_pclk", &clk_pdma1),
};
......
/* linux/arch/arm/mach-exynos4/setup-sdhci.c
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* EXYNOS4 - Helper functions for settign up SDHCI device(s) (HSMMC)
*
* 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>
/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
char *exynos4_hsmmc_clksrcs[4] = {
[0] = NULL,
[1] = NULL,
[2] = "sclk_mmc", /* mmc_bus */
[3] = NULL,
};
......@@ -15,7 +15,6 @@ 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
......
......@@ -90,39 +90,38 @@ static struct clksrc_clk hsmmc_div[] = {
},
};
static struct clksrc_clk hsmmc_mux[] = {
[0] = {
.clk = {
.name = "hsmmc-if",
.devname = "s3c-sdhci.0",
.ctrlbit = (1 << 6),
.enable = s3c2443_clkcon_enable_s,
},
.sources = &(struct clksrc_sources) {
.nr_sources = 2,
.sources = (struct clk *[]) {
[0] = &hsmmc_div[0].clk,
[1] = NULL, /* to fix */
},
},
.reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 },
static struct clksrc_clk hsmmc_mux0 = {
.clk = {
.name = "hsmmc-if",
.devname = "s3c-sdhci.0",
.ctrlbit = (1 << 6),
.enable = s3c2443_clkcon_enable_s,
},
[1] = {
.clk = {
.name = "hsmmc-if",
.devname = "s3c-sdhci.1",
.ctrlbit = (1 << 12),
.enable = s3c2443_clkcon_enable_s,
.sources = &(struct clksrc_sources) {
.nr_sources = 2,
.sources = (struct clk * []) {
[0] = &hsmmc_div[0].clk,
[1] = NULL, /* to fix */
},
.sources = &(struct clksrc_sources) {
.nr_sources = 2,
.sources = (struct clk *[]) {
[0] = &hsmmc_div[1].clk,
[1] = NULL, /* to fix */
},
},
.reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 },
};
static struct clksrc_clk hsmmc_mux1 = {
.clk = {
.name = "hsmmc-if",
.devname = "s3c-sdhci.1",
.ctrlbit = (1 << 12),
.enable = s3c2443_clkcon_enable_s,
},
.sources = &(struct clksrc_sources) {
.nr_sources = 2,
.sources = (struct clk * []) {
[0] = &hsmmc_div[1].clk,
[1] = NULL, /* to fix */
},
.reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 },
},
.reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 },
};
static struct clk hsmmc0_clk = {
......@@ -144,8 +143,14 @@ static struct clksrc_clk *clksrcs[] __initdata = {
&hsspi_mux,
&hsmmc_div[0],
&hsmmc_div[1],
&hsmmc_mux[0],
&hsmmc_mux[1],
&hsmmc_mux0,
&hsmmc_mux1,
};
static struct clk_lookup s3c2416_clk_lookup[] = {
CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &hsmmc0_clk),
CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &hsmmc_mux0.clk),
CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &hsmmc_mux1.clk),
};
void __init s3c2416_init_clocks(int xtal)
......@@ -167,6 +172,7 @@ void __init s3c2416_init_clocks(int xtal)
s3c_register_clksrc(clksrcs[ptr], 1);
s3c24xx_register_clock(&hsmmc0_clk);
clkdev_add_table(s3c2416_clk_lookup, ARRAY_SIZE(s3c2416_clk_lookup));
s3c_pwmclk_init();
......
/* 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/types.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 */
};
......@@ -77,6 +77,11 @@ config S3C64XX_SETUP_SDHCI_GPIO
help
Common setup code for S3C64XX SDHCI GPIO configurations
config S3C64XX_SETUP_SPI
bool
help
Common setup code for SPI GPIO configurations
# S36400 Macchine support
config MACH_SMDK6400
......@@ -276,6 +281,7 @@ config MACH_WLF_CRAGG_6410
select S3C64XX_SETUP_IDE
select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_KEYPAD
select S3C64XX_SETUP_SPI
select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_KEYPAD
select S3C_DEV_USB_HOST
......@@ -286,7 +292,7 @@ config MACH_WLF_CRAGG_6410
select S3C_DEV_I2C1
select S3C_DEV_WDT
select S3C_DEV_RTC
select S3C64XX_DEV_SPI
select S3C64XX_DEV_SPI0
select S3C24XX_GPIO_EXTRA128
select I2C
help
......
......@@ -32,9 +32,9 @@ obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o
obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o
obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o
obj-$(CONFIG_S3C64XX_SETUP_SDHCI) += setup-sdhci.o
obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi.o
# PM
......@@ -60,4 +60,3 @@ obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o mach-crag6410-module.o
obj-y += dev-uart.o
obj-y += dev-audio.o
obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
......@@ -183,18 +183,6 @@ static struct clk init_clocks_off[] = {
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_SPI1,
}, {
.name = "spi_48m",
.devname = "s3c64xx-spi.0",
.parent = &clk_48m,
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_SPI0_48,
}, {
.name = "spi_48m",
.devname = "s3c64xx-spi.1",
.parent = &clk_48m,
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_SPI1_48,
}, {
.name = "48m",
.devname = "s3c-sdhci.0",
......@@ -226,6 +214,22 @@ static struct clk init_clocks_off[] = {
},
};
static struct clk clk_48m_spi0 = {
.name = "spi_48m",
.devname = "s3c64xx-spi.0",
.parent = &clk_48m,
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_SPI0_48,
};
static struct clk clk_48m_spi1 = {
.name = "spi_48m",
.devname = "s3c64xx-spi.1",
.parent = &clk_48m,
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_SPI1_48,
};
static struct clk init_clocks[] = {
{
.name = "lcd",
......@@ -242,24 +246,6 @@ static struct clk init_clocks[] = {
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_UHOST,
}, {
.name = "hsmmc",
.devname = "s3c-sdhci.0",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_HSMMC0,
}, {
.name = "hsmmc",
.devname = "s3c-sdhci.1",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_HSMMC1,
}, {
.name = "hsmmc",
.devname = "s3c-sdhci.2",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_HSMMC2,
}, {
.name = "otg",
.parent = &clk_h,
......@@ -310,6 +296,29 @@ static struct clk init_clocks[] = {
}
};
static struct clk clk_hsmmc0 = {
.name = "hsmmc",
.devname = "s3c-sdhci.0",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_HSMMC0,
};
static struct clk clk_hsmmc1 = {
.name = "hsmmc",
.devname = "s3c-sdhci.1",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_HSMMC1,
};
static struct clk clk_hsmmc2 = {
.name = "hsmmc",
.devname = "s3c-sdhci.2",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_HSMMC2,
};
static struct clk clk_fout_apll = {
.name = "fout_apll",
......@@ -577,36 +586,6 @@ static struct clksrc_sources clkset_camif = {
static struct clksrc_clk clksrcs[] = {
{
.clk = {
.name = "mmc_bus",
.devname = "s3c-sdhci.0",
.ctrlbit = S3C_CLKCON_SCLK_MMC0,
.enable = s3c64xx_sclk_ctrl,
},
.reg_src = { .reg = S3C_CLK_SRC, .shift = 18, .size = 2 },
.reg_div = { .reg = S3C_CLK_DIV1, .shift = 0, .size = 4 },
.sources = &clkset_spi_mmc,
}, {
.clk = {
.name = "mmc_bus",
.devname = "s3c-sdhci.1",
.ctrlbit = S3C_CLKCON_SCLK_MMC1,
.enable = s3c64xx_sclk_ctrl,
},
.reg_src = { .reg = S3C_CLK_SRC, .shift = 20, .size = 2 },
.reg_div = { .reg = S3C_CLK_DIV1, .shift = 4, .size = 4 },
.sources = &clkset_spi_mmc,
}, {
.clk = {
.name = "mmc_bus",
.devname = "s3c-sdhci.2",
.ctrlbit = S3C_CLKCON_SCLK_MMC2,
.enable = s3c64xx_sclk_ctrl,
},
.reg_src = { .reg = S3C_CLK_SRC, .shift = 22, .size = 2 },
.reg_div = { .reg = S3C_CLK_DIV1, .shift = 8, .size = 4 },
.sources = &clkset_spi_mmc,
}, {
.clk = {
.name = "usb-bus-host",
.ctrlbit = S3C_CLKCON_SCLK_UHOST,
......@@ -615,25 +594,6 @@ static struct clksrc_clk clksrcs[] = {
.reg_src = { .reg = S3C_CLK_SRC, .shift = 5, .size = 2 },
.reg_div = { .reg = S3C_CLK_DIV1, .shift = 20, .size = 4 },
.sources = &clkset_uhost,
}, {
.clk = {
.name = "spi-bus",
.devname = "s3c64xx-spi.0",
.ctrlbit = S3C_CLKCON_SCLK_SPI0,
.enable = s3c64xx_sclk_ctrl,
},
.reg_src = { .reg = S3C_CLK_SRC, .shift = 14, .size = 2 },
.reg_div = { .reg = S3C_CLK_DIV2, .shift = 0, .size = 4 },
.sources = &clkset_spi_mmc,
}, {
.clk = {
.name = "spi-bus",
.devname = "s3c64xx-spi.1",
.enable = s3c64xx_sclk_ctrl,
},
.reg_src = { .reg = S3C_CLK_SRC, .shift = 16, .size = 2 },
.reg_div = { .reg = S3C_CLK_DIV2, .shift = 4, .size = 4 },
.sources = &clkset_spi_mmc,
}, {
.clk = {
.name = "audio-bus",
......@@ -697,6 +657,66 @@ static struct clksrc_clk clk_sclk_uclk = {
.sources = &clkset_uart,
};
static struct clksrc_clk clk_sclk_mmc0 = {
.clk = {
.name = "mmc_bus",
.devname = "s3c-sdhci.0",
.ctrlbit = S3C_CLKCON_SCLK_MMC0,
.enable = s3c64xx_sclk_ctrl,
},
.reg_src = { .reg = S3C_CLK_SRC, .shift = 18, .size = 2 },
.reg_div = { .reg = S3C_CLK_DIV1, .shift = 0, .size = 4 },
.sources = &clkset_spi_mmc,
};
static struct clksrc_clk clk_sclk_mmc1 = {
.clk = {
.name = "mmc_bus",
.devname = "s3c-sdhci.1",
.ctrlbit = S3C_CLKCON_SCLK_MMC1,
.enable = s3c64xx_sclk_ctrl,
},
.reg_src = { .reg = S3C_CLK_SRC, .shift = 20, .size = 2 },
.reg_div = { .reg = S3C_CLK_DIV1, .shift = 4, .size = 4 },
.sources = &clkset_spi_mmc,
};
static struct clksrc_clk clk_sclk_mmc2 = {
.clk = {
.name = "mmc_bus",
.devname = "s3c-sdhci.2",
.ctrlbit = S3C_CLKCON_SCLK_MMC2,
.enable = s3c64xx_sclk_ctrl,
},
.reg_src = { .reg = S3C_CLK_SRC, .shift = 22, .size = 2 },
.reg_div = { .reg = S3C_CLK_DIV1, .shift = 8, .size = 4 },
.sources = &clkset_spi_mmc,
};
static struct clksrc_clk clk_sclk_spi0 = {
.clk = {
.name = "spi-bus",
.devname = "s3c64xx-spi.0",
.ctrlbit = S3C_CLKCON_SCLK_SPI0,
.enable = s3c64xx_sclk_ctrl,
},
.reg_src = { .reg = S3C_CLK_SRC, .shift = 14, .size = 2 },
.reg_div = { .reg = S3C_CLK_DIV2, .shift = 0, .size = 4 },
.sources = &clkset_spi_mmc,
};
static struct clksrc_clk clk_sclk_spi1 = {
.clk = {
.name = "spi-bus",
.devname = "s3c64xx-spi.1",
.ctrlbit = S3C_CLKCON_SCLK_SPI1,
.enable = s3c64xx_sclk_ctrl,
},
.reg_src = { .reg = S3C_CLK_SRC, .shift = 16, .size = 2 },
.reg_div = { .reg = S3C_CLK_DIV2, .shift = 4, .size = 4 },
.sources = &clkset_spi_mmc,
};
/* Clock initialisation code */
static struct clksrc_clk *init_parents[] = {
......@@ -707,11 +727,35 @@ static struct clksrc_clk *init_parents[] = {
static struct clksrc_clk *clksrc_cdev[] = {
&clk_sclk_uclk,
&clk_sclk_mmc0,
&clk_sclk_mmc1,
&clk_sclk_mmc2,
&clk_sclk_spi0,
&clk_sclk_spi1,
};
static struct clk *clk_cdev[] = {
&clk_hsmmc0,
&clk_hsmmc1,
&clk_hsmmc2,
&clk_48m_spi0,
&clk_48m_spi1,
};
static struct clk_lookup s3c64xx_clk_lookup[] = {
CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0),
CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1),
CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2),
CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &clk_48m_spi0),
CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk2", &clk_48m_spi1),
};
#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
......@@ -834,6 +878,10 @@ void __init s3c64xx_register_clocks(unsigned long xtal,
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev));
for (cnt = 0; cnt < ARRAY_SIZE(clk_cdev); cnt++)
s3c_disable_clocks(clk_cdev[cnt], 1);
s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1));
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
for (cnt = 0; cnt < ARRAY_SIZE(clksrc_cdev); cnt++)
......
/* linux/arch/arm/plat-s3c64xx/dev-spi.c
*
* Copyright (C) 2009 Samsung Electronics Ltd.
* Jaswinder Singh <jassi.brar@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <mach/dma.h>
#include <mach/map.h>
#include <mach/spi-clocks.h>
#include <mach/irqs.h>
#include <plat/s3c64xx-spi.h>
#include <plat/gpio-cfg.h>
#include <plat/devs.h>
static char *spi_src_clks[] = {
[S3C64XX_SPI_SRCCLK_PCLK] = "pclk",
[S3C64XX_SPI_SRCCLK_SPIBUS] = "spi-bus",
[S3C64XX_SPI_SRCCLK_48M] = "spi_48m",
};
/* SPI Controller platform_devices */
/* Since we emulate multi-cs capability, we do not touch the GPC-3,7.
* The emulated CS is toggled by board specific mechanism, as it can
* be either some immediate GPIO or some signal out of some other
* chip in between ... or some yet another way.
* We simply do not assume anything about CS.
*/
static int s3c64xx_spi_cfg_gpio(struct platform_device *pdev)
{
unsigned int base;
switch (pdev->id) {
case 0:
base = S3C64XX_GPC(0);
break;
case 1:
base = S3C64XX_GPC(4);
break;
default:
dev_err(&pdev->dev, "Invalid SPI Controller number!");
return -EINVAL;
}
s3c_gpio_cfgall_range(base, 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0;
}
static struct resource s3c64xx_spi0_resource[] = {
[0] = {
.start = S3C64XX_PA_SPI0,
.end = S3C64XX_PA_SPI0 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_SPI0_TX,
.end = DMACH_SPI0_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_SPI0_RX,
.end = DMACH_SPI0_RX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = IRQ_SPI0,
.end = IRQ_SPI0,
.flags = IORESOURCE_IRQ,
},
};
static struct s3c64xx_spi_info s3c64xx_spi0_pdata = {
.cfg_gpio = s3c64xx_spi_cfg_gpio,
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 13,
.tx_st_done = 21,
};
static u64 spi_dmamask = DMA_BIT_MASK(32);
struct platform_device s3c64xx_device_spi0 = {
.name = "s3c64xx-spi",
.id = 0,
.num_resources = ARRAY_SIZE(s3c64xx_spi0_resource),
.resource = s3c64xx_spi0_resource,
.dev = {
.dma_mask = &spi_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &s3c64xx_spi0_pdata,
},
};
EXPORT_SYMBOL(s3c64xx_device_spi0);
static struct resource s3c64xx_spi1_resource[] = {
[0] = {
.start = S3C64XX_PA_SPI1,
.end = S3C64XX_PA_SPI1 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_SPI1_TX,
.end = DMACH_SPI1_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_SPI1_RX,
.end = DMACH_SPI1_RX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = IRQ_SPI1,
.end = IRQ_SPI1,
.flags = IORESOURCE_IRQ,
},
};
static struct s3c64xx_spi_info s3c64xx_spi1_pdata = {
.cfg_gpio = s3c64xx_spi_cfg_gpio,
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 13,
.tx_st_done = 21,
};
struct platform_device s3c64xx_device_spi1 = {
.name = "s3c64xx-spi",
.id = 1,
.num_resources = ARRAY_SIZE(s3c64xx_spi1_resource),
.resource = s3c64xx_spi1_resource,
.dev = {
.dma_mask = &spi_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &s3c64xx_spi1_pdata,
},
};
EXPORT_SYMBOL(s3c64xx_device_spi1);
void __init s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
{
struct s3c64xx_spi_info *pd;
/* Reject invalid configuration */
if (!num_cs || src_clk_nr < 0
|| src_clk_nr > S3C64XX_SPI_SRCCLK_48M) {
printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
return;
}
switch (cntrlr) {
case 0:
pd = &s3c64xx_spi0_pdata;
break;
case 1:
pd = &s3c64xx_spi1_pdata;
break;
default:
printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
__func__, cntrlr);
return;
}
pd->num_cs = num_cs;
pd->src_clk_nr = src_clk_nr;
pd->src_clk_name = spi_src_clks[src_clk_nr];
}
......@@ -115,6 +115,8 @@
#define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG
#define S3C_PA_RTC S3C64XX_PA_RTC
#define S3C_PA_WDT S3C64XX_PA_WATCHDOG
#define S3C_PA_SPI0 S3C64XX_PA_SPI0
#define S3C_PA_SPI1 S3C64XX_PA_SPI1
#define SAMSUNG_PA_ADC S3C64XX_PA_ADC
#define SAMSUNG_PA_CFCON S3C64XX_PA_CFCON
......
/* linux/arch/arm/mach-s3c64xx/setup-sdhci.c
*
* Copyright 2008 Simtec Electronics
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C6400/S3C6410 - Helper functions for settign up SDHCI device(s) (HSMMC)
*
* 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>
/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
char *s3c64xx_hsmmc_clksrcs[4] = {
[0] = "hsmmc",
[1] = "hsmmc",
[2] = "mmc_bus",
/* [3] = "48m", - note not successfully used yet */
};
/* linux/arch/arm/mach-s3c64xx/setup-spi.c
*
* Copyright (C) 2011 Samsung Electronics 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/gpio.h>
#include <linux/platform_device.h>
#include <plat/gpio-cfg.h>
#include <plat/s3c64xx-spi.h>
#ifdef CONFIG_S3C64XX_DEV_SPI0
struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = {
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 13,
.tx_st_done = 21,
};
int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgall_range(S3C64XX_GPC(0), 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0;
}
#endif
#ifdef CONFIG_S3C64XX_DEV_SPI1
struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = {
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 13,
.tx_st_done = 21,
};
int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgall_range(S3C64XX_GPC(4), 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0;
}
#endif
......@@ -36,6 +36,11 @@ config S5P64X0_SETUP_I2C1
help
Common setup code for i2c bus 1.
config S5P64X0_SETUP_SPI
bool
help
Common setup code for SPI GPIO configurations
# machine support
config MACH_SMDK6440
......@@ -45,7 +50,6 @@ config MACH_SMDK6440
select S3C_DEV_I2C1
select S3C_DEV_RTC
select S3C_DEV_WDT
select S3C64XX_DEV_SPI
select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_PWM
......@@ -62,7 +66,6 @@ config MACH_SMDK6450
select S3C_DEV_I2C1
select S3C_DEV_RTC
select S3C_DEV_WDT
select S3C64XX_DEV_SPI
select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_PWM
......
......@@ -26,7 +26,7 @@ obj-$(CONFIG_MACH_SMDK6450) += mach-smdk6450.o
# device support
obj-y += dev-audio.o
obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
obj-$(CONFIG_S5P64X0_SETUP_I2C1) += setup-i2c1.o
obj-$(CONFIG_S5P64X0_SETUP_FB_24BPP) += setup-fb-24bpp.o
obj-$(CONFIG_S5P64X0_SETUP_SPI) += setup-spi.o
......@@ -267,18 +267,6 @@ static struct clk init_clocks_off[] = {
.parent = &clk_pclk.clk,
.enable = s5p64x0_pclk_ctrl,
.ctrlbit = (1 << 31),
}, {
.name = "sclk_spi_48",
.devname = "s3c64xx-spi.0",
.parent = &clk_48m,
.enable = s5p64x0_sclk_ctrl,
.ctrlbit = (1 << 22),
}, {
.name = "sclk_spi_48",
.devname = "s3c64xx-spi.1",
.parent = &clk_48m,
.enable = s5p64x0_sclk_ctrl,
.ctrlbit = (1 << 23),
}, {
.name = "mmc_48m",
.devname = "s3c-sdhci.0",
......@@ -419,26 +407,6 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clkset_group1,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
.reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
}, {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.0",
.ctrlbit = (1 << 20),
.enable = s5p64x0_sclk_ctrl,
},
.sources = &clkset_group1,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
.reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.1",
.ctrlbit = (1 << 21),
.enable = s5p64x0_sclk_ctrl,
},
.sources = &clkset_group1,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
.reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
}, {
.clk = {
.name = "sclk_post",
......@@ -489,6 +457,30 @@ static struct clksrc_clk clk_sclk_uclk = {
.reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
};
static struct clksrc_clk clk_sclk_spi0 = {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.0",
.ctrlbit = (1 << 20),
.enable = s5p64x0_sclk_ctrl,
},
.sources = &clkset_group1,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
.reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
};
static struct clksrc_clk clk_sclk_spi1 = {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.1",
.ctrlbit = (1 << 21),
.enable = s5p64x0_sclk_ctrl,
},
.sources = &clkset_group1,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
.reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
};
/* Clock initialization code */
static struct clksrc_clk *sysclks[] = {
&clk_mout_apll,
......@@ -509,11 +501,16 @@ static struct clk dummy_apb_pclk = {
static struct clksrc_clk *clksrc_cdev[] = {
&clk_sclk_uclk,
&clk_sclk_spi0,
&clk_sclk_spi1,
};
static struct clk_lookup s5p6440_clk_lookup[] = {
CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
};
void __init_or_cpufreq s5p6440_setup_clocks(void)
......
......@@ -441,26 +441,6 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clkset_group2,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
.reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
}, {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.0",
.ctrlbit = (1 << 20),
.enable = s5p64x0_sclk_ctrl,
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
.reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.1",
.ctrlbit = (1 << 21),
.enable = s5p64x0_sclk_ctrl,
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
.reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
}, {
.clk = {
.name = "sclk_fimc",
......@@ -538,13 +518,42 @@ static struct clksrc_clk clk_sclk_uclk = {
.reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
};
static struct clksrc_clk clk_sclk_spi0 = {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.0",
.ctrlbit = (1 << 20),
.enable = s5p64x0_sclk_ctrl,
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
.reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
};
static struct clksrc_clk clk_sclk_spi1 = {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.1",
.ctrlbit = (1 << 21),
.enable = s5p64x0_sclk_ctrl,
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
.reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
};
static struct clksrc_clk *clksrc_cdev[] = {
&clk_sclk_uclk,
&clk_sclk_spi0,
&clk_sclk_spi1,
};
static struct clk_lookup s5p6450_clk_lookup[] = {
CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
};
/* Clock initialization code */
......
/* linux/arch/arm/mach-s5p64x0/dev-spi.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* 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 <mach/dma.h>
#include <mach/map.h>
#include <mach/irqs.h>
#include <mach/regs-clock.h>
#include <mach/spi-clocks.h>
#include <plat/cpu.h>
#include <plat/s3c64xx-spi.h>
#include <plat/gpio-cfg.h>
static char *s5p64x0_spi_src_clks[] = {
[S5P64X0_SPI_SRCCLK_PCLK] = "pclk",
[S5P64X0_SPI_SRCCLK_SCLK] = "sclk_spi",
};
/* SPI Controller platform_devices */
/* Since we emulate multi-cs capability, we do not touch the CS.
* The emulated CS is toggled by board specific mechanism, as it can
* be either some immediate GPIO or some signal out of some other
* chip in between ... or some yet another way.
* We simply do not assume anything about CS.
*/
static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
{
unsigned int base;
switch (pdev->id) {
case 0:
base = S5P6440_GPC(0);
break;
case 1:
base = S5P6440_GPC(4);
break;
default:
dev_err(&pdev->dev, "Invalid SPI Controller number!");
return -EINVAL;
}
s3c_gpio_cfgall_range(base, 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0;
}
static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
{
unsigned int base;
switch (pdev->id) {
case 0:
base = S5P6450_GPC(0);
break;
case 1:
base = S5P6450_GPC(4);
break;
default:
dev_err(&pdev->dev, "Invalid SPI Controller number!");
return -EINVAL;
}
s3c_gpio_cfgall_range(base, 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0;
}
static struct resource s5p64x0_spi0_resource[] = {
[0] = {
.start = S5P64X0_PA_SPI0,
.end = S5P64X0_PA_SPI0 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_SPI0_TX,
.end = DMACH_SPI0_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_SPI0_RX,
.end = DMACH_SPI0_RX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = IRQ_SPI0,
.end = IRQ_SPI0,
.flags = IORESOURCE_IRQ,
},
};
static struct s3c64xx_spi_info s5p6440_spi0_pdata = {
.cfg_gpio = s5p6440_spi_cfg_gpio,
.fifo_lvl_mask = 0x1ff,
.rx_lvl_offset = 15,
.tx_st_done = 25,
};
static struct s3c64xx_spi_info s5p6450_spi0_pdata = {
.cfg_gpio = s5p6450_spi_cfg_gpio,
.fifo_lvl_mask = 0x1ff,
.rx_lvl_offset = 15,
.tx_st_done = 25,
};
static u64 spi_dmamask = DMA_BIT_MASK(32);
struct platform_device s5p64x0_device_spi0 = {
.name = "s3c64xx-spi",
.id = 0,
.num_resources = ARRAY_SIZE(s5p64x0_spi0_resource),
.resource = s5p64x0_spi0_resource,
.dev = {
.dma_mask = &spi_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
static struct resource s5p64x0_spi1_resource[] = {
[0] = {
.start = S5P64X0_PA_SPI1,
.end = S5P64X0_PA_SPI1 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_SPI1_TX,
.end = DMACH_SPI1_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_SPI1_RX,
.end = DMACH_SPI1_RX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = IRQ_SPI1,
.end = IRQ_SPI1,
.flags = IORESOURCE_IRQ,
},
};
static struct s3c64xx_spi_info s5p6440_spi1_pdata = {
.cfg_gpio = s5p6440_spi_cfg_gpio,
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 15,
.tx_st_done = 25,
};
static struct s3c64xx_spi_info s5p6450_spi1_pdata = {
.cfg_gpio = s5p6450_spi_cfg_gpio,
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 15,
.tx_st_done = 25,
};
struct platform_device s5p64x0_device_spi1 = {
.name = "s3c64xx-spi",
.id = 1,
.num_resources = ARRAY_SIZE(s5p64x0_spi1_resource),
.resource = s5p64x0_spi1_resource,
.dev = {
.dma_mask = &spi_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
void __init s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
{
struct s3c64xx_spi_info *pd;
/* Reject invalid configuration */
if (!num_cs || src_clk_nr < 0
|| src_clk_nr > S5P64X0_SPI_SRCCLK_SCLK) {
printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
return;
}
switch (cntrlr) {
case 0:
if (soc_is_s5p6450())
pd = &s5p6450_spi0_pdata;
else
pd = &s5p6440_spi0_pdata;
s5p64x0_device_spi0.dev.platform_data = pd;
break;
case 1:
if (soc_is_s5p6450())
pd = &s5p6450_spi1_pdata;
else
pd = &s5p6440_spi1_pdata;
s5p64x0_device_spi1.dev.platform_data = pd;
break;
default:
printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
__func__, cntrlr);
return;
}
pd->num_cs = num_cs;
pd->src_clk_nr = src_clk_nr;
pd->src_clk_name = s5p64x0_spi_src_clks[src_clk_nr];
}
......@@ -67,6 +67,8 @@
#define S3C_PA_RTC S5P64X0_PA_RTC
#define S3C_PA_WDT S5P64X0_PA_WDT
#define S3C_PA_FB S5P64X0_PA_FB
#define S3C_PA_SPI0 S5P64X0_PA_SPI0
#define S3C_PA_SPI1 S5P64X0_PA_SPI1
#define S5P_PA_CHIPID S5P64X0_PA_CHIPID
#define S5P_PA_SROMC S5P64X0_PA_SROMC
......
/* linux/arch/arm/mach-s5p64x0/setup-spi.c
*
* Copyright (C) 2011 Samsung Electronics 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/gpio.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <plat/gpio-cfg.h>
#include <plat/cpu.h>
#include <plat/s3c64xx-spi.h>
#ifdef CONFIG_S3C64XX_DEV_SPI0
struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = {
.fifo_lvl_mask = 0x1ff,
.rx_lvl_offset = 15,
.tx_st_done = 25,
};
int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
{
if (soc_is_s5p6450())
s3c_gpio_cfgall_range(S5P6450_GPC(0), 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
else
s3c_gpio_cfgall_range(S5P6440_GPC(0), 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0;
}
#endif
#ifdef CONFIG_S3C64XX_DEV_SPI1
struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = {
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 15,
.tx_st_done = 25,
};
int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
{
if (soc_is_s5p6450())
s3c_gpio_cfgall_range(S5P6450_GPC(4), 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
else
s3c_gpio_cfgall_range(S5P6440_GPC(4), 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0;
}
#endif
......@@ -45,6 +45,11 @@ config S5PC100_SETUP_SDHCI_GPIO
help
Common setup code for SDHCI gpio.
config S5PC100_SETUP_SPI
bool
help
Common setup code for SPI GPIO configurations.
config MACH_SMDKC100
bool "SMDKC100"
select CPU_S5PC100
......
......@@ -21,12 +21,11 @@ obj-$(CONFIG_S5PC100_SETUP_FB_24BPP) += setup-fb-24bpp.o
obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o
obj-$(CONFIG_S5PC100_SETUP_IDE) += setup-ide.o
obj-$(CONFIG_S5PC100_SETUP_KEYPAD) += setup-keypad.o
obj-$(CONFIG_S5PC100_SETUP_SDHCI) += setup-sdhci.o
obj-$(CONFIG_S5PC100_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
obj-$(CONFIG_S5PC100_SETUP_SPI) += setup-spi.o
# device support
obj-y += dev-audio.o
obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
# machine support
......
......@@ -425,24 +425,6 @@ static struct clk init_clocks_off[] = {
.parent = &clk_div_d0_bus.clk,
.enable = s5pc100_d0_2_ctrl,
.ctrlbit = (1 << 1),
}, {
.name = "hsmmc",
.devname = "s3c-sdhci.2",
.parent = &clk_div_d1_bus.clk,
.enable = s5pc100_d1_0_ctrl,
.ctrlbit = (1 << 7),
}, {
.name = "hsmmc",
.devname = "s3c-sdhci.1",
.parent = &clk_div_d1_bus.clk,
.enable = s5pc100_d1_0_ctrl,
.ctrlbit = (1 << 6),
}, {
.name = "hsmmc",
.devname = "s3c-sdhci.0",
.parent = &clk_div_d1_bus.clk,
.enable = s5pc100_d1_0_ctrl,
.ctrlbit = (1 << 5),
}, {
.name = "modemif",
.parent = &clk_div_d1_bus.clk,
......@@ -672,24 +654,6 @@ static struct clk init_clocks_off[] = {
.parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 8),
}, {
.name = "spi_48m",
.devname = "s3c64xx-spi.0",
.parent = &clk_mout_48m.clk,
.enable = s5pc100_sclk0_ctrl,
.ctrlbit = (1 << 7),
}, {
.name = "spi_48m",
.devname = "s3c64xx-spi.1",
.parent = &clk_mout_48m.clk,
.enable = s5pc100_sclk0_ctrl,
.ctrlbit = (1 << 8),
}, {
.name = "spi_48m",
.devname = "s3c64xx-spi.2",
.parent = &clk_mout_48m.clk,
.enable = s5pc100_sclk0_ctrl,
.ctrlbit = (1 << 9),
}, {
.name = "mmc_48m",
.devname = "s3c-sdhci.0",
......@@ -711,6 +675,54 @@ static struct clk init_clocks_off[] = {
},
};
static struct clk clk_hsmmc2 = {
.name = "hsmmc",
.devname = "s3c-sdhci.2",
.parent = &clk_div_d1_bus.clk,
.enable = s5pc100_d1_0_ctrl,
.ctrlbit = (1 << 7),
};
static struct clk clk_hsmmc1 = {
.name = "hsmmc",
.devname = "s3c-sdhci.1",
.parent = &clk_div_d1_bus.clk,
.enable = s5pc100_d1_0_ctrl,
.ctrlbit = (1 << 6),
};
static struct clk clk_hsmmc0 = {
.name = "hsmmc",
.devname = "s3c-sdhci.0",
.parent = &clk_div_d1_bus.clk,
.enable = s5pc100_d1_0_ctrl,
.ctrlbit = (1 << 5),
};
static struct clk clk_48m_spi0 = {
.name = "spi_48m",
.devname = "s3c64xx-spi.0",
.parent = &clk_mout_48m.clk,
.enable = s5pc100_sclk0_ctrl,
.ctrlbit = (1 << 7),
};
static struct clk clk_48m_spi1 = {
.name = "spi_48m",
.devname = "s3c64xx-spi.1",
.parent = &clk_mout_48m.clk,
.enable = s5pc100_sclk0_ctrl,
.ctrlbit = (1 << 8),
};
static struct clk clk_48m_spi2 = {
.name = "spi_48m",
.devname = "s3c64xx-spi.2",
.parent = &clk_mout_48m.clk,
.enable = s5pc100_sclk0_ctrl,
.ctrlbit = (1 << 9),
};
static struct clk clk_vclk54m = {
.name = "vclk_54m",
.rate = 54000000,
......@@ -928,39 +940,6 @@ static struct clksrc_clk clk_sclk_spdif = {
static struct clksrc_clk clksrcs[] = {
{
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.0",
.ctrlbit = (1 << 4),
.enable = s5pc100_sclk0_ctrl,
},
.sources = &clk_src_group1,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 },
.reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
}, {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.1",
.ctrlbit = (1 << 5),
.enable = s5pc100_sclk0_ctrl,
},
.sources = &clk_src_group1,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 },
.reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
}, {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.2",
.ctrlbit = (1 << 6),
.enable = s5pc100_sclk0_ctrl,
},
.sources = &clk_src_group1,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 2 },
.reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 },
}, {
.clk = {
.name = "sclk_mixer",
.ctrlbit = (1 << 6),
......@@ -1012,39 +991,6 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clk_src_group7,
.reg_src = { .reg = S5P_CLK_SRC2, .shift = 24, .size = 2 },
.reg_div = { .reg = S5P_CLK_DIV3, .shift = 24, .size = 4 },
}, {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.0",
.ctrlbit = (1 << 12),
.enable = s5pc100_sclk1_ctrl,
},
.sources = &clk_src_mmc0,
.reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
.reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.1",
.ctrlbit = (1 << 13),
.enable = s5pc100_sclk1_ctrl,
},
.sources = &clk_src_mmc12,
.reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
.reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 },
}, {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.2",
.ctrlbit = (1 << 14),
.enable = s5pc100_sclk1_ctrl,
},
.sources = &clk_src_mmc12,
.reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
.reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 },
}, {
.clk = {
.name = "sclk_irda",
......@@ -1099,6 +1045,78 @@ static struct clksrc_clk clk_sclk_uart = {
.reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
};
static struct clksrc_clk clk_sclk_mmc0 = {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.0",
.ctrlbit = (1 << 12),
.enable = s5pc100_sclk1_ctrl,
},
.sources = &clk_src_mmc0,
.reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
.reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 },
};
static struct clksrc_clk clk_sclk_mmc1 = {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.1",
.ctrlbit = (1 << 13),
.enable = s5pc100_sclk1_ctrl,
},
.sources = &clk_src_mmc12,
.reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
.reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 },
};
static struct clksrc_clk clk_sclk_mmc2 = {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.2",
.ctrlbit = (1 << 14),
.enable = s5pc100_sclk1_ctrl,
},
.sources = &clk_src_mmc12,
.reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
.reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 },
};
static struct clksrc_clk clk_sclk_spi0 = {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.0",
.ctrlbit = (1 << 4),
.enable = s5pc100_sclk0_ctrl,
},
.sources = &clk_src_group1,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 },
.reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
};
static struct clksrc_clk clk_sclk_spi1 = {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.1",
.ctrlbit = (1 << 5),
.enable = s5pc100_sclk0_ctrl,
},
.sources = &clk_src_group1,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 },
.reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
};
static struct clksrc_clk clk_sclk_spi2 = {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.2",
.ctrlbit = (1 << 6),
.enable = s5pc100_sclk0_ctrl,
},
.sources = &clk_src_group1,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 2 },
.reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 },
};
/* Clock initialisation code */
static struct clksrc_clk *sysclks[] = {
&clk_mout_apll,
......@@ -1128,8 +1146,23 @@ static struct clksrc_clk *sysclks[] = {
&clk_sclk_spdif,
};
static struct clk *clk_cdev[] = {
&clk_hsmmc0,
&clk_hsmmc1,
&clk_hsmmc2,
&clk_48m_spi0,
&clk_48m_spi1,
&clk_48m_spi2,
};
static struct clksrc_clk *clksrc_cdev[] = {
&clk_sclk_uart,
&clk_sclk_mmc0,
&clk_sclk_mmc1,
&clk_sclk_mmc2,
&clk_sclk_spi0,
&clk_sclk_spi1,
&clk_sclk_spi2,
};
void __init_or_cpufreq s5pc100_setup_clocks(void)
......@@ -1274,6 +1307,19 @@ static struct clk *clks[] __initdata = {
static struct clk_lookup s5pc100_clk_lookup[] = {
CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uart.clk),
CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0),
CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1),
CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2),
CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_48m_spi0),
CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &clk_sclk_spi0.clk),
CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_48m_spi1),
CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk2", &clk_sclk_spi1.clk),
CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk1", &clk_48m_spi2),
CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk2", &clk_sclk_spi2.clk),
};
void __init s5pc100_register_clocks(void)
......@@ -1294,6 +1340,10 @@ void __init s5pc100_register_clocks(void)
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
clkdev_add_table(s5pc100_clk_lookup, ARRAY_SIZE(s5pc100_clk_lookup));
s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev));
for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++)
s3c_disable_clocks(clk_cdev[ptr], 1);
s3c24xx_register_clock(&dummy_apb_pclk);
s3c_pwmclk_init();
......
/* linux/arch/arm/mach-s5pc100/dev-spi.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 <mach/dma.h>
#include <mach/map.h>
#include <mach/spi-clocks.h>
#include <mach/irqs.h>
#include <plat/s3c64xx-spi.h>
#include <plat/gpio-cfg.h>
#include <plat/irqs.h>
static char *spi_src_clks[] = {
[S5PC100_SPI_SRCCLK_PCLK] = "pclk",
[S5PC100_SPI_SRCCLK_48M] = "spi_48m",
[S5PC100_SPI_SRCCLK_SPIBUS] = "spi_bus",
};
/* SPI Controller platform_devices */
/* Since we emulate multi-cs capability, we do not touch the CS.
* The emulated CS is toggled by board specific mechanism, as it can
* be either some immediate GPIO or some signal out of some other
* chip in between ... or some yet another way.
* We simply do not assume anything about CS.
*/
static int s5pc100_spi_cfg_gpio(struct platform_device *pdev)
{
switch (pdev->id) {
case 0:
s3c_gpio_cfgall_range(S5PC100_GPB(0), 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
break;
case 1:
s3c_gpio_cfgall_range(S5PC100_GPB(4), 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
break;
case 2:
s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(3));
s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5PC100_GPB(2), 2,
S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
break;
default:
dev_err(&pdev->dev, "Invalid SPI Controller number!");
return -EINVAL;
}
return 0;
}
static struct resource s5pc100_spi0_resource[] = {
[0] = {
.start = S5PC100_PA_SPI0,
.end = S5PC100_PA_SPI0 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_SPI0_TX,
.end = DMACH_SPI0_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_SPI0_RX,
.end = DMACH_SPI0_RX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = IRQ_SPI0,
.end = IRQ_SPI0,
.flags = IORESOURCE_IRQ,
},
};
static struct s3c64xx_spi_info s5pc100_spi0_pdata = {
.cfg_gpio = s5pc100_spi_cfg_gpio,
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 13,
.high_speed = 1,
.tx_st_done = 21,
};
static u64 spi_dmamask = DMA_BIT_MASK(32);
struct platform_device s5pc100_device_spi0 = {
.name = "s3c64xx-spi",
.id = 0,
.num_resources = ARRAY_SIZE(s5pc100_spi0_resource),
.resource = s5pc100_spi0_resource,
.dev = {
.dma_mask = &spi_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &s5pc100_spi0_pdata,
},
};
static struct resource s5pc100_spi1_resource[] = {
[0] = {
.start = S5PC100_PA_SPI1,
.end = S5PC100_PA_SPI1 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_SPI1_TX,
.end = DMACH_SPI1_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_SPI1_RX,
.end = DMACH_SPI1_RX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = IRQ_SPI1,
.end = IRQ_SPI1,
.flags = IORESOURCE_IRQ,
},
};
static struct s3c64xx_spi_info s5pc100_spi1_pdata = {
.cfg_gpio = s5pc100_spi_cfg_gpio,
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 13,
.high_speed = 1,
.tx_st_done = 21,
};
struct platform_device s5pc100_device_spi1 = {
.name = "s3c64xx-spi",
.id = 1,
.num_resources = ARRAY_SIZE(s5pc100_spi1_resource),
.resource = s5pc100_spi1_resource,
.dev = {
.dma_mask = &spi_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &s5pc100_spi1_pdata,
},
};
static struct resource s5pc100_spi2_resource[] = {
[0] = {
.start = S5PC100_PA_SPI2,
.end = S5PC100_PA_SPI2 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_SPI2_TX,
.end = DMACH_SPI2_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_SPI2_RX,
.end = DMACH_SPI2_RX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = IRQ_SPI2,
.end = IRQ_SPI2,
.flags = IORESOURCE_IRQ,
},
};
static struct s3c64xx_spi_info s5pc100_spi2_pdata = {
.cfg_gpio = s5pc100_spi_cfg_gpio,
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 13,
.high_speed = 1,
.tx_st_done = 21,
};
struct platform_device s5pc100_device_spi2 = {
.name = "s3c64xx-spi",
.id = 2,
.num_resources = ARRAY_SIZE(s5pc100_spi2_resource),
.resource = s5pc100_spi2_resource,
.dev = {
.dma_mask = &spi_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &s5pc100_spi2_pdata,
},
};
void __init s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
{
struct s3c64xx_spi_info *pd;
/* Reject invalid configuration */
if (!num_cs || src_clk_nr < 0
|| src_clk_nr > S5PC100_SPI_SRCCLK_SPIBUS) {
printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
return;
}
switch (cntrlr) {
case 0:
pd = &s5pc100_spi0_pdata;
break;
case 1:
pd = &s5pc100_spi1_pdata;
break;
case 2:
pd = &s5pc100_spi2_pdata;
break;
default:
printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
__func__, cntrlr);
return;
}
pd->num_cs = num_cs;
pd->src_clk_nr = src_clk_nr;
pd->src_clk_name = spi_src_clks[src_clk_nr];
}
......@@ -100,6 +100,9 @@
#define S3C_PA_USB_HSOTG S5PC100_PA_USB_HSOTG
#define S3C_PA_USB_HSPHY S5PC100_PA_USB_HSPHY
#define S3C_PA_WDT S5PC100_PA_WATCHDOG
#define S3C_PA_SPI0 S5PC100_PA_SPI0
#define S3C_PA_SPI1 S5PC100_PA_SPI1
#define S3C_PA_SPI2 S5PC100_PA_SPI2
#define S5P_PA_CHIPID S5PC100_PA_CHIPID
#define S5P_PA_FIMC0 S5PC100_PA_FIMC0
......
/* linux/arch/arm/mach-s5pc100/setup-sdhci.c
*
* Copyright 2008 Samsung Electronics
*
* S5PC100 - Helper functions for settign up SDHCI device(s) (HSMMC)
*
* Based on mach-s3c6410/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/types.h>
/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
char *s5pc100_hsmmc_clksrcs[4] = {
[0] = "hsmmc", /* HCLK */
/* [1] = "hsmmc", - duplicate HCLK entry */
[2] = "sclk_mmc", /* mmc_bus */
/* [3] = "48m", - note not successfully used yet */
};
/* linux/arch/arm/mach-s5pc100/setup-spi.c
*
* Copyright (C) 2011 Samsung Electronics 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/gpio.h>
#include <linux/platform_device.h>
#include <plat/gpio-cfg.h>
#include <plat/s3c64xx-spi.h>
#ifdef CONFIG_S3C64XX_DEV_SPI0
struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = {
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 13,
.high_speed = 1,
.tx_st_done = 21,
};
int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgall_range(S5PC100_GPB(0), 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0;
}
#endif
#ifdef CONFIG_S3C64XX_DEV_SPI1
struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = {
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 13,
.high_speed = 1,
.tx_st_done = 21,
};
int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgall_range(S5PC100_GPB(4), 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0;
}
#endif
#ifdef CONFIG_S3C64XX_DEV_SPI2
struct s3c64xx_spi_info s3c64xx_spi2_pdata __initdata = {
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 13,
.high_speed = 1,
.tx_st_done = 21,
};
int s3c64xx_spi2_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(3));
s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5PC100_GPB(2), 2,
S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
return 0;
}
#endif
......@@ -60,6 +60,11 @@ config S5PV210_SETUP_FIMC
help
Common setup code for the camera interfaces.
config S5PV210_SETUP_SPI
bool
help
Common setup code for SPI GPIO configurations.
menu "S5PC110 Machines"
config MACH_AQUILA
......
......@@ -27,7 +27,6 @@ obj-$(CONFIG_MACH_TORBRECK) += mach-torbreck.o
# device support
obj-y += dev-audio.o
obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
obj-$(CONFIG_S5PV210_SETUP_FB_24BPP) += setup-fb-24bpp.o
obj-$(CONFIG_S5PV210_SETUP_FIMC) += setup-fimc.o
......@@ -35,5 +34,5 @@ obj-$(CONFIG_S5PV210_SETUP_I2C1) += setup-i2c1.o
obj-$(CONFIG_S5PV210_SETUP_I2C2) += setup-i2c2.o
obj-$(CONFIG_S5PV210_SETUP_IDE) += setup-ide.o
obj-$(CONFIG_S5PV210_SETUP_KEYPAD) += setup-keypad.o
obj-$(CONFIG_S5PV210_SETUP_SDHCI) += setup-sdhci.o
obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
obj-$(CONFIG_S5PV210_SETUP_SPI) += setup-spi.o
......@@ -398,30 +398,6 @@ static struct clk init_clocks_off[] = {
.parent = &clk_hclk_psys.clk,
.enable = s5pv210_clk_ip1_ctrl,
.ctrlbit = (1<<25),
}, {
.name = "hsmmc",
.devname = "s3c-sdhci.0",
.parent = &clk_hclk_psys.clk,
.enable = s5pv210_clk_ip2_ctrl,
.ctrlbit = (1<<16),
}, {
.name = "hsmmc",
.devname = "s3c-sdhci.1",
.parent = &clk_hclk_psys.clk,
.enable = s5pv210_clk_ip2_ctrl,
.ctrlbit = (1<<17),
}, {
.name = "hsmmc",
.devname = "s3c-sdhci.2",
.parent = &clk_hclk_psys.clk,
.enable = s5pv210_clk_ip2_ctrl,
.ctrlbit = (1<<18),
}, {
.name = "hsmmc",
.devname = "s3c-sdhci.3",
.parent = &clk_hclk_psys.clk,
.enable = s5pv210_clk_ip2_ctrl,
.ctrlbit = (1<<19),
}, {
.name = "systimer",
.parent = &clk_pclk_psys.clk,
......@@ -559,6 +535,38 @@ static struct clk init_clocks[] = {
},
};
static struct clk clk_hsmmc0 = {
.name = "hsmmc",
.devname = "s3c-sdhci.0",
.parent = &clk_hclk_psys.clk,
.enable = s5pv210_clk_ip2_ctrl,
.ctrlbit = (1<<16),
};
static struct clk clk_hsmmc1 = {
.name = "hsmmc",
.devname = "s3c-sdhci.1",
.parent = &clk_hclk_psys.clk,
.enable = s5pv210_clk_ip2_ctrl,
.ctrlbit = (1<<17),
};
static struct clk clk_hsmmc2 = {
.name = "hsmmc",
.devname = "s3c-sdhci.2",
.parent = &clk_hclk_psys.clk,
.enable = s5pv210_clk_ip2_ctrl,
.ctrlbit = (1<<18),
};
static struct clk clk_hsmmc3 = {
.name = "hsmmc",
.devname = "s3c-sdhci.3",
.parent = &clk_hclk_psys.clk,
.enable = s5pv210_clk_ip2_ctrl,
.ctrlbit = (1<<19),
};
static struct clk *clkset_uart_list[] = {
[6] = &clk_mout_mpll.clk,
[7] = &clk_mout_epll.clk,
......@@ -864,46 +872,6 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 },
}, {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.0",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 8),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.1",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 9),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 },
}, {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.2",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 10),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 },
}, {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.3",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 11),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
}, {
.clk = {
.name = "sclk_mfc",
......@@ -941,26 +909,6 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 },
}, {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.0",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 16),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.1",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 17),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 },
}, {
.clk = {
.name = "sclk_pwi",
......@@ -1030,11 +978,97 @@ static struct clksrc_clk clk_sclk_uart3 = {
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
};
static struct clksrc_clk clk_sclk_mmc0 = {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.0",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 8),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 },
};
static struct clksrc_clk clk_sclk_mmc1 = {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.1",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 9),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 },
};
static struct clksrc_clk clk_sclk_mmc2 = {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.2",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 10),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 },
};
static struct clksrc_clk clk_sclk_mmc3 = {
.clk = {
.name = "sclk_mmc",
.devname = "s3c-sdhci.3",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 11),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
};
static struct clksrc_clk clk_sclk_spi0 = {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.0",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 16),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 },
};
static struct clksrc_clk clk_sclk_spi1 = {
.clk = {
.name = "sclk_spi",
.devname = "s3c64xx-spi.1",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 17),
},
.sources = &clkset_group2,
.reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 },
.reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 },
};
static struct clksrc_clk *clksrc_cdev[] = {
&clk_sclk_uart0,
&clk_sclk_uart1,
&clk_sclk_uart2,
&clk_sclk_uart3,
&clk_sclk_mmc0,
&clk_sclk_mmc1,
&clk_sclk_mmc2,
&clk_sclk_mmc3,
&clk_sclk_spi0,
&clk_sclk_spi1,
};
static struct clk *clk_cdev[] = {
&clk_hsmmc0,
&clk_hsmmc1,
&clk_hsmmc2,
&clk_hsmmc3,
};
/* Clock initialisation code */
......@@ -1282,6 +1316,17 @@ static struct clk_lookup s5pv210_clk_lookup[] = {
CLKDEV_INIT("s5pv210-uart.1", "clk_uart_baud1", &clk_sclk_uart1.clk),
CLKDEV_INIT("s5pv210-uart.2", "clk_uart_baud1", &clk_sclk_uart2.clk),
CLKDEV_INIT("s5pv210-uart.3", "clk_uart_baud1", &clk_sclk_uart3.clk),
CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0),
CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1),
CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2),
CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.0", &clk_hsmmc3),
CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk),
CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
};
void __init s5pv210_register_clocks(void)
......@@ -1306,6 +1351,10 @@ void __init s5pv210_register_clocks(void)
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
clkdev_add_table(s5pv210_clk_lookup, ARRAY_SIZE(s5pv210_clk_lookup));
s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev));
for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++)
s3c_disable_clocks(clk_cdev[ptr], 1);
s3c24xx_register_clock(&dummy_apb_pclk);
s3c_pwmclk_init();
}
/* linux/arch/arm/mach-s5pv210/dev-spi.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 <mach/dma.h>
#include <mach/map.h>
#include <mach/irqs.h>
#include <mach/spi-clocks.h>
#include <plat/s3c64xx-spi.h>
#include <plat/gpio-cfg.h>
static char *spi_src_clks[] = {
[S5PV210_SPI_SRCCLK_PCLK] = "pclk",
[S5PV210_SPI_SRCCLK_SCLK] = "sclk_spi",
};
/* SPI Controller platform_devices */
/* Since we emulate multi-cs capability, we do not touch the CS.
* The emulated CS is toggled by board specific mechanism, as it can
* be either some immediate GPIO or some signal out of some other
* chip in between ... or some yet another way.
* We simply do not assume anything about CS.
*/
static int s5pv210_spi_cfg_gpio(struct platform_device *pdev)
{
unsigned int base;
switch (pdev->id) {
case 0:
base = S5PV210_GPB(0);
break;
case 1:
base = S5PV210_GPB(4);
break;
default:
dev_err(&pdev->dev, "Invalid SPI Controller number!");
return -EINVAL;
}
s3c_gpio_cfgall_range(base, 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0;
}
static struct resource s5pv210_spi0_resource[] = {
[0] = {
.start = S5PV210_PA_SPI0,
.end = S5PV210_PA_SPI0 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_SPI0_TX,
.end = DMACH_SPI0_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_SPI0_RX,
.end = DMACH_SPI0_RX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = IRQ_SPI0,
.end = IRQ_SPI0,
.flags = IORESOURCE_IRQ,
},
};
static struct s3c64xx_spi_info s5pv210_spi0_pdata = {
.cfg_gpio = s5pv210_spi_cfg_gpio,
.fifo_lvl_mask = 0x1ff,
.rx_lvl_offset = 15,
.high_speed = 1,
.tx_st_done = 25,
};
static u64 spi_dmamask = DMA_BIT_MASK(32);
struct platform_device s5pv210_device_spi0 = {
.name = "s3c64xx-spi",
.id = 0,
.num_resources = ARRAY_SIZE(s5pv210_spi0_resource),
.resource = s5pv210_spi0_resource,
.dev = {
.dma_mask = &spi_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &s5pv210_spi0_pdata,
},
};
static struct resource s5pv210_spi1_resource[] = {
[0] = {
.start = S5PV210_PA_SPI1,
.end = S5PV210_PA_SPI1 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_SPI1_TX,
.end = DMACH_SPI1_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMACH_SPI1_RX,
.end = DMACH_SPI1_RX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = IRQ_SPI1,
.end = IRQ_SPI1,
.flags = IORESOURCE_IRQ,
},
};
static struct s3c64xx_spi_info s5pv210_spi1_pdata = {
.cfg_gpio = s5pv210_spi_cfg_gpio,
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 15,
.high_speed = 1,
.tx_st_done = 25,
};
struct platform_device s5pv210_device_spi1 = {
.name = "s3c64xx-spi",
.id = 1,
.num_resources = ARRAY_SIZE(s5pv210_spi1_resource),
.resource = s5pv210_spi1_resource,
.dev = {
.dma_mask = &spi_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &s5pv210_spi1_pdata,
},
};
void __init s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
{
struct s3c64xx_spi_info *pd;
/* Reject invalid configuration */
if (!num_cs || src_clk_nr < 0
|| src_clk_nr > S5PV210_SPI_SRCCLK_SCLK) {
printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
return;
}
switch (cntrlr) {
case 0:
pd = &s5pv210_spi0_pdata;
break;
case 1:
pd = &s5pv210_spi1_pdata;
break;
default:
printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
__func__, cntrlr);
return;
}
pd->num_cs = num_cs;
pd->src_clk_nr = src_clk_nr;
pd->src_clk_name = spi_src_clks[src_clk_nr];
}
......@@ -109,6 +109,8 @@
#define S3C_PA_RTC S5PV210_PA_RTC
#define S3C_PA_USB_HSOTG S5PV210_PA_HSOTG
#define S3C_PA_WDT S5PV210_PA_WATCHDOG
#define S3C_PA_SPI0 S5PV210_PA_SPI0
#define S3C_PA_SPI1 S5PV210_PA_SPI1
#define S5P_PA_CHIPID S5PV210_PA_CHIPID
#define S5P_PA_FIMC0 S5PV210_PA_FIMC0
......
/* linux/arch/arm/mach-s5pv210/setup-sdhci.c
*
* Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* S5PV210 - Helper functions for settign up SDHCI device(s) (HSMMC)
*
* 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>
/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
char *s5pv210_hsmmc_clksrcs[4] = {
[0] = "hsmmc", /* HCLK */
/* [1] = "hsmmc", - duplicate HCLK entry */
[2] = "sclk_mmc", /* mmc_bus */
/* [3] = NULL, - reserved */
};
/* linux/arch/arm/mach-s5pv210/setup-spi.c
*
* Copyright (C) 2011 Samsung Electronics 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/gpio.h>
#include <linux/platform_device.h>
#include <plat/gpio-cfg.h>
#include <plat/s3c64xx-spi.h>
#ifdef CONFIG_S3C64XX_DEV_SPI0
struct s3c64xx_spi_info s3c64xx_spi0_pdata = {
.fifo_lvl_mask = 0x1ff,
.rx_lvl_offset = 15,
.high_speed = 1,
.tx_st_done = 25,
};
int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5PV210_GPB(0), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV210_GPB(0), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5PV210_GPB(2), 2,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0;
}
#endif
#ifdef CONFIG_S3C64XX_DEV_SPI1
struct s3c64xx_spi_info s3c64xx_spi1_pdata = {
.fifo_lvl_mask = 0x7f,
.rx_lvl_offset = 15,
.high_speed = 1,
.tx_st_done = 25,
};
int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5PV210_GPB(4), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV210_GPB(4), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5PV210_GPB(6), 2,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0;
}
#endif
......@@ -426,12 +426,6 @@ static struct clk init_clocks[] = {
.parent = &clk_h,
.enable = s3c2443_clkcon_enable_h,
.ctrlbit = S3C2443_HCLKCON_DMA5,
}, {
.name = "hsmmc",
.devname = "s3c-sdhci.1",
.parent = &clk_h,
.enable = s3c2443_clkcon_enable_h,
.ctrlbit = S3C2443_HCLKCON_HSMMC,
}, {
.name = "gpio",
.parent = &clk_p,
......@@ -514,6 +508,14 @@ static struct clk init_clocks[] = {
}
};
static struct clk hsmmc1_clk = {
.name = "hsmmc",
.devname = "s3c-sdhci.1",
.parent = &clk_h,
.enable = s3c2443_clkcon_enable_h,
.ctrlbit = S3C2443_HCLKCON_HSMMC,
};
static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
{
clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
......@@ -579,6 +581,7 @@ static struct clk *clks[] __initdata = {
&clk_epll,
&clk_usb_bus,
&clk_armdiv,
&hsmmc1_clk,
};
static struct clksrc_clk *clksrcs[] __initdata = {
......@@ -595,6 +598,7 @@ static struct clk_lookup s3c2443_clk_lookup[] = {
CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk),
CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk),
};
void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
......
......@@ -226,11 +226,23 @@ config SAMSUNG_DEV_IDE
help
Compile in platform device definitions for IDE
config S3C64XX_DEV_SPI
config S3C64XX_DEV_SPI0
bool
help
Compile in platform device definitions for S3C64XX's type
SPI controllers.
SPI controller 0
config S3C64XX_DEV_SPI1
bool
help
Compile in platform device definitions for S3C64XX's type
SPI controller 1
config S3C64XX_DEV_SPI2
bool
help
Compile in platform device definitions for S3C64XX's type
SPI controller 2
config SAMSUNG_DEV_TS
bool
......
......@@ -61,6 +61,7 @@
#include <plat/regs-iic.h>
#include <plat/regs-serial.h>
#include <plat/regs-spi.h>
#include <plat/s3c64xx-spi.h>
static u64 samsung_device_dma_mask = DMA_BIT_MASK(32);
......@@ -1461,3 +1462,129 @@ struct platform_device s3c_device_wdt = {
.resource = s3c_wdt_resource,
};
#endif /* CONFIG_S3C_DEV_WDT */
#ifdef CONFIG_S3C64XX_DEV_SPI0
static struct resource s3c64xx_spi0_resource[] = {
[0] = DEFINE_RES_MEM(S3C_PA_SPI0, SZ_256),
[1] = DEFINE_RES_DMA(DMACH_SPI0_TX),
[2] = DEFINE_RES_DMA(DMACH_SPI0_RX),
[3] = DEFINE_RES_IRQ(IRQ_SPI0),
};
struct platform_device s3c64xx_device_spi0 = {
.name = "s3c64xx-spi",
.id = 0,
.num_resources = ARRAY_SIZE(s3c64xx_spi0_resource),
.resource = s3c64xx_spi0_resource,
.dev = {
.dma_mask = &samsung_device_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
void __init s3c64xx_spi0_set_platdata(struct s3c64xx_spi_info *pd,
int src_clk_nr, int num_cs)
{
if (!pd) {
pr_err("%s:Need to pass platform data\n", __func__);
return;
}
/* Reject invalid configuration */
if (!num_cs || src_clk_nr < 0) {
pr_err("%s: Invalid SPI configuration\n", __func__);
return;
}
pd->num_cs = num_cs;
pd->src_clk_nr = src_clk_nr;
if (!pd->cfg_gpio)
pd->cfg_gpio = s3c64xx_spi0_cfg_gpio;
s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi0);
}
#endif /* CONFIG_S3C64XX_DEV_SPI0 */
#ifdef CONFIG_S3C64XX_DEV_SPI1
static struct resource s3c64xx_spi1_resource[] = {
[0] = DEFINE_RES_MEM(S3C_PA_SPI1, SZ_256),
[1] = DEFINE_RES_DMA(DMACH_SPI1_TX),
[2] = DEFINE_RES_DMA(DMACH_SPI1_RX),
[3] = DEFINE_RES_IRQ(IRQ_SPI1),
};
struct platform_device s3c64xx_device_spi1 = {
.name = "s3c64xx-spi",
.id = 1,
.num_resources = ARRAY_SIZE(s3c64xx_spi1_resource),
.resource = s3c64xx_spi1_resource,
.dev = {
.dma_mask = &samsung_device_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
void __init s3c64xx_spi1_set_platdata(struct s3c64xx_spi_info *pd,
int src_clk_nr, int num_cs)
{
if (!pd) {
pr_err("%s:Need to pass platform data\n", __func__);
return;
}
/* Reject invalid configuration */
if (!num_cs || src_clk_nr < 0) {
pr_err("%s: Invalid SPI configuration\n", __func__);
return;
}
pd->num_cs = num_cs;
pd->src_clk_nr = src_clk_nr;
if (!pd->cfg_gpio)
pd->cfg_gpio = s3c64xx_spi1_cfg_gpio;
s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi1);
}
#endif /* CONFIG_S3C64XX_DEV_SPI1 */
#ifdef CONFIG_S3C64XX_DEV_SPI2
static struct resource s3c64xx_spi2_resource[] = {
[0] = DEFINE_RES_MEM(S3C_PA_SPI2, SZ_256),
[1] = DEFINE_RES_DMA(DMACH_SPI2_TX),
[2] = DEFINE_RES_DMA(DMACH_SPI2_RX),
[3] = DEFINE_RES_IRQ(IRQ_SPI2),
};
struct platform_device s3c64xx_device_spi2 = {
.name = "s3c64xx-spi",
.id = 2,
.num_resources = ARRAY_SIZE(s3c64xx_spi2_resource),
.resource = s3c64xx_spi2_resource,
.dev = {
.dma_mask = &samsung_device_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
void __init s3c64xx_spi2_set_platdata(struct s3c64xx_spi_info *pd,
int src_clk_nr, int num_cs)
{
if (!pd) {
pr_err("%s:Need to pass platform data\n", __func__);
return;
}
/* Reject invalid configuration */
if (!num_cs || src_clk_nr < 0) {
pr_err("%s: Invalid SPI configuration\n", __func__);
return;
}
pd->num_cs = num_cs;
pd->src_clk_nr = src_clk_nr;
if (!pd->cfg_gpio)
pd->cfg_gpio = s3c64xx_spi2_cfg_gpio;
s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi2);
}
#endif /* CONFIG_S3C64XX_DEV_SPI2 */
......@@ -39,6 +39,7 @@ extern struct platform_device s3c64xx_device_pcm0;
extern struct platform_device s3c64xx_device_pcm1;
extern struct platform_device s3c64xx_device_spi0;
extern struct platform_device s3c64xx_device_spi1;
extern struct platform_device s3c64xx_device_spi2;
extern struct platform_device s3c_device_adc;
extern struct platform_device s3c_device_cfcon;
......@@ -98,8 +99,6 @@ extern struct platform_device s5p6450_device_iis1;
extern struct platform_device s5p6450_device_iis2;
extern struct platform_device s5p6450_device_pcm0;
extern struct platform_device s5p64x0_device_spi0;
extern struct platform_device s5p64x0_device_spi1;
extern struct platform_device s5pc100_device_ac97;
extern struct platform_device s5pc100_device_iis0;
......@@ -108,9 +107,6 @@ extern struct platform_device s5pc100_device_iis2;
extern struct platform_device s5pc100_device_pcm0;
extern struct platform_device s5pc100_device_pcm1;
extern struct platform_device s5pc100_device_spdif;
extern struct platform_device s5pc100_device_spi0;
extern struct platform_device s5pc100_device_spi1;
extern struct platform_device s5pc100_device_spi2;
extern struct platform_device s5pv210_device_ac97;
extern struct platform_device s5pv210_device_iis0;
......@@ -120,8 +116,6 @@ extern struct platform_device s5pv210_device_pcm0;
extern struct platform_device s5pv210_device_pcm1;
extern struct platform_device s5pv210_device_pcm2;
extern struct platform_device s5pv210_device_spdif;
extern struct platform_device s5pv210_device_spi0;
extern struct platform_device s5pv210_device_spi1;
extern struct platform_device exynos4_device_ac97;
extern struct platform_device exynos4_device_ahci;
......
......@@ -31,7 +31,6 @@ struct s3c64xx_spi_csinfo {
/**
* struct s3c64xx_spi_info - SPI Controller defining structure
* @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field.
* @src_clk_name: Platform name of the corresponding clock.
* @clk_from_cmu: If the SPI clock/prescalar control block is present
* by the platform's clock-management-unit and not in SPI controller.
* @num_cs: Number of CS this controller emulates.
......@@ -43,7 +42,6 @@ struct s3c64xx_spi_csinfo {
*/
struct s3c64xx_spi_info {
int src_clk_nr;
char *src_clk_name;
bool clk_from_cmu;
int num_cs;
......@@ -58,18 +56,28 @@ struct s3c64xx_spi_info {
};
/**
* s3c64xx_spi_set_info - SPI Controller configure callback by the board
* s3c64xx_spi_set_platdata - SPI Controller configure callback by the board
* initialization code.
* @cntrlr: SPI controller number the configuration is for.
* @pd: SPI platform data to set.
* @src_clk_nr: Clock the SPI controller is to use to generate SPI clocks.
* @num_cs: Number of elements in the 'cs' array.
*
* Call this from machine init code for each SPI Controller that
* has some chips attached to it.
*/
extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s3c64xx_spi0_set_platdata(struct s3c64xx_spi_info *pd,
int src_clk_nr, int num_cs);
extern void s3c64xx_spi1_set_platdata(struct s3c64xx_spi_info *pd,
int src_clk_nr, int num_cs);
extern void s3c64xx_spi2_set_platdata(struct s3c64xx_spi_info *pd,
int src_clk_nr, int num_cs);
/* defined by architecture to configure gpio */
extern int s3c64xx_spi0_cfg_gpio(struct platform_device *dev);
extern int s3c64xx_spi1_cfg_gpio(struct platform_device *dev);
extern int s3c64xx_spi2_cfg_gpio(struct platform_device *dev);
extern struct s3c64xx_spi_info s3c64xx_spi0_pdata;
extern struct s3c64xx_spi_info s3c64xx_spi1_pdata;
extern struct s3c64xx_spi_info s3c64xx_spi2_pdata;
#endif /* __S3C64XX_PLAT_SPI_H */
......@@ -66,8 +66,6 @@ struct s3c_sdhci_platdata {
enum cd_types cd_type;
enum clk_types clk_type;
char **clocks; /* set of clock sources */
int ext_cd_gpio;
bool ext_cd_gpio_invert;
int (*ext_cd_init)(void (*notify_func)(struct platform_device *,
......@@ -129,12 +127,9 @@ extern void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
/* S3C2416 SDHCI setup */
#ifdef CONFIG_S3C2416_SETUP_SDHCI
extern char *s3c2416_hsmmc_clksrcs[4];
static inline void s3c2416_default_sdhci0(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC
s3c_hsmmc0_def_platdata.clocks = s3c2416_hsmmc_clksrcs;
s3c_hsmmc0_def_platdata.cfg_gpio = s3c2416_setup_sdhci0_cfg_gpio;
#endif /* CONFIG_S3C_DEV_HSMMC */
}
......@@ -142,7 +137,6 @@ static inline void s3c2416_default_sdhci0(void)
static inline void s3c2416_default_sdhci1(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC1
s3c_hsmmc1_def_platdata.clocks = s3c2416_hsmmc_clksrcs;
s3c_hsmmc1_def_platdata.cfg_gpio = s3c2416_setup_sdhci1_cfg_gpio;
#endif /* CONFIG_S3C_DEV_HSMMC1 */
}
......@@ -155,12 +149,9 @@ static inline void s3c2416_default_sdhci1(void) { }
/* S3C64XX SDHCI setup */
#ifdef CONFIG_S3C64XX_SETUP_SDHCI
extern char *s3c64xx_hsmmc_clksrcs[4];
static inline void s3c6400_default_sdhci0(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC
s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
#endif
}
......@@ -168,7 +159,6 @@ static inline void s3c6400_default_sdhci0(void)
static inline void s3c6400_default_sdhci1(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC1
s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
#endif
}
......@@ -176,7 +166,6 @@ static inline void s3c6400_default_sdhci1(void)
static inline void s3c6400_default_sdhci2(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC2
s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
#endif
}
......@@ -184,7 +173,6 @@ static inline void s3c6400_default_sdhci2(void)
static inline void s3c6410_default_sdhci0(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC
s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
#endif
}
......@@ -192,7 +180,6 @@ static inline void s3c6410_default_sdhci0(void)
static inline void s3c6410_default_sdhci1(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC1
s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
#endif
}
......@@ -200,7 +187,6 @@ static inline void s3c6410_default_sdhci1(void)
static inline void s3c6410_default_sdhci2(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC2
s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
#endif
}
......@@ -218,12 +204,9 @@ static inline void s3c6400_default_sdhci2(void) { }
/* S5PC100 SDHCI setup */
#ifdef CONFIG_S5PC100_SETUP_SDHCI
extern char *s5pc100_hsmmc_clksrcs[4];
static inline void s5pc100_default_sdhci0(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC
s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio;
#endif
}
......@@ -231,7 +214,6 @@ static inline void s5pc100_default_sdhci0(void)
static inline void s5pc100_default_sdhci1(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC1
s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio;
#endif
}
......@@ -239,7 +221,6 @@ static inline void s5pc100_default_sdhci1(void)
static inline void s5pc100_default_sdhci2(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC2
s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio;
#endif
}
......@@ -254,12 +235,9 @@ static inline void s5pc100_default_sdhci2(void) { }
/* S5PV210 SDHCI setup */
#ifdef CONFIG_S5PV210_SETUP_SDHCI
extern char *s5pv210_hsmmc_clksrcs[4];
static inline void s5pv210_default_sdhci0(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC
s3c_hsmmc0_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio;
#endif
}
......@@ -267,7 +245,6 @@ static inline void s5pv210_default_sdhci0(void)
static inline void s5pv210_default_sdhci1(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC1
s3c_hsmmc1_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio;
#endif
}
......@@ -275,7 +252,6 @@ static inline void s5pv210_default_sdhci1(void)
static inline void s5pv210_default_sdhci2(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC2
s3c_hsmmc2_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio;
#endif
}
......@@ -283,7 +259,6 @@ static inline void s5pv210_default_sdhci2(void)
static inline void s5pv210_default_sdhci3(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC3
s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio;
#endif
}
......@@ -298,12 +273,9 @@ static inline void s5pv210_default_sdhci3(void) { }
/* EXYNOS4 SDHCI setup */
#ifdef CONFIG_EXYNOS4_SETUP_SDHCI
extern char *exynos4_hsmmc_clksrcs[4];
static inline void exynos4_default_sdhci0(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC
s3c_hsmmc0_def_platdata.clocks = exynos4_hsmmc_clksrcs;
s3c_hsmmc0_def_platdata.cfg_gpio = exynos4_setup_sdhci0_cfg_gpio;
#endif
}
......@@ -311,7 +283,6 @@ static inline void exynos4_default_sdhci0(void)
static inline void exynos4_default_sdhci1(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC1
s3c_hsmmc1_def_platdata.clocks = exynos4_hsmmc_clksrcs;
s3c_hsmmc1_def_platdata.cfg_gpio = exynos4_setup_sdhci1_cfg_gpio;
#endif
}
......@@ -319,7 +290,6 @@ static inline void exynos4_default_sdhci1(void)
static inline void exynos4_default_sdhci2(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC2
s3c_hsmmc2_def_platdata.clocks = exynos4_hsmmc_clksrcs;
s3c_hsmmc2_def_platdata.cfg_gpio = exynos4_setup_sdhci2_cfg_gpio;
#endif
}
......@@ -327,7 +297,6 @@ static inline void exynos4_default_sdhci2(void)
static inline void exynos4_default_sdhci3(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC3
s3c_hsmmc3_def_platdata.clocks = exynos4_hsmmc_clksrcs;
s3c_hsmmc3_def_platdata.cfg_gpio = exynos4_setup_sdhci3_cfg_gpio;
#endif
}
......
......@@ -435,14 +435,11 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
struct clk *clk;
char *name = pdata->clocks[ptr];
if (name == NULL)
continue;
char name[14];
snprintf(name, 14, "mmc_busclk.%d", ptr);
clk = clk_get(dev, name);
if (IS_ERR(clk)) {
dev_err(dev, "failed to get clock %s\n", name);
continue;
}
......
......@@ -971,6 +971,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
struct s3c64xx_spi_info *sci;
struct spi_master *master;
int ret;
char clk_name[16];
if (pdev->id < 0) {
dev_err(&pdev->dev,
......@@ -984,11 +985,6 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
}
sci = pdev->dev.platform_data;
if (!sci->src_clk_name) {
dev_err(&pdev->dev,
"Board init must call s3c64xx_spi_set_info()\n");
return -EINVAL;
}
/* Check for availability of necessary resource */
......@@ -1073,17 +1069,17 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
goto err4;
}
sdd->src_clk = clk_get(&pdev->dev, sci->src_clk_name);
sprintf(clk_name, "spi_busclk%d", sci->src_clk_nr);
sdd->src_clk = clk_get(&pdev->dev, clk_name);
if (IS_ERR(sdd->src_clk)) {
dev_err(&pdev->dev,
"Unable to acquire clock '%s'\n", sci->src_clk_name);
"Unable to acquire clock '%s'\n", clk_name);
ret = PTR_ERR(sdd->src_clk);
goto err5;
}
if (clk_enable(sdd->src_clk)) {
dev_err(&pdev->dev, "Couldn't enable clock '%s'\n",
sci->src_clk_name);
dev_err(&pdev->dev, "Couldn't enable clock '%s'\n", clk_name);
ret = -EBUSY;
goto err6;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment