diff options
| author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
|---|---|---|
| committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
| commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
| tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /arch/arm/plat-samsung | |
| parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) | |
Diffstat (limited to 'arch/arm/plat-samsung')
48 files changed, 5593 insertions, 0 deletions
diff --git a/arch/arm/plat-samsung/dev-adc.c b/arch/arm/plat-samsung/dev-adc.c new file mode 100644 index 00000000000..9d903d4095e --- /dev/null +++ b/arch/arm/plat-samsung/dev-adc.c | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/dev-adc.c | ||
| 2 | * | ||
| 3 | * Copyright 2010 Maurus Cuelenaere | ||
| 4 | * | ||
| 5 | * S3C64xx series device definition for ADC device | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/string.h> | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | |||
| 16 | #include <mach/irqs.h> | ||
| 17 | #include <mach/map.h> | ||
| 18 | |||
| 19 | #include <plat/adc.h> | ||
| 20 | #include <plat/devs.h> | ||
| 21 | #include <plat/cpu.h> | ||
| 22 | |||
| 23 | static struct resource s3c_adc_resource[] = { | ||
| 24 | [0] = { | ||
| 25 | .start = SAMSUNG_PA_ADC, | ||
| 26 | .end = SAMSUNG_PA_ADC + SZ_256 - 1, | ||
| 27 | .flags = IORESOURCE_MEM, | ||
| 28 | }, | ||
| 29 | [1] = { | ||
| 30 | .start = IRQ_TC, | ||
| 31 | .end = IRQ_TC, | ||
| 32 | .flags = IORESOURCE_IRQ, | ||
| 33 | }, | ||
| 34 | [2] = { | ||
| 35 | .start = IRQ_ADC, | ||
| 36 | .end = IRQ_ADC, | ||
| 37 | .flags = IORESOURCE_IRQ, | ||
| 38 | }, | ||
| 39 | }; | ||
| 40 | |||
| 41 | struct platform_device s3c_device_adc = { | ||
| 42 | .name = "samsung-adc", | ||
| 43 | .id = -1, | ||
| 44 | .num_resources = ARRAY_SIZE(s3c_adc_resource), | ||
| 45 | .resource = s3c_adc_resource, | ||
| 46 | }; | ||
diff --git a/arch/arm/plat-samsung/dev-asocdma.c b/arch/arm/plat-samsung/dev-asocdma.c new file mode 100644 index 00000000000..97e35d3c064 --- /dev/null +++ b/arch/arm/plat-samsung/dev-asocdma.c | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/dev-asocdma.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2010 Samsung Electronics Co. Ltd | ||
| 4 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/platform_device.h> | ||
| 12 | #include <linux/dma-mapping.h> | ||
| 13 | #include <plat/devs.h> | ||
| 14 | |||
| 15 | static u64 audio_dmamask = DMA_BIT_MASK(32); | ||
| 16 | |||
| 17 | struct platform_device samsung_asoc_dma = { | ||
| 18 | .name = "samsung-audio", | ||
| 19 | .id = -1, | ||
| 20 | .dev = { | ||
| 21 | .dma_mask = &audio_dmamask, | ||
| 22 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 23 | } | ||
| 24 | }; | ||
| 25 | EXPORT_SYMBOL(samsung_asoc_dma); | ||
| 26 | |||
| 27 | struct platform_device samsung_asoc_idma = { | ||
| 28 | .name = "samsung-idma", | ||
| 29 | .id = -1, | ||
| 30 | .dev = { | ||
| 31 | .dma_mask = &audio_dmamask, | ||
| 32 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 33 | } | ||
| 34 | }; | ||
| 35 | EXPORT_SYMBOL(samsung_asoc_idma); | ||
diff --git a/arch/arm/plat-samsung/dev-fb.c b/arch/arm/plat-samsung/dev-fb.c new file mode 100644 index 00000000000..49a1362fd25 --- /dev/null +++ b/arch/arm/plat-samsung/dev-fb.c | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c/dev-fb.c | ||
| 2 | * | ||
| 3 | * Copyright 2008 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * http://armlinux.simtec.co.uk/ | ||
| 6 | * | ||
| 7 | * S3C series device definition for framebuffer device | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/string.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <linux/fb.h> | ||
| 18 | #include <linux/gfp.h> | ||
| 19 | |||
| 20 | #include <mach/irqs.h> | ||
| 21 | #include <mach/map.h> | ||
| 22 | |||
| 23 | #include <plat/fb.h> | ||
| 24 | #include <plat/devs.h> | ||
| 25 | #include <plat/cpu.h> | ||
| 26 | |||
| 27 | static struct resource s3c_fb_resource[] = { | ||
| 28 | [0] = { | ||
| 29 | .start = S3C_PA_FB, | ||
| 30 | .end = S3C_PA_FB + SZ_16K - 1, | ||
| 31 | .flags = IORESOURCE_MEM, | ||
| 32 | }, | ||
| 33 | [1] = { | ||
| 34 | .start = IRQ_LCD_VSYNC, | ||
| 35 | .end = IRQ_LCD_VSYNC, | ||
| 36 | .flags = IORESOURCE_IRQ, | ||
| 37 | }, | ||
| 38 | [2] = { | ||
| 39 | .start = IRQ_LCD_FIFO, | ||
| 40 | .end = IRQ_LCD_FIFO, | ||
| 41 | .flags = IORESOURCE_IRQ, | ||
| 42 | }, | ||
| 43 | [3] = { | ||
| 44 | .start = IRQ_LCD_SYSTEM, | ||
| 45 | .end = IRQ_LCD_SYSTEM, | ||
| 46 | .flags = IORESOURCE_IRQ, | ||
| 47 | }, | ||
| 48 | }; | ||
| 49 | |||
| 50 | struct platform_device s3c_device_fb = { | ||
| 51 | .name = "s3c-fb", | ||
| 52 | .id = -1, | ||
| 53 | .num_resources = ARRAY_SIZE(s3c_fb_resource), | ||
| 54 | .resource = s3c_fb_resource, | ||
| 55 | .dev.dma_mask = &s3c_device_fb.dev.coherent_dma_mask, | ||
| 56 | .dev.coherent_dma_mask = 0xffffffffUL, | ||
| 57 | }; | ||
| 58 | |||
| 59 | void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd) | ||
| 60 | { | ||
| 61 | s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata), | ||
| 62 | &s3c_device_fb); | ||
| 63 | } | ||
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c new file mode 100644 index 00000000000..db7a65c7f12 --- /dev/null +++ b/arch/arm/plat-samsung/dev-hsmmc.c | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c/dev-hsmmc.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2008 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * http://armlinux.simtec.co.uk/ | ||
| 6 | * | ||
| 7 | * S3C series device definition for hsmmc devices | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/mmc/host.h> | ||
| 17 | |||
| 18 | #include <mach/map.h> | ||
| 19 | #include <plat/sdhci.h> | ||
| 20 | #include <plat/devs.h> | ||
| 21 | #include <plat/cpu.h> | ||
| 22 | |||
| 23 | #define S3C_SZ_HSMMC (0x1000) | ||
| 24 | |||
| 25 | static struct resource s3c_hsmmc_resource[] = { | ||
| 26 | [0] = { | ||
| 27 | .start = S3C_PA_HSMMC0, | ||
| 28 | .end = S3C_PA_HSMMC0 + S3C_SZ_HSMMC - 1, | ||
| 29 | .flags = IORESOURCE_MEM, | ||
| 30 | }, | ||
| 31 | [1] = { | ||
| 32 | .start = IRQ_HSMMC0, | ||
| 33 | .end = IRQ_HSMMC0, | ||
| 34 | .flags = IORESOURCE_IRQ, | ||
| 35 | } | ||
| 36 | }; | ||
| 37 | |||
| 38 | static u64 s3c_device_hsmmc_dmamask = 0xffffffffUL; | ||
| 39 | |||
| 40 | struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = { | ||
| 41 | .max_width = 4, | ||
| 42 | .host_caps = (MMC_CAP_4_BIT_DATA | | ||
| 43 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), | ||
| 44 | .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, | ||
| 45 | }; | ||
| 46 | |||
| 47 | struct platform_device s3c_device_hsmmc0 = { | ||
| 48 | .name = "s3c-sdhci", | ||
| 49 | .id = 0, | ||
| 50 | .num_resources = ARRAY_SIZE(s3c_hsmmc_resource), | ||
| 51 | .resource = s3c_hsmmc_resource, | ||
| 52 | .dev = { | ||
| 53 | .dma_mask = &s3c_device_hsmmc_dmamask, | ||
| 54 | .coherent_dma_mask = 0xffffffffUL, | ||
| 55 | .platform_data = &s3c_hsmmc0_def_platdata, | ||
| 56 | }, | ||
| 57 | }; | ||
| 58 | |||
| 59 | void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd) | ||
| 60 | { | ||
| 61 | struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata; | ||
| 62 | |||
| 63 | set->cd_type = pd->cd_type; | ||
| 64 | set->ext_cd_init = pd->ext_cd_init; | ||
| 65 | set->ext_cd_cleanup = pd->ext_cd_cleanup; | ||
| 66 | set->ext_cd_gpio = pd->ext_cd_gpio; | ||
| 67 | set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; | ||
| 68 | |||
| 69 | if (pd->max_width) | ||
| 70 | set->max_width = pd->max_width; | ||
| 71 | if (pd->cfg_gpio) | ||
| 72 | set->cfg_gpio = pd->cfg_gpio; | ||
| 73 | if (pd->cfg_card) | ||
| 74 | set->cfg_card = pd->cfg_card; | ||
| 75 | if (pd->host_caps) | ||
| 76 | set->host_caps |= pd->host_caps; | ||
| 77 | if (pd->clk_type) | ||
| 78 | set->clk_type = pd->clk_type; | ||
| 79 | } | ||
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c new file mode 100644 index 00000000000..2497321f08d --- /dev/null +++ b/arch/arm/plat-samsung/dev-hsmmc1.c | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c/dev-hsmmc1.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2008 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * http://armlinux.simtec.co.uk/ | ||
| 6 | * | ||
| 7 | * S3C series device definition for hsmmc device 1 | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/mmc/host.h> | ||
| 17 | |||
| 18 | #include <mach/map.h> | ||
| 19 | #include <plat/sdhci.h> | ||
| 20 | #include <plat/devs.h> | ||
| 21 | #include <plat/cpu.h> | ||
| 22 | |||
| 23 | #define S3C_SZ_HSMMC (0x1000) | ||
| 24 | |||
| 25 | static struct resource s3c_hsmmc1_resource[] = { | ||
| 26 | [0] = { | ||
| 27 | .start = S3C_PA_HSMMC1, | ||
| 28 | .end = S3C_PA_HSMMC1 + S3C_SZ_HSMMC - 1, | ||
| 29 | .flags = IORESOURCE_MEM, | ||
| 30 | }, | ||
| 31 | [1] = { | ||
| 32 | .start = IRQ_HSMMC1, | ||
| 33 | .end = IRQ_HSMMC1, | ||
| 34 | .flags = IORESOURCE_IRQ, | ||
| 35 | } | ||
| 36 | }; | ||
| 37 | |||
| 38 | static u64 s3c_device_hsmmc1_dmamask = 0xffffffffUL; | ||
| 39 | |||
| 40 | struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = { | ||
| 41 | .max_width = 4, | ||
| 42 | .host_caps = (MMC_CAP_4_BIT_DATA | | ||
| 43 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), | ||
| 44 | .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, | ||
| 45 | }; | ||
| 46 | |||
| 47 | struct platform_device s3c_device_hsmmc1 = { | ||
| 48 | .name = "s3c-sdhci", | ||
| 49 | .id = 1, | ||
| 50 | .num_resources = ARRAY_SIZE(s3c_hsmmc1_resource), | ||
| 51 | .resource = s3c_hsmmc1_resource, | ||
| 52 | .dev = { | ||
| 53 | .dma_mask = &s3c_device_hsmmc1_dmamask, | ||
| 54 | .coherent_dma_mask = 0xffffffffUL, | ||
| 55 | .platform_data = &s3c_hsmmc1_def_platdata, | ||
| 56 | }, | ||
| 57 | }; | ||
| 58 | |||
| 59 | void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd) | ||
| 60 | { | ||
| 61 | struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata; | ||
| 62 | |||
| 63 | set->cd_type = pd->cd_type; | ||
| 64 | set->ext_cd_init = pd->ext_cd_init; | ||
| 65 | set->ext_cd_cleanup = pd->ext_cd_cleanup; | ||
| 66 | set->ext_cd_gpio = pd->ext_cd_gpio; | ||
| 67 | set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; | ||
| 68 | |||
| 69 | if (pd->max_width) | ||
| 70 | set->max_width = pd->max_width; | ||
| 71 | if (pd->cfg_gpio) | ||
| 72 | set->cfg_gpio = pd->cfg_gpio; | ||
| 73 | if (pd->cfg_card) | ||
| 74 | set->cfg_card = pd->cfg_card; | ||
| 75 | if (pd->host_caps) | ||
| 76 | set->host_caps |= pd->host_caps; | ||
| 77 | if (pd->clk_type) | ||
| 78 | set->clk_type = pd->clk_type; | ||
| 79 | } | ||
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c new file mode 100644 index 00000000000..f60aedba417 --- /dev/null +++ b/arch/arm/plat-samsung/dev-hsmmc2.c | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c/dev-hsmmc2.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2009 Samsung Electronics | ||
| 4 | * Copyright (c) 2009 Maurus Cuelenaere | ||
| 5 | * | ||
| 6 | * Based on arch/arm/plat-s3c/dev-hsmmc1.c | ||
| 7 | * original file Copyright (c) 2008 Simtec Electronics | ||
| 8 | * | ||
| 9 | * S3C series device definition for hsmmc device 2 | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 as | ||
| 13 | * published by the Free Software Foundation. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | #include <linux/mmc/host.h> | ||
| 19 | |||
| 20 | #include <mach/map.h> | ||
| 21 | #include <plat/sdhci.h> | ||
| 22 | #include <plat/devs.h> | ||
| 23 | |||
| 24 | #define S3C_SZ_HSMMC (0x1000) | ||
| 25 | |||
| 26 | static struct resource s3c_hsmmc2_resource[] = { | ||
| 27 | [0] = { | ||
| 28 | .start = S3C_PA_HSMMC2, | ||
| 29 | .end = S3C_PA_HSMMC2 + S3C_SZ_HSMMC - 1, | ||
| 30 | .flags = IORESOURCE_MEM, | ||
| 31 | }, | ||
| 32 | [1] = { | ||
| 33 | .start = IRQ_HSMMC2, | ||
| 34 | .end = IRQ_HSMMC2, | ||
| 35 | .flags = IORESOURCE_IRQ, | ||
| 36 | } | ||
| 37 | }; | ||
| 38 | |||
| 39 | static u64 s3c_device_hsmmc2_dmamask = 0xffffffffUL; | ||
| 40 | |||
| 41 | struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = { | ||
| 42 | .max_width = 4, | ||
| 43 | .host_caps = (MMC_CAP_4_BIT_DATA | | ||
| 44 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), | ||
| 45 | .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, | ||
| 46 | }; | ||
| 47 | |||
| 48 | struct platform_device s3c_device_hsmmc2 = { | ||
| 49 | .name = "s3c-sdhci", | ||
| 50 | .id = 2, | ||
| 51 | .num_resources = ARRAY_SIZE(s3c_hsmmc2_resource), | ||
| 52 | .resource = s3c_hsmmc2_resource, | ||
| 53 | .dev = { | ||
| 54 | .dma_mask = &s3c_device_hsmmc2_dmamask, | ||
| 55 | .coherent_dma_mask = 0xffffffffUL, | ||
| 56 | .platform_data = &s3c_hsmmc2_def_platdata, | ||
| 57 | }, | ||
| 58 | }; | ||
| 59 | |||
| 60 | void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd) | ||
| 61 | { | ||
| 62 | struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata; | ||
| 63 | |||
| 64 | set->cd_type = pd->cd_type; | ||
| 65 | set->ext_cd_init = pd->ext_cd_init; | ||
| 66 | set->ext_cd_cleanup = pd->ext_cd_cleanup; | ||
| 67 | set->ext_cd_gpio = pd->ext_cd_gpio; | ||
| 68 | set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; | ||
| 69 | |||
| 70 | if (pd->max_width) | ||
| 71 | set->max_width = pd->max_width; | ||
| 72 | if (pd->cfg_gpio) | ||
| 73 | set->cfg_gpio = pd->cfg_gpio; | ||
| 74 | if (pd->cfg_card) | ||
| 75 | set->cfg_card = pd->cfg_card; | ||
| 76 | if (pd->host_caps) | ||
| 77 | set->host_caps |= pd->host_caps; | ||
| 78 | if (pd->clk_type) | ||
| 79 | set->clk_type = pd->clk_type; | ||
| 80 | } | ||
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c new file mode 100644 index 00000000000..ede776f20e6 --- /dev/null +++ b/arch/arm/plat-samsung/dev-hsmmc3.c | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/dev-hsmmc3.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
| 4 | * http://www.samsung.com | ||
| 5 | * | ||
| 6 | * Copyright (c) 2008 Simtec Electronics | ||
| 7 | * Ben Dooks <ben@simtec.co.uk> | ||
| 8 | * http://armlinux.simtec.co.uk/ | ||
| 9 | * | ||
| 10 | * Based on arch/arm/plat-samsung/dev-hsmmc1.c | ||
| 11 | * | ||
| 12 | * Samsung device definition for hsmmc device 3 | ||
| 13 | * | ||
| 14 | * This program is free software; you can redistribute it and/or modify | ||
| 15 | * it under the terms of the GNU General Public License version 2 as | ||
| 16 | * published by the Free Software Foundation. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | #include <linux/mmc/host.h> | ||
| 22 | |||
| 23 | #include <mach/map.h> | ||
| 24 | #include <plat/sdhci.h> | ||
| 25 | #include <plat/devs.h> | ||
| 26 | |||
| 27 | #define S3C_SZ_HSMMC (0x1000) | ||
| 28 | |||
| 29 | static struct resource s3c_hsmmc3_resource[] = { | ||
| 30 | [0] = { | ||
| 31 | .start = S3C_PA_HSMMC3, | ||
| 32 | .end = S3C_PA_HSMMC3 + S3C_SZ_HSMMC - 1, | ||
| 33 | .flags = IORESOURCE_MEM, | ||
| 34 | }, | ||
| 35 | [1] = { | ||
| 36 | .start = IRQ_HSMMC3, | ||
| 37 | .end = IRQ_HSMMC3, | ||
| 38 | .flags = IORESOURCE_IRQ, | ||
| 39 | } | ||
| 40 | }; | ||
| 41 | |||
| 42 | static u64 s3c_device_hsmmc3_dmamask = 0xffffffffUL; | ||
| 43 | |||
| 44 | struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = { | ||
| 45 | .max_width = 4, | ||
| 46 | .host_caps = (MMC_CAP_4_BIT_DATA | | ||
| 47 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), | ||
| 48 | .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, | ||
| 49 | }; | ||
| 50 | |||
| 51 | struct platform_device s3c_device_hsmmc3 = { | ||
| 52 | .name = "s3c-sdhci", | ||
| 53 | .id = 3, | ||
| 54 | .num_resources = ARRAY_SIZE(s3c_hsmmc3_resource), | ||
| 55 | .resource = s3c_hsmmc3_resource, | ||
| 56 | .dev = { | ||
| 57 | .dma_mask = &s3c_device_hsmmc3_dmamask, | ||
| 58 | .coherent_dma_mask = 0xffffffffUL, | ||
| 59 | .platform_data = &s3c_hsmmc3_def_platdata, | ||
| 60 | }, | ||
| 61 | }; | ||
| 62 | |||
| 63 | void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd) | ||
| 64 | { | ||
| 65 | struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata; | ||
| 66 | |||
| 67 | set->cd_type = pd->cd_type; | ||
| 68 | set->ext_cd_init = pd->ext_cd_init; | ||
| 69 | set->ext_cd_cleanup = pd->ext_cd_cleanup; | ||
| 70 | set->ext_cd_gpio = pd->ext_cd_gpio; | ||
| 71 | set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; | ||
| 72 | |||
| 73 | if (pd->max_width) | ||
| 74 | set->max_width = pd->max_width; | ||
| 75 | if (pd->cfg_gpio) | ||
| 76 | set->cfg_gpio = pd->cfg_gpio; | ||
| 77 | if (pd->cfg_card) | ||
| 78 | set->cfg_card = pd->cfg_card; | ||
| 79 | if (pd->host_caps) | ||
| 80 | set->host_caps |= pd->host_caps; | ||
| 81 | if (pd->clk_type) | ||
| 82 | set->clk_type = pd->clk_type; | ||
| 83 | } | ||
diff --git a/arch/arm/plat-samsung/dev-hwmon.c b/arch/arm/plat-samsung/dev-hwmon.c new file mode 100644 index 00000000000..c91a79ce8f3 --- /dev/null +++ b/arch/arm/plat-samsung/dev-hwmon.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/dev-hwmon.c | ||
| 2 | * | ||
| 3 | * Copyright 2008 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * http://armlinux.simtec.co.uk/ | ||
| 6 | * | ||
| 7 | * Adapted for HWMON by Maurus Cuelenaere | ||
| 8 | * | ||
| 9 | * Samsung series device definition for HWMON | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 as | ||
| 13 | * published by the Free Software Foundation. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | |||
| 19 | #include <plat/devs.h> | ||
| 20 | #include <plat/hwmon.h> | ||
| 21 | |||
| 22 | struct platform_device s3c_device_hwmon = { | ||
| 23 | .name = "s3c-hwmon", | ||
| 24 | .id = -1, | ||
| 25 | .dev.parent = &s3c_device_adc.dev, | ||
| 26 | }; | ||
| 27 | |||
| 28 | void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd) | ||
| 29 | { | ||
| 30 | s3c_set_platdata(pd, sizeof(struct s3c_hwmon_pdata), | ||
| 31 | &s3c_device_hwmon); | ||
| 32 | } | ||
diff --git a/arch/arm/plat-samsung/dev-i2c0.c b/arch/arm/plat-samsung/dev-i2c0.c new file mode 100644 index 00000000000..f8251f5098b --- /dev/null +++ b/arch/arm/plat-samsung/dev-i2c0.c | |||
| @@ -0,0 +1,70 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c/dev-i2c0.c | ||
| 2 | * | ||
| 3 | * Copyright 2008-2009 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * http://armlinux.simtec.co.uk/ | ||
| 6 | * | ||
| 7 | * S3C series device definition for i2c device 0 | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/gfp.h> | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/string.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | |||
| 19 | #include <mach/irqs.h> | ||
| 20 | #include <mach/map.h> | ||
| 21 | |||
| 22 | #include <plat/regs-iic.h> | ||
| 23 | #include <plat/iic.h> | ||
| 24 | #include <plat/devs.h> | ||
| 25 | #include <plat/cpu.h> | ||
| 26 | |||
| 27 | static struct resource s3c_i2c_resource[] = { | ||
| 28 | [0] = { | ||
| 29 | .start = S3C_PA_IIC, | ||
| 30 | .end = S3C_PA_IIC + SZ_4K - 1, | ||
| 31 | .flags = IORESOURCE_MEM, | ||
| 32 | }, | ||
| 33 | [1] = { | ||
| 34 | .start = IRQ_IIC, | ||
| 35 | .end = IRQ_IIC, | ||
| 36 | .flags = IORESOURCE_IRQ, | ||
| 37 | }, | ||
| 38 | }; | ||
| 39 | |||
| 40 | struct platform_device s3c_device_i2c0 = { | ||
| 41 | .name = "s3c2410-i2c", | ||
| 42 | #ifdef CONFIG_S3C_DEV_I2C1 | ||
| 43 | .id = 0, | ||
| 44 | #else | ||
| 45 | .id = -1, | ||
| 46 | #endif | ||
| 47 | .num_resources = ARRAY_SIZE(s3c_i2c_resource), | ||
| 48 | .resource = s3c_i2c_resource, | ||
| 49 | }; | ||
| 50 | |||
| 51 | struct s3c2410_platform_i2c default_i2c_data __initdata = { | ||
| 52 | .flags = 0, | ||
| 53 | .slave_addr = 0x10, | ||
| 54 | .frequency = 100*1000, | ||
| 55 | .sda_delay = 100, | ||
| 56 | }; | ||
| 57 | |||
| 58 | void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd) | ||
| 59 | { | ||
| 60 | struct s3c2410_platform_i2c *npd; | ||
| 61 | |||
| 62 | if (!pd) | ||
| 63 | pd = &default_i2c_data; | ||
| 64 | |||
| 65 | npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), | ||
| 66 | &s3c_device_i2c0); | ||
| 67 | |||
| 68 | if (!npd->cfg_gpio) | ||
| 69 | npd->cfg_gpio = s3c_i2c0_cfg_gpio; | ||
| 70 | } | ||
diff --git a/arch/arm/plat-samsung/dev-i2c1.c b/arch/arm/plat-samsung/dev-i2c1.c new file mode 100644 index 00000000000..3b7c7bec1cf --- /dev/null +++ b/arch/arm/plat-samsung/dev-i2c1.c | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c/dev-i2c1.c | ||
| 2 | * | ||
| 3 | * Copyright 2008-2009 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * http://armlinux.simtec.co.uk/ | ||
| 6 | * | ||
| 7 | * S3C series device definition for i2c device 1 | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/gfp.h> | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/string.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | |||
| 19 | #include <mach/irqs.h> | ||
| 20 | #include <mach/map.h> | ||
| 21 | |||
| 22 | #include <plat/regs-iic.h> | ||
| 23 | #include <plat/iic.h> | ||
| 24 | #include <plat/devs.h> | ||
| 25 | #include <plat/cpu.h> | ||
| 26 | |||
| 27 | static struct resource s3c_i2c_resource[] = { | ||
| 28 | [0] = { | ||
| 29 | .start = S3C_PA_IIC1, | ||
| 30 | .end = S3C_PA_IIC1 + SZ_4K - 1, | ||
| 31 | .flags = IORESOURCE_MEM, | ||
| 32 | }, | ||
| 33 | [1] = { | ||
| 34 | .start = IRQ_IIC1, | ||
| 35 | .end = IRQ_IIC1, | ||
| 36 | .flags = IORESOURCE_IRQ, | ||
| 37 | }, | ||
| 38 | }; | ||
| 39 | |||
| 40 | struct platform_device s3c_device_i2c1 = { | ||
| 41 | .name = "s3c2410-i2c", | ||
| 42 | .id = 1, | ||
| 43 | .num_resources = ARRAY_SIZE(s3c_i2c_resource), | ||
| 44 | .resource = s3c_i2c_resource, | ||
| 45 | }; | ||
| 46 | |||
| 47 | void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd) | ||
| 48 | { | ||
| 49 | struct s3c2410_platform_i2c *npd; | ||
| 50 | |||
| 51 | if (!pd) { | ||
| 52 | pd = &default_i2c_data; | ||
| 53 | pd->bus_num = 1; | ||
| 54 | } | ||
| 55 | |||
| 56 | npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), | ||
| 57 | &s3c_device_i2c1); | ||
| 58 | |||
| 59 | if (!npd->cfg_gpio) | ||
| 60 | npd->cfg_gpio = s3c_i2c1_cfg_gpio; | ||
| 61 | } | ||
diff --git a/arch/arm/plat-samsung/dev-i2c2.c b/arch/arm/plat-samsung/dev-i2c2.c new file mode 100644 index 00000000000..07e9fd0b1b8 --- /dev/null +++ b/arch/arm/plat-samsung/dev-i2c2.c | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c/dev-i2c2.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
| 4 | * http://www.samsung.com/ | ||
| 5 | * | ||
| 6 | * S3C series device definition for i2c device 2 | ||
| 7 | * | ||
| 8 | * Based on plat-samsung/dev-i2c0.c | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/gfp.h> | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/string.h> | ||
| 18 | #include <linux/platform_device.h> | ||
| 19 | |||
| 20 | #include <mach/irqs.h> | ||
| 21 | #include <mach/map.h> | ||
| 22 | |||
| 23 | #include <plat/regs-iic.h> | ||
| 24 | #include <plat/iic.h> | ||
| 25 | #include <plat/devs.h> | ||
| 26 | #include <plat/cpu.h> | ||
| 27 | |||
| 28 | static struct resource s3c_i2c_resource[] = { | ||
| 29 | [0] = { | ||
| 30 | .start = S3C_PA_IIC2, | ||
| 31 | .end = S3C_PA_IIC2 + SZ_4K - 1, | ||
| 32 | .flags = IORESOURCE_MEM, | ||
| 33 | }, | ||
| 34 | [1] = { | ||
| 35 | .start = IRQ_IIC2, | ||
| 36 | .end = IRQ_IIC2, | ||
| 37 | .flags = IORESOURCE_IRQ, | ||
| 38 | }, | ||
| 39 | }; | ||
| 40 | |||
| 41 | struct platform_device s3c_device_i2c2 = { | ||
| 42 | .name = "s3c2410-i2c", | ||
| 43 | .id = 2, | ||
| 44 | .num_resources = ARRAY_SIZE(s3c_i2c_resource), | ||
| 45 | .resource = s3c_i2c_resource, | ||
| 46 | }; | ||
| 47 | |||
| 48 | void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd) | ||
| 49 | { | ||
| 50 | struct s3c2410_platform_i2c *npd; | ||
| 51 | |||
| 52 | if (!pd) { | ||
| 53 | pd = &default_i2c_data; | ||
| 54 | pd->bus_num = 2; | ||
| 55 | } | ||
| 56 | |||
| 57 | npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), | ||
| 58 | &s3c_device_i2c2); | ||
| 59 | |||
| 60 | if (!npd->cfg_gpio) | ||
| 61 | npd->cfg_gpio = s3c_i2c2_cfg_gpio; | ||
| 62 | } | ||
diff --git a/arch/arm/plat-samsung/dev-i2c3.c b/arch/arm/plat-samsung/dev-i2c3.c new file mode 100644 index 00000000000..d48efa93c6e --- /dev/null +++ b/arch/arm/plat-samsung/dev-i2c3.c | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/dev-i2c3.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
| 4 | * http://www.samsung.com/ | ||
| 5 | * | ||
| 6 | * S5P series device definition for i2c device 3 | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/gfp.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/string.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | |||
| 18 | #include <mach/irqs.h> | ||
| 19 | #include <mach/map.h> | ||
| 20 | |||
| 21 | #include <plat/regs-iic.h> | ||
| 22 | #include <plat/iic.h> | ||
| 23 | #include <plat/devs.h> | ||
| 24 | #include <plat/cpu.h> | ||
| 25 | |||
| 26 | static struct resource s3c_i2c_resource[] = { | ||
| 27 | [0] = { | ||
| 28 | .start = S3C_PA_IIC3, | ||
| 29 | .end = S3C_PA_IIC3 + SZ_4K - 1, | ||
| 30 | .flags = IORESOURCE_MEM, | ||
| 31 | }, | ||
| 32 | [1] = { | ||
| 33 | .start = IRQ_IIC3, | ||
| 34 | .end = IRQ_IIC3, | ||
| 35 | .flags = IORESOURCE_IRQ, | ||
| 36 | }, | ||
| 37 | }; | ||
| 38 | |||
| 39 | struct platform_device s3c_device_i2c3 = { | ||
| 40 | .name = "s3c2440-i2c", | ||
| 41 | .id = 3, | ||
| 42 | .num_resources = ARRAY_SIZE(s3c_i2c_resource), | ||
| 43 | .resource = s3c_i2c_resource, | ||
| 44 | }; | ||
| 45 | |||
| 46 | void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd) | ||
| 47 | { | ||
| 48 | struct s3c2410_platform_i2c *npd; | ||
| 49 | |||
| 50 | if (!pd) { | ||
| 51 | pd = &default_i2c_data; | ||
| 52 | pd->bus_num = 3; | ||
| 53 | } | ||
| 54 | |||
| 55 | npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), | ||
| 56 | &s3c_device_i2c3); | ||
| 57 | |||
| 58 | if (!npd->cfg_gpio) | ||
| 59 | npd->cfg_gpio = s3c_i2c3_cfg_gpio; | ||
| 60 | } | ||
diff --git a/arch/arm/plat-samsung/dev-i2c4.c b/arch/arm/plat-samsung/dev-i2c4.c new file mode 100644 index 00000000000..07e26444efe --- /dev/null +++ b/arch/arm/plat-samsung/dev-i2c4.c | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/dev-i2c4.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
| 4 | * http://www.samsung.com/ | ||
| 5 | * | ||
| 6 | * S5P series device definition for i2c device 3 | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/gfp.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/string.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | |||
| 18 | #include <mach/irqs.h> | ||
| 19 | #include <mach/map.h> | ||
| 20 | |||
| 21 | #include <plat/regs-iic.h> | ||
| 22 | #include <plat/iic.h> | ||
| 23 | #include <plat/devs.h> | ||
| 24 | #include <plat/cpu.h> | ||
| 25 | |||
| 26 | static struct resource s3c_i2c_resource[] = { | ||
| 27 | [0] = { | ||
| 28 | .start = S3C_PA_IIC4, | ||
| 29 | .end = S3C_PA_IIC4 + SZ_4K - 1, | ||
| 30 | .flags = IORESOURCE_MEM, | ||
| 31 | }, | ||
| 32 | [1] = { | ||
| 33 | .start = IRQ_IIC4, | ||
| 34 | .end = IRQ_IIC4, | ||
| 35 | .flags = IORESOURCE_IRQ, | ||
| 36 | }, | ||
| 37 | }; | ||
| 38 | |||
| 39 | struct platform_device s3c_device_i2c4 = { | ||
| 40 | .name = "s3c2440-i2c", | ||
| 41 | .id = 4, | ||
| 42 | .num_resources = ARRAY_SIZE(s3c_i2c_resource), | ||
| 43 | .resource = s3c_i2c_resource, | ||
| 44 | }; | ||
| 45 | |||
| 46 | void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd) | ||
| 47 | { | ||
| 48 | struct s3c2410_platform_i2c *npd; | ||
| 49 | |||
| 50 | if (!pd) { | ||
| 51 | pd = &default_i2c_data; | ||
| 52 | pd->bus_num = 4; | ||
| 53 | } | ||
| 54 | |||
| 55 | npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), | ||
| 56 | &s3c_device_i2c4); | ||
| 57 | |||
| 58 | if (!npd->cfg_gpio) | ||
| 59 | npd->cfg_gpio = s3c_i2c4_cfg_gpio; | ||
| 60 | } | ||
diff --git a/arch/arm/plat-samsung/dev-i2c5.c b/arch/arm/plat-samsung/dev-i2c5.c new file mode 100644 index 00000000000..f4965578456 --- /dev/null +++ b/arch/arm/plat-samsung/dev-i2c5.c | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/dev-i2c3.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
| 4 | * http://www.samsung.com/ | ||
| 5 | * | ||
| 6 | * S5P series device definition for i2c device 3 | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/gfp.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/string.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | |||
| 18 | #include <mach/irqs.h> | ||
| 19 | #include <mach/map.h> | ||
| 20 | |||
| 21 | #include <plat/regs-iic.h> | ||
| 22 | #include <plat/iic.h> | ||
| 23 | #include <plat/devs.h> | ||
| 24 | #include <plat/cpu.h> | ||
| 25 | |||
| 26 | static struct resource s3c_i2c_resource[] = { | ||
| 27 | [0] = { | ||
| 28 | .start = S3C_PA_IIC5, | ||
| 29 | .end = S3C_PA_IIC5 + SZ_4K - 1, | ||
| 30 | .flags = IORESOURCE_MEM, | ||
| 31 | }, | ||
| 32 | [1] = { | ||
| 33 | .start = IRQ_IIC5, | ||
| 34 | .end = IRQ_IIC5, | ||
| 35 | .flags = IORESOURCE_IRQ, | ||
| 36 | }, | ||
| 37 | }; | ||
| 38 | |||
| 39 | struct platform_device s3c_device_i2c5 = { | ||
| 40 | .name = "s3c2440-i2c", | ||
| 41 | .id = 5, | ||
| 42 | .num_resources = ARRAY_SIZE(s3c_i2c_resource), | ||
| 43 | .resource = s3c_i2c_resource, | ||
| 44 | }; | ||
| 45 | |||
| 46 | void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd) | ||
| 47 | { | ||
| 48 | struct s3c2410_platform_i2c *npd; | ||
| 49 | |||
| 50 | if (!pd) { | ||
| 51 | pd = &default_i2c_data; | ||
| 52 | pd->bus_num = 5; | ||
| 53 | } | ||
| 54 | |||
| 55 | npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), | ||
| 56 | &s3c_device_i2c5); | ||
| 57 | |||
| 58 | if (!npd->cfg_gpio) | ||
| 59 | npd->cfg_gpio = s3c_i2c5_cfg_gpio; | ||
| 60 | } | ||
diff --git a/arch/arm/plat-samsung/dev-i2c6.c b/arch/arm/plat-samsung/dev-i2c6.c new file mode 100644 index 00000000000..141d799944e --- /dev/null +++ b/arch/arm/plat-samsung/dev-i2c6.c | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/dev-i2c6.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
| 4 | * http://www.samsung.com/ | ||
| 5 | * | ||
| 6 | * S5P series device definition for i2c device 6 | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/gfp.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/string.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | |||
| 18 | #include <mach/irqs.h> | ||
| 19 | #include <mach/map.h> | ||
| 20 | |||
| 21 | #include <plat/regs-iic.h> | ||
| 22 | #include <plat/iic.h> | ||
| 23 | #include <plat/devs.h> | ||
| 24 | #include <plat/cpu.h> | ||
| 25 | |||
| 26 | static struct resource s3c_i2c_resource[] = { | ||
| 27 | [0] = { | ||
| 28 | .start = S3C_PA_IIC6, | ||
| 29 | .end = S3C_PA_IIC6 + SZ_4K - 1, | ||
| 30 | .flags = IORESOURCE_MEM, | ||
| 31 | }, | ||
| 32 | [1] = { | ||
| 33 | .start = IRQ_IIC6, | ||
| 34 | .end = IRQ_IIC6, | ||
| 35 | .flags = IORESOURCE_IRQ, | ||
| 36 | }, | ||
| 37 | }; | ||
| 38 | |||
| 39 | struct platform_device s3c_device_i2c6 = { | ||
| 40 | .name = "s3c2440-i2c", | ||
| 41 | .id = 6, | ||
| 42 | .num_resources = ARRAY_SIZE(s3c_i2c_resource), | ||
| 43 | .resource = s3c_i2c_resource, | ||
| 44 | }; | ||
| 45 | |||
| 46 | void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd) | ||
| 47 | { | ||
| 48 | struct s3c2410_platform_i2c *npd; | ||
| 49 | |||
| 50 | if (!pd) { | ||
| 51 | pd = &default_i2c_data; | ||
| 52 | pd->bus_num = 6; | ||
| 53 | } | ||
| 54 | |||
| 55 | npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), | ||
| 56 | &s3c_device_i2c6); | ||
| 57 | |||
| 58 | if (!npd->cfg_gpio) | ||
| 59 | npd->cfg_gpio = s3c_i2c6_cfg_gpio; | ||
| 60 | } | ||
diff --git a/arch/arm/plat-samsung/dev-i2c7.c b/arch/arm/plat-samsung/dev-i2c7.c new file mode 100644 index 00000000000..9dddcd1665b --- /dev/null +++ b/arch/arm/plat-samsung/dev-i2c7.c | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/dev-i2c7.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
| 4 | * http://www.samsung.com/ | ||
| 5 | * | ||
| 6 | * S5P series device definition for i2c device 7 | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/gfp.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/string.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | |||
| 18 | #include <mach/irqs.h> | ||
| 19 | #include <mach/map.h> | ||
| 20 | |||
| 21 | #include <plat/regs-iic.h> | ||
| 22 | #include <plat/iic.h> | ||
| 23 | #include <plat/devs.h> | ||
| 24 | #include <plat/cpu.h> | ||
| 25 | |||
| 26 | static struct resource s3c_i2c_resource[] = { | ||
| 27 | [0] = { | ||
| 28 | .start = S3C_PA_IIC7, | ||
| 29 | .end = S3C_PA_IIC7 + SZ_4K - 1, | ||
| 30 | .flags = IORESOURCE_MEM, | ||
| 31 | }, | ||
| 32 | [1] = { | ||
| 33 | .start = IRQ_IIC7, | ||
| 34 | .end = IRQ_IIC7, | ||
| 35 | .flags = IORESOURCE_IRQ, | ||
| 36 | }, | ||
| 37 | }; | ||
| 38 | |||
| 39 | struct platform_device s3c_device_i2c7 = { | ||
| 40 | .name = "s3c2440-i2c", | ||
| 41 | .id = 7, | ||
| 42 | .num_resources = ARRAY_SIZE(s3c_i2c_resource), | ||
| 43 | .resource = s3c_i2c_resource, | ||
| 44 | }; | ||
| 45 | |||
| 46 | void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd) | ||
| 47 | { | ||
| 48 | struct s3c2410_platform_i2c *npd; | ||
| 49 | |||
| 50 | if (!pd) { | ||
| 51 | pd = &default_i2c_data; | ||
| 52 | pd->bus_num = 7; | ||
| 53 | } | ||
| 54 | |||
| 55 | npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), | ||
| 56 | &s3c_device_i2c7); | ||
| 57 | |||
| 58 | if (!npd->cfg_gpio) | ||
| 59 | npd->cfg_gpio = s3c_i2c7_cfg_gpio; | ||
| 60 | } | ||
diff --git a/arch/arm/plat-samsung/dev-ide.c b/arch/arm/plat-samsung/dev-ide.c new file mode 100644 index 00000000000..b497982795a --- /dev/null +++ b/arch/arm/plat-samsung/dev-ide.c | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/dev-ide.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
| 4 | * http://www.samsung.com | ||
| 5 | * | ||
| 6 | * Samsung CF-ATA device definition. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/interrupt.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | |||
| 17 | #include <mach/map.h> | ||
| 18 | #include <plat/ata.h> | ||
| 19 | #include <plat/devs.h> | ||
| 20 | |||
| 21 | static struct resource s3c_cfcon_resource[] = { | ||
| 22 | [0] = { | ||
| 23 | .start = SAMSUNG_PA_CFCON, | ||
| 24 | .end = SAMSUNG_PA_CFCON + SZ_16K - 1, | ||
| 25 | .flags = IORESOURCE_MEM, | ||
| 26 | }, | ||
| 27 | [1] = { | ||
| 28 | .start = IRQ_CFCON, | ||
| 29 | .end = IRQ_CFCON, | ||
| 30 | .flags = IORESOURCE_IRQ, | ||
| 31 | }, | ||
| 32 | }; | ||
| 33 | |||
| 34 | struct platform_device s3c_device_cfcon = { | ||
| 35 | .id = 0, | ||
| 36 | .num_resources = ARRAY_SIZE(s3c_cfcon_resource), | ||
| 37 | .resource = s3c_cfcon_resource, | ||
| 38 | }; | ||
| 39 | |||
| 40 | void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata) | ||
| 41 | { | ||
| 42 | s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata), | ||
| 43 | &s3c_device_cfcon); | ||
| 44 | } | ||
diff --git a/arch/arm/plat-samsung/dev-keypad.c b/arch/arm/plat-samsung/dev-keypad.c new file mode 100644 index 00000000000..677c2d731b6 --- /dev/null +++ b/arch/arm/plat-samsung/dev-keypad.c | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/plat-samsung/dev-keypad.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd | ||
| 5 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License as published by the | ||
| 9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 10 | * option) any later version. | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/platform_device.h> | ||
| 15 | #include <mach/irqs.h> | ||
| 16 | #include <mach/map.h> | ||
| 17 | #include <plat/cpu.h> | ||
| 18 | #include <plat/devs.h> | ||
| 19 | #include <plat/keypad.h> | ||
| 20 | |||
| 21 | static struct resource samsung_keypad_resources[] = { | ||
| 22 | [0] = { | ||
| 23 | .start = SAMSUNG_PA_KEYPAD, | ||
| 24 | .end = SAMSUNG_PA_KEYPAD + 0x20 - 1, | ||
| 25 | .flags = IORESOURCE_MEM, | ||
| 26 | }, | ||
| 27 | [1] = { | ||
| 28 | .start = IRQ_KEYPAD, | ||
| 29 | .end = IRQ_KEYPAD, | ||
| 30 | .flags = IORESOURCE_IRQ, | ||
| 31 | }, | ||
| 32 | }; | ||
| 33 | |||
| 34 | struct platform_device samsung_device_keypad = { | ||
| 35 | .name = "samsung-keypad", | ||
| 36 | .id = -1, | ||
| 37 | .num_resources = ARRAY_SIZE(samsung_keypad_resources), | ||
| 38 | .resource = samsung_keypad_resources, | ||
| 39 | }; | ||
| 40 | |||
| 41 | void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd) | ||
| 42 | { | ||
| 43 | struct samsung_keypad_platdata *npd; | ||
| 44 | |||
| 45 | npd = s3c_set_platdata(pd, sizeof(struct samsung_keypad_platdata), | ||
| 46 | &samsung_device_keypad); | ||
| 47 | |||
| 48 | if (!npd->cfg_gpio) | ||
| 49 | npd->cfg_gpio = samsung_keypad_cfg_gpio; | ||
| 50 | } | ||
diff --git a/arch/arm/plat-samsung/dev-nand.c b/arch/arm/plat-samsung/dev-nand.c new file mode 100644 index 00000000000..b8e30ec6ac2 --- /dev/null +++ b/arch/arm/plat-samsung/dev-nand.c | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | /* | ||
| 2 | * S3C series device definition for nand device | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/gfp.h> | ||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/platform_device.h> | ||
| 12 | |||
| 13 | #include <linux/mtd/mtd.h> | ||
| 14 | #include <linux/mtd/partitions.h> | ||
| 15 | |||
| 16 | #include <mach/map.h> | ||
| 17 | #include <plat/devs.h> | ||
| 18 | #include <plat/nand.h> | ||
| 19 | |||
| 20 | static struct resource s3c_nand_resource[] = { | ||
| 21 | [0] = { | ||
| 22 | .start = S3C_PA_NAND, | ||
| 23 | .end = S3C_PA_NAND + SZ_1M, | ||
| 24 | .flags = IORESOURCE_MEM, | ||
| 25 | } | ||
| 26 | }; | ||
| 27 | |||
| 28 | struct platform_device s3c_device_nand = { | ||
| 29 | .name = "s3c2410-nand", | ||
| 30 | .id = -1, | ||
| 31 | .num_resources = ARRAY_SIZE(s3c_nand_resource), | ||
| 32 | .resource = s3c_nand_resource, | ||
| 33 | }; | ||
| 34 | |||
| 35 | EXPORT_SYMBOL(s3c_device_nand); | ||
| 36 | |||
| 37 | /** | ||
| 38 | * s3c_nand_copy_set() - copy nand set data | ||
| 39 | * @set: The new structure, directly copied from the old. | ||
| 40 | * | ||
| 41 | * Copy all the fields from the NAND set field from what is probably __initdata | ||
| 42 | * to new kernel memory. The code returns 0 if the copy happened correctly or | ||
| 43 | * an error code for the calling function to display. | ||
| 44 | * | ||
| 45 | * Note, we currently do not try and look to see if we've already copied the | ||
| 46 | * data in a previous set. | ||
| 47 | */ | ||
| 48 | static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set) | ||
| 49 | { | ||
| 50 | void *ptr; | ||
| 51 | int size; | ||
| 52 | |||
| 53 | size = sizeof(struct mtd_partition) * set->nr_partitions; | ||
| 54 | if (size) { | ||
| 55 | ptr = kmemdup(set->partitions, size, GFP_KERNEL); | ||
| 56 | set->partitions = ptr; | ||
| 57 | |||
| 58 | if (!ptr) | ||
| 59 | return -ENOMEM; | ||
| 60 | } | ||
| 61 | |||
| 62 | if (set->nr_map && set->nr_chips) { | ||
| 63 | size = sizeof(int) * set->nr_chips; | ||
| 64 | ptr = kmemdup(set->nr_map, size, GFP_KERNEL); | ||
| 65 | set->nr_map = ptr; | ||
| 66 | |||
| 67 | if (!ptr) | ||
| 68 | return -ENOMEM; | ||
| 69 | } | ||
| 70 | |||
| 71 | if (set->ecc_layout) { | ||
| 72 | ptr = kmemdup(set->ecc_layout, | ||
| 73 | sizeof(struct nand_ecclayout), GFP_KERNEL); | ||
| 74 | set->ecc_layout = ptr; | ||
| 75 | |||
| 76 | if (!ptr) | ||
| 77 | return -ENOMEM; | ||
| 78 | } | ||
| 79 | |||
| 80 | return 0; | ||
| 81 | } | ||
| 82 | |||
| 83 | void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand) | ||
| 84 | { | ||
| 85 | struct s3c2410_platform_nand *npd; | ||
| 86 | int size; | ||
| 87 | int ret; | ||
| 88 | |||
| 89 | /* note, if we get a failure in allocation, we simply drop out of the | ||
| 90 | * function. If there is so little memory available at initialisation | ||
| 91 | * time then there is little chance the system is going to run. | ||
| 92 | */ | ||
| 93 | |||
| 94 | npd = s3c_set_platdata(nand, sizeof(struct s3c2410_platform_nand), | ||
| 95 | &s3c_device_nand); | ||
| 96 | if (!npd) | ||
| 97 | return; | ||
| 98 | |||
| 99 | /* now see if we need to copy any of the nand set data */ | ||
| 100 | |||
| 101 | size = sizeof(struct s3c2410_nand_set) * npd->nr_sets; | ||
| 102 | if (size) { | ||
| 103 | struct s3c2410_nand_set *from = npd->sets; | ||
| 104 | struct s3c2410_nand_set *to; | ||
| 105 | int i; | ||
| 106 | |||
| 107 | to = kmemdup(from, size, GFP_KERNEL); | ||
| 108 | npd->sets = to; /* set, even if we failed */ | ||
| 109 | |||
| 110 | if (!to) { | ||
| 111 | printk(KERN_ERR "%s: no memory for sets\n", __func__); | ||
| 112 | return; | ||
| 113 | } | ||
| 114 | |||
| 115 | for (i = 0; i < npd->nr_sets; i++) { | ||
| 116 | ret = s3c_nand_copy_set(to); | ||
| 117 | if (ret) { | ||
| 118 | printk(KERN_ERR "%s: failed to copy set %d\n", | ||
| 119 | __func__, i); | ||
| 120 | return; | ||
| 121 | } | ||
| 122 | to++; | ||
| 123 | } | ||
| 124 | } | ||
| 125 | } | ||
diff --git a/arch/arm/plat-samsung/dev-onenand.c b/arch/arm/plat-samsung/dev-onenand.c new file mode 100644 index 00000000000..f54ae71f0cd --- /dev/null +++ b/arch/arm/plat-samsung/dev-onenand.c | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/plat-samsung/dev-onenand.c | ||
| 3 | * | ||
| 4 | * Copyright (c) 2008-2010 Samsung Electronics | ||
| 5 | * Kyungmin Park <kyungmin.park@samsung.com> | ||
| 6 | * | ||
| 7 | * S3C64XX/S5PC100 series device definition for OneNAND devices | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | |||
| 17 | #include <mach/irqs.h> | ||
| 18 | #include <mach/map.h> | ||
| 19 | |||
| 20 | static struct resource s3c_onenand_resources[] = { | ||
| 21 | [0] = { | ||
| 22 | .start = S3C_PA_ONENAND, | ||
| 23 | .end = S3C_PA_ONENAND + 0x400 - 1, | ||
| 24 | .flags = IORESOURCE_MEM, | ||
| 25 | }, | ||
| 26 | [1] = { | ||
| 27 | .start = S3C_PA_ONENAND_BUF, | ||
| 28 | .end = S3C_PA_ONENAND_BUF + S3C_SZ_ONENAND_BUF - 1, | ||
| 29 | .flags = IORESOURCE_MEM, | ||
| 30 | }, | ||
| 31 | [2] = { | ||
| 32 | .start = IRQ_ONENAND, | ||
| 33 | .end = IRQ_ONENAND, | ||
| 34 | .flags = IORESOURCE_IRQ, | ||
| 35 | }, | ||
| 36 | }; | ||
| 37 | |||
| 38 | struct platform_device s3c_device_onenand = { | ||
| 39 | .name = "samsung-onenand", | ||
| 40 | .id = 0, | ||
| 41 | .num_resources = ARRAY_SIZE(s3c_onenand_resources), | ||
| 42 | .resource = s3c_onenand_resources, | ||
| 43 | }; | ||
diff --git a/arch/arm/plat-samsung/dev-pwm.c b/arch/arm/plat-samsung/dev-pwm.c new file mode 100644 index 00000000000..dab47b0e190 --- /dev/null +++ b/arch/arm/plat-samsung/dev-pwm.c | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/dev-pwm.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. | ||
| 4 | * http://www.samsung.com | ||
| 5 | * | ||
| 6 | * Copyright (c) 2007 Ben Dooks | ||
| 7 | * Copyright (c) 2008 Simtec Electronics | ||
| 8 | * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org> | ||
| 9 | * | ||
| 10 | * S3C series device definition for the PWM timer | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify | ||
| 13 | * it under the terms of the GNU General Public License version 2 as | ||
| 14 | * published by the Free Software Foundation. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/platform_device.h> | ||
| 19 | |||
| 20 | #include <mach/irqs.h> | ||
| 21 | |||
| 22 | #include <plat/devs.h> | ||
| 23 | |||
| 24 | #define TIMER_RESOURCE_SIZE (1) | ||
| 25 | |||
| 26 | #define TIMER_RESOURCE(_tmr, _irq) \ | ||
| 27 | (struct resource [TIMER_RESOURCE_SIZE]) { \ | ||
| 28 | [0] = { \ | ||
| 29 | .start = _irq, \ | ||
| 30 | .end = _irq, \ | ||
| 31 | .flags = IORESOURCE_IRQ \ | ||
| 32 | } \ | ||
| 33 | } | ||
| 34 | |||
| 35 | #define DEFINE_S3C_TIMER(_tmr_no, _irq) \ | ||
| 36 | .name = "s3c24xx-pwm", \ | ||
| 37 | .id = _tmr_no, \ | ||
| 38 | .num_resources = TIMER_RESOURCE_SIZE, \ | ||
| 39 | .resource = TIMER_RESOURCE(_tmr_no, _irq), \ | ||
| 40 | |||
| 41 | /* | ||
| 42 | * since we already have an static mapping for the timer, | ||
| 43 | * we do not bother setting any IO resource for the base. | ||
| 44 | */ | ||
| 45 | |||
| 46 | struct platform_device s3c_device_timer[] = { | ||
| 47 | [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) }, | ||
| 48 | [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) }, | ||
| 49 | [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) }, | ||
| 50 | [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) }, | ||
| 51 | [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) }, | ||
| 52 | }; | ||
| 53 | EXPORT_SYMBOL(s3c_device_timer); | ||
diff --git a/arch/arm/plat-samsung/dev-rtc.c b/arch/arm/plat-samsung/dev-rtc.c new file mode 100644 index 00000000000..bf4e2267333 --- /dev/null +++ b/arch/arm/plat-samsung/dev-rtc.c | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/dev-rtc.c | ||
| 2 | * | ||
| 3 | * Copyright 2009 by Maurus Cuelenaere <mcuelenaere@gmail.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/string.h> | ||
| 12 | #include <linux/platform_device.h> | ||
| 13 | |||
| 14 | #include <mach/irqs.h> | ||
| 15 | #include <mach/map.h> | ||
| 16 | |||
| 17 | #include <plat/devs.h> | ||
| 18 | |||
| 19 | static struct resource s3c_rtc_resource[] = { | ||
| 20 | [0] = { | ||
| 21 | .start = S3C_PA_RTC, | ||
| 22 | .end = S3C_PA_RTC + 0xff, | ||
| 23 | .flags = IORESOURCE_MEM, | ||
| 24 | }, | ||
| 25 | [1] = { | ||
| 26 | .start = IRQ_RTC_ALARM, | ||
| 27 | .end = IRQ_RTC_ALARM, | ||
| 28 | .flags = IORESOURCE_IRQ, | ||
| 29 | }, | ||
| 30 | [2] = { | ||
| 31 | .start = IRQ_RTC_TIC, | ||
| 32 | .end = IRQ_RTC_TIC, | ||
| 33 | .flags = IORESOURCE_IRQ | ||
| 34 | } | ||
| 35 | }; | ||
| 36 | |||
| 37 | struct platform_device s3c_device_rtc = { | ||
| 38 | .name = "s3c64xx-rtc", | ||
| 39 | .id = -1, | ||
| 40 | .num_resources = ARRAY_SIZE(s3c_rtc_resource), | ||
| 41 | .resource = s3c_rtc_resource, | ||
| 42 | }; | ||
| 43 | EXPORT_SYMBOL(s3c_device_rtc); | ||
diff --git a/arch/arm/plat-samsung/dev-ts.c b/arch/arm/plat-samsung/dev-ts.c new file mode 100644 index 00000000000..82543f0248a --- /dev/null +++ b/arch/arm/plat-samsung/dev-ts.c | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /* linux/arch/arm/mach-s3c64xx/dev-ts.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2008 Simtec Electronics | ||
| 4 | * http://armlinux.simtec.co.uk/ | ||
| 5 | * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org> | ||
| 6 | * | ||
| 7 | * Adapted by Maurus Cuelenaere for s3c64xx | ||
| 8 | * | ||
| 9 | * S3C64XX series device definition for touchscreen device | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 as | ||
| 13 | * published by the Free Software Foundation. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/string.h> | ||
| 18 | #include <linux/platform_device.h> | ||
| 19 | |||
| 20 | #include <mach/irqs.h> | ||
| 21 | #include <mach/map.h> | ||
| 22 | |||
| 23 | #include <plat/devs.h> | ||
| 24 | #include <plat/ts.h> | ||
| 25 | |||
| 26 | static struct resource s3c_ts_resource[] = { | ||
| 27 | [0] = { | ||
| 28 | .start = SAMSUNG_PA_ADC, | ||
| 29 | .end = SAMSUNG_PA_ADC + SZ_256 - 1, | ||
| 30 | .flags = IORESOURCE_MEM, | ||
| 31 | }, | ||
| 32 | [1] = { | ||
| 33 | .start = IRQ_TC, | ||
| 34 | .end = IRQ_TC, | ||
| 35 | .flags = IORESOURCE_IRQ, | ||
| 36 | }, | ||
| 37 | }; | ||
| 38 | |||
| 39 | struct platform_device s3c_device_ts = { | ||
| 40 | .name = "s3c64xx-ts", | ||
| 41 | .id = -1, | ||
| 42 | .num_resources = ARRAY_SIZE(s3c_ts_resource), | ||
| 43 | .resource = s3c_ts_resource, | ||
| 44 | }; | ||
| 45 | |||
| 46 | void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd) | ||
| 47 | { | ||
| 48 | s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info), | ||
| 49 | &s3c_device_ts); | ||
| 50 | } | ||
diff --git a/arch/arm/plat-samsung/dev-usb-hsotg.c b/arch/arm/plat-samsung/dev-usb-hsotg.c new file mode 100644 index 00000000000..33a844ab691 --- /dev/null +++ b/arch/arm/plat-samsung/dev-usb-hsotg.c | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c/dev-usb-hsotg.c | ||
| 2 | * | ||
| 3 | * Copyright 2008 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * http://armlinux.simtec.co.uk/ | ||
| 6 | * | ||
| 7 | * S3C series device definition for USB high-speed UDC/OtG block | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/string.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <linux/dma-mapping.h> | ||
| 18 | |||
| 19 | #include <mach/irqs.h> | ||
| 20 | #include <mach/map.h> | ||
| 21 | |||
| 22 | #include <plat/devs.h> | ||
| 23 | |||
| 24 | static struct resource s3c_usb_hsotg_resources[] = { | ||
| 25 | [0] = { | ||
| 26 | .start = S3C_PA_USB_HSOTG, | ||
| 27 | .end = S3C_PA_USB_HSOTG + 0x10000 - 1, | ||
| 28 | .flags = IORESOURCE_MEM, | ||
| 29 | }, | ||
| 30 | [1] = { | ||
| 31 | .start = IRQ_OTG, | ||
| 32 | .end = IRQ_OTG, | ||
| 33 | .flags = IORESOURCE_IRQ, | ||
| 34 | }, | ||
| 35 | }; | ||
| 36 | |||
| 37 | static u64 s3c_hsotg_dmamask = DMA_BIT_MASK(32); | ||
| 38 | |||
| 39 | struct platform_device s3c_device_usb_hsotg = { | ||
| 40 | .name = "s3c-hsotg", | ||
| 41 | .id = -1, | ||
| 42 | .num_resources = ARRAY_SIZE(s3c_usb_hsotg_resources), | ||
| 43 | .resource = s3c_usb_hsotg_resources, | ||
| 44 | .dev = { | ||
| 45 | .dma_mask = &s3c_hsotg_dmamask, | ||
| 46 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 47 | }, | ||
| 48 | }; | ||
diff --git a/arch/arm/plat-samsung/dev-usb.c b/arch/arm/plat-samsung/dev-usb.c new file mode 100644 index 00000000000..33fbaa96770 --- /dev/null +++ b/arch/arm/plat-samsung/dev-usb.c | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c/dev-usb.c | ||
| 2 | * | ||
| 3 | * Copyright 2008 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * http://armlinux.simtec.co.uk/ | ||
| 6 | * | ||
| 7 | * S3C series device definition for USB host | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/gfp.h> | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/string.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | |||
| 19 | #include <mach/irqs.h> | ||
| 20 | #include <mach/map.h> | ||
| 21 | |||
| 22 | #include <plat/devs.h> | ||
| 23 | #include <plat/usb-control.h> | ||
| 24 | |||
| 25 | static struct resource s3c_usb_resource[] = { | ||
| 26 | [0] = { | ||
| 27 | .start = S3C_PA_USBHOST, | ||
| 28 | .end = S3C_PA_USBHOST + 0x100 - 1, | ||
| 29 | .flags = IORESOURCE_MEM, | ||
| 30 | }, | ||
| 31 | [1] = { | ||
| 32 | .start = IRQ_USBH, | ||
| 33 | .end = IRQ_USBH, | ||
| 34 | .flags = IORESOURCE_IRQ, | ||
| 35 | } | ||
| 36 | }; | ||
| 37 | |||
| 38 | static u64 s3c_device_usb_dmamask = 0xffffffffUL; | ||
| 39 | |||
| 40 | struct platform_device s3c_device_ohci = { | ||
| 41 | .name = "s3c2410-ohci", | ||
| 42 | .id = -1, | ||
| 43 | .num_resources = ARRAY_SIZE(s3c_usb_resource), | ||
| 44 | .resource = s3c_usb_resource, | ||
| 45 | .dev = { | ||
| 46 | .dma_mask = &s3c_device_usb_dmamask, | ||
| 47 | .coherent_dma_mask = 0xffffffffUL | ||
| 48 | } | ||
| 49 | }; | ||
| 50 | |||
| 51 | EXPORT_SYMBOL(s3c_device_ohci); | ||
| 52 | |||
| 53 | /** | ||
| 54 | * s3c_ohci_set_platdata - initialise OHCI device platform data | ||
| 55 | * @info: The platform data. | ||
| 56 | * | ||
| 57 | * This call copies the @info passed in and sets the device .platform_data | ||
| 58 | * field to that copy. The @info is copied so that the original can be marked | ||
| 59 | * __initdata. | ||
| 60 | */ | ||
| 61 | void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info) | ||
| 62 | { | ||
| 63 | s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info), | ||
| 64 | &s3c_device_ohci); | ||
| 65 | } | ||
diff --git a/arch/arm/plat-samsung/dev-wdt.c b/arch/arm/plat-samsung/dev-wdt.c new file mode 100644 index 00000000000..019b5b8cf14 --- /dev/null +++ b/arch/arm/plat-samsung/dev-wdt.c | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/dev-wdt.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2004 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * | ||
| 6 | * S3C series device definition for the watchdog timer | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | |||
| 16 | #include <mach/irqs.h> | ||
| 17 | #include <mach/map.h> | ||
| 18 | |||
| 19 | #include <plat/devs.h> | ||
| 20 | |||
| 21 | static struct resource s3c_wdt_resource[] = { | ||
| 22 | [0] = { | ||
| 23 | .start = S3C_PA_WDT, | ||
| 24 | .end = S3C_PA_WDT + SZ_1K, | ||
| 25 | .flags = IORESOURCE_MEM, | ||
| 26 | }, | ||
| 27 | [1] = { | ||
| 28 | .start = IRQ_WDT, | ||
| 29 | .end = IRQ_WDT, | ||
| 30 | .flags = IORESOURCE_IRQ, | ||
| 31 | } | ||
| 32 | }; | ||
| 33 | |||
| 34 | struct platform_device s3c_device_wdt = { | ||
| 35 | .name = "s3c2410-wdt", | ||
| 36 | .id = -1, | ||
| 37 | .num_resources = ARRAY_SIZE(s3c_wdt_resource), | ||
| 38 | .resource = s3c_wdt_resource, | ||
| 39 | }; | ||
| 40 | EXPORT_SYMBOL(s3c_device_wdt); | ||
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c new file mode 100644 index 00000000000..1c0b0401594 --- /dev/null +++ b/arch/arm/plat-samsung/gpio-config.c | |||
| @@ -0,0 +1,431 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c/gpio-config.c | ||
| 2 | * | ||
| 3 | * Copyright 2008 Openmoko, Inc. | ||
| 4 | * Copyright 2008-2010 Simtec Electronics | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * http://armlinux.simtec.co.uk/ | ||
| 7 | * | ||
| 8 | * S3C series GPIO configuration core | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/gpio.h> | ||
| 18 | #include <linux/io.h> | ||
| 19 | |||
| 20 | #include <plat/gpio-core.h> | ||
| 21 | #include <plat/gpio-cfg.h> | ||
| 22 | #include <plat/gpio-cfg-helpers.h> | ||
| 23 | |||
| 24 | int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) | ||
| 25 | { | ||
| 26 | struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); | ||
| 27 | unsigned long flags; | ||
| 28 | int offset; | ||
| 29 | int ret; | ||
| 30 | |||
| 31 | if (!chip) | ||
| 32 | return -EINVAL; | ||
| 33 | |||
| 34 | offset = pin - chip->chip.base; | ||
| 35 | |||
| 36 | s3c_gpio_lock(chip, flags); | ||
| 37 | ret = s3c_gpio_do_setcfg(chip, offset, config); | ||
| 38 | s3c_gpio_unlock(chip, flags); | ||
| 39 | |||
| 40 | return ret; | ||
| 41 | } | ||
| 42 | EXPORT_SYMBOL(s3c_gpio_cfgpin); | ||
| 43 | |||
| 44 | int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr, | ||
| 45 | unsigned int cfg) | ||
| 46 | { | ||
| 47 | int ret; | ||
| 48 | |||
| 49 | for (; nr > 0; nr--, start++) { | ||
| 50 | ret = s3c_gpio_cfgpin(start, cfg); | ||
| 51 | if (ret != 0) | ||
| 52 | return ret; | ||
| 53 | } | ||
| 54 | |||
| 55 | return 0; | ||
| 56 | } | ||
| 57 | EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range); | ||
| 58 | |||
| 59 | int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr, | ||
| 60 | unsigned int cfg, s3c_gpio_pull_t pull) | ||
| 61 | { | ||
| 62 | int ret; | ||
| 63 | |||
| 64 | for (; nr > 0; nr--, start++) { | ||
| 65 | s3c_gpio_setpull(start, pull); | ||
| 66 | ret = s3c_gpio_cfgpin(start, cfg); | ||
| 67 | if (ret != 0) | ||
| 68 | return ret; | ||
| 69 | } | ||
| 70 | |||
| 71 | return 0; | ||
| 72 | } | ||
| 73 | EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range); | ||
| 74 | |||
| 75 | unsigned s3c_gpio_getcfg(unsigned int pin) | ||
| 76 | { | ||
| 77 | struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); | ||
| 78 | unsigned long flags; | ||
| 79 | unsigned ret = 0; | ||
| 80 | int offset; | ||
| 81 | |||
| 82 | if (chip) { | ||
| 83 | offset = pin - chip->chip.base; | ||
| 84 | |||
| 85 | s3c_gpio_lock(chip, flags); | ||
| 86 | ret = s3c_gpio_do_getcfg(chip, offset); | ||
| 87 | s3c_gpio_unlock(chip, flags); | ||
| 88 | } | ||
| 89 | |||
| 90 | return ret; | ||
| 91 | } | ||
| 92 | EXPORT_SYMBOL(s3c_gpio_getcfg); | ||
| 93 | |||
| 94 | |||
| 95 | int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) | ||
| 96 | { | ||
| 97 | struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); | ||
| 98 | unsigned long flags; | ||
| 99 | int offset, ret; | ||
| 100 | |||
| 101 | if (!chip) | ||
| 102 | return -EINVAL; | ||
| 103 | |||
| 104 | offset = pin - chip->chip.base; | ||
| 105 | |||
| 106 | s3c_gpio_lock(chip, flags); | ||
| 107 | ret = s3c_gpio_do_setpull(chip, offset, pull); | ||
| 108 | s3c_gpio_unlock(chip, flags); | ||
| 109 | |||
| 110 | return ret; | ||
| 111 | } | ||
| 112 | EXPORT_SYMBOL(s3c_gpio_setpull); | ||
| 113 | |||
| 114 | s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin) | ||
| 115 | { | ||
| 116 | struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); | ||
| 117 | unsigned long flags; | ||
| 118 | int offset; | ||
| 119 | u32 pup = 0; | ||
| 120 | |||
| 121 | if (chip) { | ||
| 122 | offset = pin - chip->chip.base; | ||
| 123 | |||
| 124 | s3c_gpio_lock(chip, flags); | ||
| 125 | pup = s3c_gpio_do_getpull(chip, offset); | ||
| 126 | s3c_gpio_unlock(chip, flags); | ||
| 127 | } | ||
| 128 | |||
| 129 | return (__force s3c_gpio_pull_t)pup; | ||
| 130 | } | ||
| 131 | EXPORT_SYMBOL(s3c_gpio_getpull); | ||
| 132 | |||
| 133 | #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX | ||
| 134 | int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, | ||
| 135 | unsigned int off, unsigned int cfg) | ||
| 136 | { | ||
| 137 | void __iomem *reg = chip->base; | ||
| 138 | unsigned int shift = off; | ||
| 139 | u32 con; | ||
| 140 | |||
| 141 | if (s3c_gpio_is_cfg_special(cfg)) { | ||
| 142 | cfg &= 0xf; | ||
| 143 | |||
| 144 | /* Map output to 0, and SFN2 to 1 */ | ||
| 145 | cfg -= 1; | ||
| 146 | if (cfg > 1) | ||
| 147 | return -EINVAL; | ||
| 148 | |||
| 149 | cfg <<= shift; | ||
| 150 | } | ||
| 151 | |||
| 152 | con = __raw_readl(reg); | ||
| 153 | con &= ~(0x1 << shift); | ||
| 154 | con |= cfg; | ||
| 155 | __raw_writel(con, reg); | ||
| 156 | |||
| 157 | return 0; | ||
| 158 | } | ||
| 159 | |||
| 160 | unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip, | ||
| 161 | unsigned int off) | ||
| 162 | { | ||
| 163 | u32 con; | ||
| 164 | |||
| 165 | con = __raw_readl(chip->base); | ||
| 166 | con >>= off; | ||
| 167 | con &= 1; | ||
| 168 | con++; | ||
| 169 | |||
| 170 | return S3C_GPIO_SFN(con); | ||
| 171 | } | ||
| 172 | |||
| 173 | int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, | ||
| 174 | unsigned int off, unsigned int cfg) | ||
| 175 | { | ||
| 176 | void __iomem *reg = chip->base; | ||
| 177 | unsigned int shift = off * 2; | ||
| 178 | u32 con; | ||
| 179 | |||
| 180 | if (s3c_gpio_is_cfg_special(cfg)) { | ||
| 181 | cfg &= 0xf; | ||
| 182 | if (cfg > 3) | ||
| 183 | return -EINVAL; | ||
| 184 | |||
| 185 | cfg <<= shift; | ||
| 186 | } | ||
| 187 | |||
| 188 | con = __raw_readl(reg); | ||
| 189 | con &= ~(0x3 << shift); | ||
| 190 | con |= cfg; | ||
| 191 | __raw_writel(con, reg); | ||
| 192 | |||
| 193 | return 0; | ||
| 194 | } | ||
| 195 | |||
| 196 | unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip, | ||
| 197 | unsigned int off) | ||
| 198 | { | ||
| 199 | u32 con; | ||
| 200 | |||
| 201 | con = __raw_readl(chip->base); | ||
| 202 | con >>= off * 2; | ||
| 203 | con &= 3; | ||
| 204 | |||
| 205 | /* this conversion works for IN and OUT as well as special mode */ | ||
| 206 | return S3C_GPIO_SPECIAL(con); | ||
| 207 | } | ||
| 208 | #endif | ||
| 209 | |||
| 210 | #ifdef CONFIG_S3C_GPIO_CFG_S3C64XX | ||
| 211 | int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, | ||
| 212 | unsigned int off, unsigned int cfg) | ||
| 213 | { | ||
| 214 | void __iomem *reg = chip->base; | ||
| 215 | unsigned int shift = (off & 7) * 4; | ||
| 216 | u32 con; | ||
| 217 | |||
| 218 | if (off < 8 && chip->chip.ngpio > 8) | ||
| 219 | reg -= 4; | ||
| 220 | |||
| 221 | if (s3c_gpio_is_cfg_special(cfg)) { | ||
| 222 | cfg &= 0xf; | ||
| 223 | cfg <<= shift; | ||
| 224 | } | ||
| 225 | |||
| 226 | con = __raw_readl(reg); | ||
| 227 | con &= ~(0xf << shift); | ||
| 228 | con |= cfg; | ||
| 229 | __raw_writel(con, reg); | ||
| 230 | |||
| 231 | return 0; | ||
| 232 | } | ||
| 233 | |||
| 234 | unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, | ||
| 235 | unsigned int off) | ||
| 236 | { | ||
| 237 | void __iomem *reg = chip->base; | ||
| 238 | unsigned int shift = (off & 7) * 4; | ||
| 239 | u32 con; | ||
| 240 | |||
| 241 | if (off < 8 && chip->chip.ngpio > 8) | ||
| 242 | reg -= 4; | ||
| 243 | |||
| 244 | con = __raw_readl(reg); | ||
| 245 | con >>= shift; | ||
| 246 | con &= 0xf; | ||
| 247 | |||
| 248 | /* this conversion works for IN and OUT as well as special mode */ | ||
| 249 | return S3C_GPIO_SPECIAL(con); | ||
| 250 | } | ||
| 251 | |||
| 252 | #endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */ | ||
| 253 | |||
| 254 | #ifdef CONFIG_S3C_GPIO_PULL_UPDOWN | ||
| 255 | int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip, | ||
| 256 | unsigned int off, s3c_gpio_pull_t pull) | ||
| 257 | { | ||
| 258 | void __iomem *reg = chip->base + 0x08; | ||
| 259 | int shift = off * 2; | ||
| 260 | u32 pup; | ||
| 261 | |||
| 262 | pup = __raw_readl(reg); | ||
| 263 | pup &= ~(3 << shift); | ||
| 264 | pup |= pull << shift; | ||
| 265 | __raw_writel(pup, reg); | ||
| 266 | |||
| 267 | return 0; | ||
| 268 | } | ||
| 269 | |||
| 270 | s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip, | ||
| 271 | unsigned int off) | ||
| 272 | { | ||
| 273 | void __iomem *reg = chip->base + 0x08; | ||
| 274 | int shift = off * 2; | ||
| 275 | u32 pup = __raw_readl(reg); | ||
| 276 | |||
| 277 | pup >>= shift; | ||
| 278 | pup &= 0x3; | ||
| 279 | return (__force s3c_gpio_pull_t)pup; | ||
| 280 | } | ||
| 281 | |||
| 282 | #ifdef CONFIG_S3C_GPIO_PULL_S3C2443 | ||
| 283 | int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip, | ||
| 284 | unsigned int off, s3c_gpio_pull_t pull) | ||
| 285 | { | ||
| 286 | switch (pull) { | ||
| 287 | case S3C_GPIO_PULL_NONE: | ||
| 288 | pull = 0x01; | ||
| 289 | break; | ||
| 290 | case S3C_GPIO_PULL_UP: | ||
| 291 | pull = 0x00; | ||
| 292 | break; | ||
| 293 | case S3C_GPIO_PULL_DOWN: | ||
| 294 | pull = 0x02; | ||
| 295 | break; | ||
| 296 | } | ||
| 297 | return s3c_gpio_setpull_updown(chip, off, pull); | ||
| 298 | } | ||
| 299 | |||
| 300 | s3c_gpio_pull_t s3c_gpio_getpull_s3c2443(struct s3c_gpio_chip *chip, | ||
| 301 | unsigned int off) | ||
| 302 | { | ||
| 303 | s3c_gpio_pull_t pull; | ||
| 304 | |||
| 305 | pull = s3c_gpio_getpull_updown(chip, off); | ||
| 306 | |||
| 307 | switch (pull) { | ||
| 308 | case 0x00: | ||
| 309 | pull = S3C_GPIO_PULL_UP; | ||
| 310 | break; | ||
| 311 | case 0x01: | ||
| 312 | case 0x03: | ||
| 313 | pull = S3C_GPIO_PULL_NONE; | ||
| 314 | break; | ||
| 315 | case 0x02: | ||
| 316 | pull = S3C_GPIO_PULL_DOWN; | ||
| 317 | break; | ||
| 318 | } | ||
| 319 | |||
| 320 | return pull; | ||
| 321 | } | ||
| 322 | #endif | ||
| 323 | #endif | ||
| 324 | |||
| 325 | #if defined(CONFIG_S3C_GPIO_PULL_UP) || defined(CONFIG_S3C_GPIO_PULL_DOWN) | ||
| 326 | static int s3c_gpio_setpull_1(struct s3c_gpio_chip *chip, | ||
| 327 | unsigned int off, s3c_gpio_pull_t pull, | ||
| 328 | s3c_gpio_pull_t updown) | ||
| 329 | { | ||
| 330 | void __iomem *reg = chip->base + 0x08; | ||
| 331 | u32 pup = __raw_readl(reg); | ||
| 332 | |||
| 333 | if (pull == updown) | ||
| 334 | pup &= ~(1 << off); | ||
| 335 | else if (pull == S3C_GPIO_PULL_NONE) | ||
| 336 | pup |= (1 << off); | ||
| 337 | else | ||
| 338 | return -EINVAL; | ||
| 339 | |||
| 340 | __raw_writel(pup, reg); | ||
| 341 | return 0; | ||
| 342 | } | ||
| 343 | |||
| 344 | static s3c_gpio_pull_t s3c_gpio_getpull_1(struct s3c_gpio_chip *chip, | ||
| 345 | unsigned int off, s3c_gpio_pull_t updown) | ||
| 346 | { | ||
| 347 | void __iomem *reg = chip->base + 0x08; | ||
| 348 | u32 pup = __raw_readl(reg); | ||
| 349 | |||
| 350 | pup &= (1 << off); | ||
| 351 | return pup ? S3C_GPIO_PULL_NONE : updown; | ||
| 352 | } | ||
| 353 | #endif /* CONFIG_S3C_GPIO_PULL_UP || CONFIG_S3C_GPIO_PULL_DOWN */ | ||
| 354 | |||
| 355 | #ifdef CONFIG_S3C_GPIO_PULL_UP | ||
| 356 | s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, | ||
| 357 | unsigned int off) | ||
| 358 | { | ||
| 359 | return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP); | ||
| 360 | } | ||
| 361 | |||
| 362 | int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, | ||
| 363 | unsigned int off, s3c_gpio_pull_t pull) | ||
| 364 | { | ||
| 365 | return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP); | ||
| 366 | } | ||
| 367 | #endif /* CONFIG_S3C_GPIO_PULL_UP */ | ||
| 368 | |||
| 369 | #ifdef CONFIG_S3C_GPIO_PULL_DOWN | ||
| 370 | s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip, | ||
| 371 | unsigned int off) | ||
| 372 | { | ||
| 373 | return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN); | ||
| 374 | } | ||
| 375 | |||
| 376 | int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip, | ||
| 377 | unsigned int off, s3c_gpio_pull_t pull) | ||
| 378 | { | ||
| 379 | return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN); | ||
| 380 | } | ||
| 381 | #endif /* CONFIG_S3C_GPIO_PULL_DOWN */ | ||
| 382 | |||
| 383 | #ifdef CONFIG_S5P_GPIO_DRVSTR | ||
| 384 | s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) | ||
| 385 | { | ||
| 386 | struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); | ||
| 387 | unsigned int off; | ||
| 388 | void __iomem *reg; | ||
| 389 | int shift; | ||
| 390 | u32 drvstr; | ||
| 391 | |||
| 392 | if (!chip) | ||
| 393 | return -EINVAL; | ||
| 394 | |||
| 395 | off = pin - chip->chip.base; | ||
| 396 | shift = off * 2; | ||
| 397 | reg = chip->base + 0x0C; | ||
| 398 | |||
| 399 | drvstr = __raw_readl(reg); | ||
| 400 | drvstr = drvstr >> shift; | ||
| 401 | drvstr &= 0x3; | ||
| 402 | |||
| 403 | return (__force s5p_gpio_drvstr_t)drvstr; | ||
| 404 | } | ||
| 405 | EXPORT_SYMBOL(s5p_gpio_get_drvstr); | ||
| 406 | |||
| 407 | int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr) | ||
| 408 | { | ||
| 409 | struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); | ||
| 410 | unsigned int off; | ||
| 411 | void __iomem *reg; | ||
| 412 | int shift; | ||
| 413 | u32 tmp; | ||
| 414 | |||
| 415 | if (!chip) | ||
| 416 | return -EINVAL; | ||
| 417 | |||
| 418 | off = pin - chip->chip.base; | ||
| 419 | shift = off * 2; | ||
| 420 | reg = chip->base + 0x0C; | ||
| 421 | |||
| 422 | tmp = __raw_readl(reg); | ||
| 423 | tmp &= ~(0x3 << shift); | ||
| 424 | tmp |= drvstr << shift; | ||
| 425 | |||
| 426 | __raw_writel(tmp, reg); | ||
| 427 | |||
| 428 | return 0; | ||
| 429 | } | ||
| 430 | EXPORT_SYMBOL(s5p_gpio_set_drvstr); | ||
| 431 | #endif /* CONFIG_S5P_GPIO_DRVSTR */ | ||
diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c new file mode 100644 index 00000000000..7743c4b8b2f --- /dev/null +++ b/arch/arm/plat-samsung/gpio.c | |||
| @@ -0,0 +1,167 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c/gpio.c | ||
| 2 | * | ||
| 3 | * Copyright 2008 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * http://armlinux.simtec.co.uk/ | ||
| 6 | * | ||
| 7 | * S3C series GPIO core | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/io.h> | ||
| 17 | #include <linux/gpio.h> | ||
| 18 | #include <linux/spinlock.h> | ||
| 19 | |||
| 20 | #include <plat/gpio-core.h> | ||
| 21 | |||
| 22 | #ifdef CONFIG_S3C_GPIO_TRACK | ||
| 23 | struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END]; | ||
| 24 | |||
| 25 | static __init void s3c_gpiolib_track(struct s3c_gpio_chip *chip) | ||
| 26 | { | ||
| 27 | unsigned int gpn; | ||
| 28 | int i; | ||
| 29 | |||
| 30 | gpn = chip->chip.base; | ||
| 31 | for (i = 0; i < chip->chip.ngpio; i++, gpn++) { | ||
| 32 | BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios)); | ||
| 33 | s3c_gpios[gpn] = chip; | ||
| 34 | } | ||
| 35 | } | ||
| 36 | #endif /* CONFIG_S3C_GPIO_TRACK */ | ||
| 37 | |||
| 38 | /* Default routines for controlling GPIO, based on the original S3C24XX | ||
| 39 | * GPIO functions which deal with the case where each gpio bank of the | ||
| 40 | * chip is as following: | ||
| 41 | * | ||
| 42 | * base + 0x00: Control register, 2 bits per gpio | ||
| 43 | * gpio n: 2 bits starting at (2*n) | ||
| 44 | * 00 = input, 01 = output, others mean special-function | ||
| 45 | * base + 0x04: Data register, 1 bit per gpio | ||
| 46 | * bit n: data bit n | ||
| 47 | */ | ||
| 48 | |||
| 49 | static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset) | ||
| 50 | { | ||
| 51 | struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); | ||
| 52 | void __iomem *base = ourchip->base; | ||
| 53 | unsigned long flags; | ||
| 54 | unsigned long con; | ||
| 55 | |||
| 56 | s3c_gpio_lock(ourchip, flags); | ||
| 57 | |||
| 58 | con = __raw_readl(base + 0x00); | ||
| 59 | con &= ~(3 << (offset * 2)); | ||
| 60 | |||
| 61 | __raw_writel(con, base + 0x00); | ||
| 62 | |||
| 63 | s3c_gpio_unlock(ourchip, flags); | ||
| 64 | return 0; | ||
| 65 | } | ||
| 66 | |||
| 67 | static int s3c_gpiolib_output(struct gpio_chip *chip, | ||
| 68 | unsigned offset, int value) | ||
| 69 | { | ||
| 70 | struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); | ||
| 71 | void __iomem *base = ourchip->base; | ||
| 72 | unsigned long flags; | ||
| 73 | unsigned long dat; | ||
| 74 | unsigned long con; | ||
| 75 | |||
| 76 | s3c_gpio_lock(ourchip, flags); | ||
| 77 | |||
| 78 | dat = __raw_readl(base + 0x04); | ||
| 79 | dat &= ~(1 << offset); | ||
| 80 | if (value) | ||
| 81 | dat |= 1 << offset; | ||
| 82 | __raw_writel(dat, base + 0x04); | ||
| 83 | |||
| 84 | con = __raw_readl(base + 0x00); | ||
| 85 | con &= ~(3 << (offset * 2)); | ||
| 86 | con |= 1 << (offset * 2); | ||
| 87 | |||
| 88 | __raw_writel(con, base + 0x00); | ||
| 89 | __raw_writel(dat, base + 0x04); | ||
| 90 | |||
| 91 | s3c_gpio_unlock(ourchip, flags); | ||
| 92 | return 0; | ||
| 93 | } | ||
| 94 | |||
| 95 | static void s3c_gpiolib_set(struct gpio_chip *chip, | ||
| 96 | unsigned offset, int value) | ||
| 97 | { | ||
| 98 | struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); | ||
| 99 | void __iomem *base = ourchip->base; | ||
| 100 | unsigned long flags; | ||
| 101 | unsigned long dat; | ||
| 102 | |||
| 103 | s3c_gpio_lock(ourchip, flags); | ||
| 104 | |||
| 105 | dat = __raw_readl(base + 0x04); | ||
| 106 | dat &= ~(1 << offset); | ||
| 107 | if (value) | ||
| 108 | dat |= 1 << offset; | ||
| 109 | __raw_writel(dat, base + 0x04); | ||
| 110 | |||
| 111 | s3c_gpio_unlock(ourchip, flags); | ||
| 112 | } | ||
| 113 | |||
| 114 | static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset) | ||
| 115 | { | ||
| 116 | struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); | ||
| 117 | unsigned long val; | ||
| 118 | |||
| 119 | val = __raw_readl(ourchip->base + 0x04); | ||
| 120 | val >>= offset; | ||
| 121 | val &= 1; | ||
| 122 | |||
| 123 | return val; | ||
| 124 | } | ||
| 125 | |||
| 126 | __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip) | ||
| 127 | { | ||
| 128 | struct gpio_chip *gc = &chip->chip; | ||
| 129 | int ret; | ||
| 130 | |||
| 131 | BUG_ON(!chip->base); | ||
| 132 | BUG_ON(!gc->label); | ||
| 133 | BUG_ON(!gc->ngpio); | ||
| 134 | |||
| 135 | spin_lock_init(&chip->lock); | ||
| 136 | |||
| 137 | if (!gc->direction_input) | ||
| 138 | gc->direction_input = s3c_gpiolib_input; | ||
| 139 | if (!gc->direction_output) | ||
| 140 | gc->direction_output = s3c_gpiolib_output; | ||
| 141 | if (!gc->set) | ||
| 142 | gc->set = s3c_gpiolib_set; | ||
| 143 | if (!gc->get) | ||
| 144 | gc->get = s3c_gpiolib_get; | ||
| 145 | |||
| 146 | #ifdef CONFIG_PM | ||
| 147 | if (chip->pm != NULL) { | ||
| 148 | if (!chip->pm->save || !chip->pm->resume) | ||
| 149 | printk(KERN_ERR "gpio: %s has missing PM functions\n", | ||
| 150 | gc->label); | ||
| 151 | } else | ||
| 152 | printk(KERN_ERR "gpio: %s has no PM function\n", gc->label); | ||
| 153 | #endif | ||
| 154 | |||
| 155 | /* gpiochip_add() prints own failure message on error. */ | ||
| 156 | ret = gpiochip_add(gc); | ||
| 157 | if (ret >= 0) | ||
| 158 | s3c_gpiolib_track(chip); | ||
| 159 | } | ||
| 160 | |||
| 161 | int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) | ||
| 162 | { | ||
| 163 | struct s3c_gpio_chip *s3c_chip = container_of(chip, | ||
| 164 | struct s3c_gpio_chip, chip); | ||
| 165 | |||
| 166 | return s3c_chip->irq_base + offset; | ||
| 167 | } | ||
diff --git a/arch/arm/plat-samsung/include/plat/ata.h b/arch/arm/plat-samsung/include/plat/ata.h new file mode 100644 index 00000000000..2a3855a8372 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/ata.h | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/include/plat/ata.h | ||
| 2 | * | ||
| 3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
| 4 | * http://www.samsung.com | ||
| 5 | * | ||
| 6 | * Samsung CF-ATA platform_device info | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef __ASM_PLAT_ATA_H | ||
| 14 | #define __ASM_PLAT_ATA_H __FILE__ | ||
| 15 | |||
| 16 | /** | ||
| 17 | * struct s3c_ide_platdata - S3C IDE driver platform data. | ||
| 18 | * @setup_gpio: Setup the external GPIO pins to the right state for data | ||
| 19 | * transfer in true-ide mode. | ||
| 20 | */ | ||
| 21 | struct s3c_ide_platdata { | ||
| 22 | void (*setup_gpio)(void); | ||
| 23 | }; | ||
| 24 | |||
| 25 | /* | ||
| 26 | * s3c_ide_set_platdata() - Setup the platform specifc data for IDE driver. | ||
| 27 | * @pdata: Platform data for IDE driver. | ||
| 28 | */ | ||
| 29 | extern void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata); | ||
| 30 | |||
| 31 | /* architecture-specific IDE configuration */ | ||
| 32 | extern void s3c64xx_ide_setup_gpio(void); | ||
| 33 | extern void s5pc100_ide_setup_gpio(void); | ||
| 34 | extern void s5pv210_ide_setup_gpio(void); | ||
| 35 | |||
| 36 | #endif /*__ASM_PLAT_ATA_H */ | ||
diff --git a/arch/arm/plat-samsung/include/plat/audio.h b/arch/arm/plat-samsung/include/plat/audio.h new file mode 100644 index 00000000000..aa9875f77c4 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/audio.h | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | /* arch/arm/plat-samsung/include/plat/audio.h | ||
| 2 | * | ||
| 3 | * Copyright (c) 2009 Samsung Electronics Co. Ltd | ||
| 4 | * Author: Jaswinder Singh <jassi.brar@samsung.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | /* The machine init code calls s3c*_ac97_setup_gpio with | ||
| 12 | * one of these defines in order to select appropriate bank | ||
| 13 | * of GPIO for AC97 pins | ||
| 14 | */ | ||
| 15 | #define S3C64XX_AC97_GPD 0 | ||
| 16 | #define S3C64XX_AC97_GPE 1 | ||
| 17 | extern void s3c64xx_ac97_setup_gpio(int); | ||
| 18 | |||
| 19 | /* | ||
| 20 | * The machine init code calls s5p*_spdif_setup_gpio with | ||
| 21 | * one of these defines in order to select appropriate bank | ||
| 22 | * of GPIO for S/PDIF pins | ||
| 23 | */ | ||
| 24 | #define S5PC100_SPDIF_GPD 0 | ||
| 25 | #define S5PC100_SPDIF_GPG3 1 | ||
| 26 | extern void s5pc100_spdif_setup_gpio(int); | ||
| 27 | |||
| 28 | struct samsung_i2s { | ||
| 29 | /* If the Primary DAI has 5.1 Channels */ | ||
| 30 | #define QUIRK_PRI_6CHAN (1 << 0) | ||
| 31 | /* If the I2S block has a Stereo Overlay Channel */ | ||
| 32 | #define QUIRK_SEC_DAI (1 << 1) | ||
| 33 | /* | ||
| 34 | * If the I2S block has no internal prescalar or MUX (I2SMOD[10] bit) | ||
| 35 | * The Machine driver must provide suitably set clock to the I2S block. | ||
| 36 | */ | ||
| 37 | #define QUIRK_NO_MUXPSR (1 << 2) | ||
| 38 | #define QUIRK_NEED_RSTCLR (1 << 3) | ||
| 39 | /* Quirks of the I2S controller */ | ||
| 40 | u32 quirks; | ||
| 41 | |||
| 42 | /* | ||
| 43 | * Array of clock names that can be used to generate I2S signals. | ||
| 44 | * Also corresponds to clocks of I2SMOD[10] | ||
| 45 | */ | ||
| 46 | const char **src_clk; | ||
| 47 | dma_addr_t idma_addr; | ||
| 48 | }; | ||
| 49 | |||
| 50 | /** | ||
| 51 | * struct s3c_audio_pdata - common platform data for audio device drivers | ||
| 52 | * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode | ||
| 53 | */ | ||
| 54 | struct s3c_audio_pdata { | ||
| 55 | int (*cfg_gpio)(struct platform_device *); | ||
| 56 | union { | ||
| 57 | struct samsung_i2s i2s; | ||
| 58 | } type; | ||
| 59 | }; | ||
diff --git a/arch/arm/plat-samsung/include/plat/hwmon.h b/arch/arm/plat-samsung/include/plat/hwmon.h new file mode 100644 index 00000000000..c167e4429bc --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/hwmon.h | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c/include/plat/hwmon.h | ||
| 2 | * | ||
| 3 | * Copyright 2005 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * http://armlinux.simtec.co.uk/ | ||
| 6 | * | ||
| 7 | * S3C - HWMon interface for ADC | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #ifndef __ASM_ARCH_ADC_HWMON_H | ||
| 15 | #define __ASM_ARCH_ADC_HWMON_H __FILE__ | ||
| 16 | |||
| 17 | /** | ||
| 18 | * s3c_hwmon_chcfg - channel configuration | ||
| 19 | * @name: The name to give this channel. | ||
| 20 | * @mult: Multiply the ADC value read by this. | ||
| 21 | * @div: Divide the value from the ADC by this. | ||
| 22 | * | ||
| 23 | * The value read from the ADC is converted to a value that | ||
| 24 | * hwmon expects (mV) by result = (value_read * @mult) / @div. | ||
| 25 | */ | ||
| 26 | struct s3c_hwmon_chcfg { | ||
| 27 | const char *name; | ||
| 28 | unsigned int mult; | ||
| 29 | unsigned int div; | ||
| 30 | }; | ||
| 31 | |||
| 32 | /** | ||
| 33 | * s3c_hwmon_pdata - HWMON platform data | ||
| 34 | * @in: One configuration for each possible channel used. | ||
| 35 | */ | ||
| 36 | struct s3c_hwmon_pdata { | ||
| 37 | struct s3c_hwmon_chcfg *in[8]; | ||
| 38 | }; | ||
| 39 | |||
| 40 | /** | ||
| 41 | * s3c_hwmon_set_platdata - Set platform data for S3C HWMON device | ||
| 42 | * @pd: Platform data to register to device. | ||
| 43 | * | ||
| 44 | * Register the given platform data for use with the S3C HWMON device. | ||
| 45 | * The call will copy the platform data, so the board definitions can | ||
| 46 | * make the structure itself __initdata. | ||
| 47 | */ | ||
| 48 | extern void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd); | ||
| 49 | |||
| 50 | #endif /* __ASM_ARCH_ADC_HWMON_H */ | ||
| 51 | |||
diff --git a/arch/arm/plat-samsung/include/plat/iic.h b/arch/arm/plat-samsung/include/plat/iic.h new file mode 100644 index 00000000000..56b0059439e --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/iic.h | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* arch/arm/plat-s3c/include/plat/iic.h | ||
| 2 | * | ||
| 3 | * Copyright 2004-2009 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * | ||
| 6 | * S3C - I2C Controller platform_device info | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef __ASM_ARCH_IIC_H | ||
| 14 | #define __ASM_ARCH_IIC_H __FILE__ | ||
| 15 | |||
| 16 | #define S3C_IICFLG_FILTER (1<<0) /* enable s3c2440 filter */ | ||
| 17 | |||
| 18 | /** | ||
| 19 | * struct s3c2410_platform_i2c - Platform data for s3c I2C. | ||
| 20 | * @bus_num: The bus number to use (if possible). | ||
| 21 | * @flags: Any flags for the I2C bus (E.g. S3C_IICFLK_FILTER). | ||
| 22 | * @slave_addr: The I2C address for the slave device (if enabled). | ||
| 23 | * @frequency: The desired frequency in Hz of the bus. This is | ||
| 24 | * guaranteed to not be exceeded. If the caller does | ||
| 25 | * not care, use zero and the driver will select a | ||
| 26 | * useful default. | ||
| 27 | * @sda_delay: The delay (in ns) applied to SDA edges. | ||
| 28 | * @cfg_gpio: A callback to configure the pins for I2C operation. | ||
| 29 | */ | ||
| 30 | struct s3c2410_platform_i2c { | ||
| 31 | int bus_num; | ||
| 32 | unsigned int flags; | ||
| 33 | unsigned int slave_addr; | ||
| 34 | unsigned long frequency; | ||
| 35 | unsigned int sda_delay; | ||
| 36 | |||
| 37 | void (*cfg_gpio)(struct platform_device *dev); | ||
| 38 | }; | ||
| 39 | |||
| 40 | /** | ||
| 41 | * s3c_i2c0_set_platdata - set platform data for i2c0 device | ||
| 42 | * @i2c: The platform data to set, or NULL for default data. | ||
| 43 | * | ||
| 44 | * Register the given platform data for use with the i2c0 device. This | ||
| 45 | * call copies the platform data, so the caller can use __initdata for | ||
| 46 | * their copy. | ||
| 47 | * | ||
| 48 | * This call will set cfg_gpio if is null to the default platform | ||
| 49 | * implementation. | ||
| 50 | * | ||
| 51 | * Any user of s3c_device_i2c0 should call this, even if it is with | ||
| 52 | * NULL to ensure that the device is given the default platform data | ||
| 53 | * as the driver will no longer carry defaults. | ||
| 54 | */ | ||
| 55 | extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c); | ||
| 56 | extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c); | ||
| 57 | extern void s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *i2c); | ||
| 58 | extern void s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *i2c); | ||
| 59 | extern void s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *i2c); | ||
| 60 | extern void s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *i2c); | ||
| 61 | extern void s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *i2c); | ||
| 62 | extern void s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *i2c); | ||
| 63 | |||
| 64 | /* defined by architecture to configure gpio */ | ||
| 65 | extern void s3c_i2c0_cfg_gpio(struct platform_device *dev); | ||
| 66 | extern void s3c_i2c1_cfg_gpio(struct platform_device *dev); | ||
| 67 | extern void s3c_i2c2_cfg_gpio(struct platform_device *dev); | ||
| 68 | extern void s3c_i2c3_cfg_gpio(struct platform_device *dev); | ||
| 69 | extern void s3c_i2c4_cfg_gpio(struct platform_device *dev); | ||
| 70 | extern void s3c_i2c5_cfg_gpio(struct platform_device *dev); | ||
| 71 | extern void s3c_i2c6_cfg_gpio(struct platform_device *dev); | ||
| 72 | extern void s3c_i2c7_cfg_gpio(struct platform_device *dev); | ||
| 73 | |||
| 74 | extern struct s3c2410_platform_i2c default_i2c_data; | ||
| 75 | |||
| 76 | #endif /* __ASM_ARCH_IIC_H */ | ||
diff --git a/arch/arm/plat-samsung/include/plat/nand.h b/arch/arm/plat-samsung/include/plat/nand.h new file mode 100644 index 00000000000..b64115fa93a --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/nand.h | |||
| @@ -0,0 +1,67 @@ | |||
| 1 | /* arch/arm/mach-s3c2410/include/mach/nand.h | ||
| 2 | * | ||
| 3 | * Copyright (c) 2004 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * | ||
| 6 | * S3C2410 - NAND device controller platform_device info | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | /** | ||
| 14 | * struct s3c2410_nand_set - define a set of one or more nand chips | ||
| 15 | * @disable_ecc: Entirely disable ECC - Dangerous | ||
| 16 | * @flash_bbt: Openmoko u-boot can create a Bad Block Table | ||
| 17 | * Setting this flag will allow the kernel to | ||
| 18 | * look for it at boot time and also skip the NAND | ||
| 19 | * scan. | ||
| 20 | * @options: Default value to set into 'struct nand_chip' options. | ||
| 21 | * @nr_chips: Number of chips in this set | ||
| 22 | * @nr_partitions: Number of partitions pointed to by @partitions | ||
| 23 | * @name: Name of set (optional) | ||
| 24 | * @nr_map: Map for low-layer logical to physical chip numbers (option) | ||
| 25 | * @partitions: The mtd partition list | ||
| 26 | * | ||
| 27 | * define a set of one or more nand chips registered with an unique mtd. Also | ||
| 28 | * allows to pass flag to the underlying NAND layer. 'disable_ecc' will trigger | ||
| 29 | * a warning at boot time. | ||
| 30 | */ | ||
| 31 | struct s3c2410_nand_set { | ||
| 32 | unsigned int disable_ecc:1; | ||
| 33 | unsigned int flash_bbt:1; | ||
| 34 | |||
| 35 | unsigned int options; | ||
| 36 | int nr_chips; | ||
| 37 | int nr_partitions; | ||
| 38 | char *name; | ||
| 39 | int *nr_map; | ||
| 40 | struct mtd_partition *partitions; | ||
| 41 | struct nand_ecclayout *ecc_layout; | ||
| 42 | }; | ||
| 43 | |||
| 44 | struct s3c2410_platform_nand { | ||
| 45 | /* timing information for controller, all times in nanoseconds */ | ||
| 46 | |||
| 47 | int tacls; /* time for active CLE/ALE to nWE/nOE */ | ||
| 48 | int twrph0; /* active time for nWE/nOE */ | ||
| 49 | int twrph1; /* time for release CLE/ALE from nWE/nOE inactive */ | ||
| 50 | |||
| 51 | unsigned int ignore_unset_ecc:1; | ||
| 52 | |||
| 53 | int nr_sets; | ||
| 54 | struct s3c2410_nand_set *sets; | ||
| 55 | |||
| 56 | void (*select_chip)(struct s3c2410_nand_set *, | ||
| 57 | int chip); | ||
| 58 | }; | ||
| 59 | |||
| 60 | /** | ||
| 61 | * s3c_nand_set_platdata() - register NAND platform data. | ||
| 62 | * @nand: The NAND platform data to register with s3c_device_nand. | ||
| 63 | * | ||
| 64 | * This function copies the given NAND platform data, @nand and registers | ||
| 65 | * it with the s3c_device_nand. This allows @nand to be __initdata. | ||
| 66 | */ | ||
| 67 | extern void s3c_nand_set_platdata(struct s3c2410_platform_nand *nand); | ||
diff --git a/arch/arm/plat-samsung/include/plat/pd.h b/arch/arm/plat-samsung/include/plat/pd.h new file mode 100644 index 00000000000..abb4bc32716 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/pd.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/include/plat/pd.h | ||
| 2 | * | ||
| 3 | * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. | ||
| 4 | * http://www.samsung.com | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef __ASM_PLAT_SAMSUNG_PD_H | ||
| 12 | #define __ASM_PLAT_SAMSUNG_PD_H __FILE__ | ||
| 13 | |||
| 14 | struct samsung_pd_info { | ||
| 15 | int (*enable)(struct device *dev); | ||
| 16 | int (*disable)(struct device *dev); | ||
| 17 | void __iomem *base; | ||
| 18 | }; | ||
| 19 | |||
| 20 | enum exynos4_pd_block { | ||
| 21 | PD_MFC, | ||
| 22 | PD_G3D, | ||
| 23 | PD_LCD0, | ||
| 24 | PD_LCD1, | ||
| 25 | PD_TV, | ||
| 26 | PD_CAM, | ||
| 27 | PD_GPS | ||
| 28 | }; | ||
| 29 | |||
| 30 | #endif /* __ASM_PLAT_SAMSUNG_PD_H */ | ||
diff --git a/arch/arm/plat-samsung/include/plat/pll6553x.h b/arch/arm/plat-samsung/include/plat/pll6553x.h new file mode 100644 index 00000000000..b8b7e1d884f --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/pll6553x.h | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | /* arch/arm/plat-samsung/include/plat/pll6553x.h | ||
| 2 | * partially from arch/arm/mach-s3c64xx/include/mach/pll.h | ||
| 3 | * | ||
| 4 | * Copyright 2008 Openmoko, Inc. | ||
| 5 | * Copyright 2008 Simtec Electronics | ||
| 6 | * Ben Dooks <ben@simtec.co.uk> | ||
| 7 | * http://armlinux.simtec.co.uk/ | ||
| 8 | * | ||
| 9 | * Samsung PLL6553x PLL code | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 as | ||
| 13 | * published by the Free Software Foundation. | ||
| 14 | */ | ||
| 15 | |||
| 16 | /* S3C6400 and compatible (S3C2416, etc.) EPLL code */ | ||
| 17 | |||
| 18 | #define PLL6553X_MDIV_MASK ((1 << (23-16)) - 1) | ||
| 19 | #define PLL6553X_PDIV_MASK ((1 << (13-8)) - 1) | ||
| 20 | #define PLL6553X_SDIV_MASK ((1 << (2-0)) - 1) | ||
| 21 | #define PLL6553X_MDIV_SHIFT (16) | ||
| 22 | #define PLL6553X_PDIV_SHIFT (8) | ||
| 23 | #define PLL6553X_SDIV_SHIFT (0) | ||
| 24 | #define PLL6553X_KDIV_MASK (0xffff) | ||
| 25 | |||
| 26 | static inline unsigned long s3c_get_pll6553x(unsigned long baseclk, | ||
| 27 | u32 pll0, u32 pll1) | ||
| 28 | { | ||
| 29 | unsigned long result; | ||
| 30 | u32 mdiv, pdiv, sdiv, kdiv; | ||
| 31 | u64 tmp; | ||
| 32 | |||
| 33 | mdiv = (pll0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK; | ||
| 34 | pdiv = (pll0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK; | ||
| 35 | sdiv = (pll0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK; | ||
| 36 | kdiv = pll1 & PLL6553X_KDIV_MASK; | ||
| 37 | |||
| 38 | /* We need to multiple baseclk by mdiv (the integer part) and kdiv | ||
| 39 | * which is in 2^16ths, so shift mdiv up (does not overflow) and | ||
| 40 | * add kdiv before multiplying. The use of tmp is to avoid any | ||
| 41 | * overflows before shifting bac down into result when multipling | ||
| 42 | * by the mdiv and kdiv pair. | ||
| 43 | */ | ||
| 44 | |||
| 45 | tmp = baseclk; | ||
| 46 | tmp *= (mdiv << 16) + kdiv; | ||
| 47 | do_div(tmp, (pdiv << sdiv)); | ||
| 48 | result = tmp >> 16; | ||
| 49 | |||
| 50 | return result; | ||
| 51 | } | ||
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h new file mode 100644 index 00000000000..4c3647f8005 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h | |||
| @@ -0,0 +1,159 @@ | |||
| 1 | /* arch/arm/plat-samsung/include/plat/regs-fb-v4.h | ||
| 2 | * | ||
| 3 | * Copyright 2008 Openmoko, Inc. | ||
| 4 | * Copyright 2008 Simtec Electronics | ||
| 5 | * http://armlinux.simtec.co.uk/ | ||
| 6 | * Ben Dooks <ben@simtec.co.uk> | ||
| 7 | * | ||
| 8 | * S3C64XX - new-style framebuffer register definitions | ||
| 9 | * | ||
| 10 | * This is the register set for the new style framebuffer interface | ||
| 11 | * found from the S3C2443 onwards and specifically the S3C64XX series | ||
| 12 | * S3C6400 and S3C6410. | ||
| 13 | * | ||
| 14 | * The file contains the cpu specific items which change between whichever | ||
| 15 | * architecture is selected. See <plat/regs-fb.h> for the core definitions | ||
| 16 | * that are the same. | ||
| 17 | * | ||
| 18 | * This program is free software; you can redistribute it and/or modify | ||
| 19 | * it under the terms of the GNU General Public License version 2 as | ||
| 20 | * published by the Free Software Foundation. | ||
| 21 | */ | ||
| 22 | |||
| 23 | /* include the core definitions here, in case we really do need to | ||
| 24 | * override them at a later date. | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include <plat/regs-fb.h> | ||
| 28 | |||
| 29 | #define S3C_FB_MAX_WIN (5) /* number of hardware windows available. */ | ||
| 30 | #define VIDCON1_FSTATUS_EVEN (1 << 15) | ||
| 31 | |||
| 32 | /* Video timing controls */ | ||
| 33 | #define VIDTCON0 (0x10) | ||
| 34 | #define VIDTCON1 (0x14) | ||
| 35 | #define VIDTCON2 (0x18) | ||
| 36 | |||
| 37 | /* Window position controls */ | ||
| 38 | |||
| 39 | #define WINCON(_win) (0x20 + ((_win) * 4)) | ||
| 40 | |||
| 41 | /* OSD1 and OSD4 do not have register D */ | ||
| 42 | |||
| 43 | #define VIDOSD_BASE (0x40) | ||
| 44 | |||
| 45 | #define VIDINTCON0 (0x130) | ||
| 46 | |||
| 47 | /* WINCONx */ | ||
| 48 | |||
| 49 | #define WINCONx_CSCWIDTH_MASK (0x3 << 26) | ||
| 50 | #define WINCONx_CSCWIDTH_SHIFT (26) | ||
| 51 | #define WINCONx_CSCWIDTH_WIDE (0x0 << 26) | ||
| 52 | #define WINCONx_CSCWIDTH_NARROW (0x3 << 26) | ||
| 53 | |||
| 54 | #define WINCONx_ENLOCAL (1 << 22) | ||
| 55 | #define WINCONx_BUFSTATUS (1 << 21) | ||
| 56 | #define WINCONx_BUFSEL (1 << 20) | ||
| 57 | #define WINCONx_BUFAUTOEN (1 << 19) | ||
| 58 | #define WINCONx_YCbCr (1 << 13) | ||
| 59 | |||
| 60 | #define WINCON1_LOCALSEL_CAMIF (1 << 23) | ||
| 61 | |||
| 62 | #define WINCON2_LOCALSEL_CAMIF (1 << 23) | ||
| 63 | #define WINCON2_BLD_PIX (1 << 6) | ||
| 64 | |||
| 65 | #define WINCON2_ALPHA_SEL (1 << 1) | ||
| 66 | #define WINCON2_BPPMODE_MASK (0xf << 2) | ||
| 67 | #define WINCON2_BPPMODE_SHIFT (2) | ||
| 68 | #define WINCON2_BPPMODE_1BPP (0x0 << 2) | ||
| 69 | #define WINCON2_BPPMODE_2BPP (0x1 << 2) | ||
| 70 | #define WINCON2_BPPMODE_4BPP (0x2 << 2) | ||
| 71 | #define WINCON2_BPPMODE_8BPP_1232 (0x4 << 2) | ||
| 72 | #define WINCON2_BPPMODE_16BPP_565 (0x5 << 2) | ||
| 73 | #define WINCON2_BPPMODE_16BPP_A1555 (0x6 << 2) | ||
| 74 | #define WINCON2_BPPMODE_16BPP_I1555 (0x7 << 2) | ||
| 75 | #define WINCON2_BPPMODE_18BPP_666 (0x8 << 2) | ||
| 76 | #define WINCON2_BPPMODE_18BPP_A1665 (0x9 << 2) | ||
| 77 | #define WINCON2_BPPMODE_19BPP_A1666 (0xa << 2) | ||
| 78 | #define WINCON2_BPPMODE_24BPP_888 (0xb << 2) | ||
| 79 | #define WINCON2_BPPMODE_24BPP_A1887 (0xc << 2) | ||
| 80 | #define WINCON2_BPPMODE_25BPP_A1888 (0xd << 2) | ||
| 81 | #define WINCON2_BPPMODE_28BPP_A4888 (0xd << 2) | ||
| 82 | |||
| 83 | #define WINCON3_BLD_PIX (1 << 6) | ||
| 84 | |||
| 85 | #define WINCON3_ALPHA_SEL (1 << 1) | ||
| 86 | #define WINCON3_BPPMODE_MASK (0xf << 2) | ||
| 87 | #define WINCON3_BPPMODE_SHIFT (2) | ||
| 88 | #define WINCON3_BPPMODE_1BPP (0x0 << 2) | ||
| 89 | #define WINCON3_BPPMODE_2BPP (0x1 << 2) | ||
| 90 | #define WINCON3_BPPMODE_4BPP (0x2 << 2) | ||
| 91 | #define WINCON3_BPPMODE_16BPP_565 (0x5 << 2) | ||
| 92 | #define WINCON3_BPPMODE_16BPP_A1555 (0x6 << 2) | ||
| 93 | #define WINCON3_BPPMODE_16BPP_I1555 (0x7 << 2) | ||
| 94 | #define WINCON3_BPPMODE_18BPP_666 (0x8 << 2) | ||
| 95 | #define WINCON3_BPPMODE_18BPP_A1665 (0x9 << 2) | ||
| 96 | #define WINCON3_BPPMODE_19BPP_A1666 (0xa << 2) | ||
| 97 | #define WINCON3_BPPMODE_24BPP_888 (0xb << 2) | ||
| 98 | #define WINCON3_BPPMODE_24BPP_A1887 (0xc << 2) | ||
| 99 | #define WINCON3_BPPMODE_25BPP_A1888 (0xd << 2) | ||
| 100 | #define WINCON3_BPPMODE_28BPP_A4888 (0xd << 2) | ||
| 101 | |||
| 102 | #define VIDINTCON0_FIFIOSEL_WINDOW2 (0x10 << 5) | ||
| 103 | #define VIDINTCON0_FIFIOSEL_WINDOW3 (0x20 << 5) | ||
| 104 | #define VIDINTCON0_FIFIOSEL_WINDOW4 (0x40 << 5) | ||
| 105 | |||
| 106 | #define DITHMODE (0x170) | ||
| 107 | #define WINxMAP(_win) (0x180 + ((_win) * 4)) | ||
| 108 | |||
| 109 | |||
| 110 | #define DITHMODE_R_POS_MASK (0x3 << 5) | ||
| 111 | #define DITHMODE_R_POS_SHIFT (5) | ||
| 112 | #define DITHMODE_R_POS_8BIT (0x0 << 5) | ||
| 113 | #define DITHMODE_R_POS_6BIT (0x1 << 5) | ||
| 114 | #define DITHMODE_R_POS_5BIT (0x2 << 5) | ||
| 115 | |||
| 116 | #define DITHMODE_G_POS_MASK (0x3 << 3) | ||
| 117 | #define DITHMODE_G_POS_SHIFT (3) | ||
| 118 | #define DITHMODE_G_POS_8BIT (0x0 << 3) | ||
| 119 | #define DITHMODE_G_POS_6BIT (0x1 << 3) | ||
| 120 | #define DITHMODE_G_POS_5BIT (0x2 << 3) | ||
| 121 | |||
| 122 | #define DITHMODE_B_POS_MASK (0x3 << 1) | ||
| 123 | #define DITHMODE_B_POS_SHIFT (1) | ||
| 124 | #define DITHMODE_B_POS_8BIT (0x0 << 1) | ||
| 125 | #define DITHMODE_B_POS_6BIT (0x1 << 1) | ||
| 126 | #define DITHMODE_B_POS_5BIT (0x2 << 1) | ||
| 127 | |||
| 128 | #define DITHMODE_DITH_EN (1 << 0) | ||
| 129 | |||
| 130 | #define WPALCON (0x1A0) | ||
| 131 | |||
| 132 | /* Palette control */ | ||
| 133 | /* Note for S5PC100: you can still use those macros on WPALCON (aka WPALCON_L), | ||
| 134 | * but make sure that WPALCON_H W2PAL-W4PAL entries are zeroed out */ | ||
| 135 | #define WPALCON_W4PAL_16BPP_A555 (1 << 8) | ||
| 136 | #define WPALCON_W3PAL_16BPP_A555 (1 << 7) | ||
| 137 | #define WPALCON_W2PAL_16BPP_A555 (1 << 6) | ||
| 138 | |||
| 139 | |||
| 140 | /* Notes on per-window bpp settings | ||
| 141 | * | ||
| 142 | * Value Win0 Win1 Win2 Win3 Win 4 | ||
| 143 | * 0000 1(P) 1(P) 1(P) 1(P) 1(P) | ||
| 144 | * 0001 2(P) 2(P) 2(P) 2(P) 2(P) | ||
| 145 | * 0010 4(P) 4(P) 4(P) 4(P) -none- | ||
| 146 | * 0011 8(P) 8(P) -none- -none- -none- | ||
| 147 | * 0100 -none- 8(A232) 8(A232) -none- -none- | ||
| 148 | * 0101 16(565) 16(565) 16(565) 16(565) 16(565) | ||
| 149 | * 0110 -none- 16(A555) 16(A555) 16(A555) 16(A555) | ||
| 150 | * 0111 16(I555) 16(I565) 16(I555) 16(I555) 16(I555) | ||
| 151 | * 1000 18(666) 18(666) 18(666) 18(666) 18(666) | ||
| 152 | * 1001 -none- 18(A665) 18(A665) 18(A665) 16(A665) | ||
| 153 | * 1010 -none- 19(A666) 19(A666) 19(A666) 19(A666) | ||
| 154 | * 1011 24(888) 24(888) 24(888) 24(888) 24(888) | ||
| 155 | * 1100 -none- 24(A887) 24(A887) 24(A887) 24(A887) | ||
| 156 | * 1101 -none- 25(A888) 25(A888) 25(A888) 25(A888) | ||
| 157 | * 1110 -none- -none- -none- -none- -none- | ||
| 158 | * 1111 -none- -none- -none- -none- -none- | ||
| 159 | */ | ||
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb.h b/arch/arm/plat-samsung/include/plat/regs-fb.h new file mode 100644 index 00000000000..8f39aa5b26e --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/regs-fb.h | |||
| @@ -0,0 +1,386 @@ | |||
| 1 | /* arch/arm/plat-samsung/include/plat/regs-fb.h | ||
| 2 | * | ||
| 3 | * Copyright 2008 Openmoko, Inc. | ||
| 4 | * Copyright 2008 Simtec Electronics | ||
| 5 | * http://armlinux.simtec.co.uk/ | ||
| 6 | * Ben Dooks <ben@simtec.co.uk> | ||
| 7 | * | ||
| 8 | * S3C Platform - new-style framebuffer register definitions | ||
| 9 | * | ||
| 10 | * This is the register set for the new style framebuffer interface | ||
| 11 | * found from the S3C2443 onwards into the S3C2416, S3C2450 and the | ||
| 12 | * S3C64XX series such as the S3C6400 and S3C6410. | ||
| 13 | * | ||
| 14 | * The file does not contain the cpu specific items which are based on | ||
| 15 | * whichever architecture is selected, it only contains the core of the | ||
| 16 | * register set. See <mach/regs-fb.h> to get the specifics. | ||
| 17 | * | ||
| 18 | * Note, we changed to using regs-fb.h as it avoids any clashes with | ||
| 19 | * the original regs-lcd.h so out of the way of regs-lcd.h as well as | ||
| 20 | * indicating the newer block is much more than just an LCD interface. | ||
| 21 | * | ||
| 22 | * This program is free software; you can redistribute it and/or modify | ||
| 23 | * it under the terms of the GNU General Public License version 2 as | ||
| 24 | * published by the Free Software Foundation. | ||
| 25 | */ | ||
| 26 | |||
| 27 | /* Please do not include this file directly, use <mach/regs-fb.h> to | ||
| 28 | * ensure all the localised SoC support is included as necessary. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /* VIDCON0 */ | ||
| 32 | |||
| 33 | #define VIDCON0 (0x00) | ||
| 34 | #define VIDCON0_INTERLACE (1 << 29) | ||
| 35 | #define VIDCON0_VIDOUT_MASK (0x3 << 26) | ||
| 36 | #define VIDCON0_VIDOUT_SHIFT (26) | ||
| 37 | #define VIDCON0_VIDOUT_RGB (0x0 << 26) | ||
| 38 | #define VIDCON0_VIDOUT_TV (0x1 << 26) | ||
| 39 | #define VIDCON0_VIDOUT_I80_LDI0 (0x2 << 26) | ||
| 40 | #define VIDCON0_VIDOUT_I80_LDI1 (0x3 << 26) | ||
| 41 | |||
| 42 | #define VIDCON0_L1_DATA_MASK (0x7 << 23) | ||
| 43 | #define VIDCON0_L1_DATA_SHIFT (23) | ||
| 44 | #define VIDCON0_L1_DATA_16BPP (0x0 << 23) | ||
| 45 | #define VIDCON0_L1_DATA_18BPP16 (0x1 << 23) | ||
| 46 | #define VIDCON0_L1_DATA_18BPP9 (0x2 << 23) | ||
| 47 | #define VIDCON0_L1_DATA_24BPP (0x3 << 23) | ||
| 48 | #define VIDCON0_L1_DATA_18BPP (0x4 << 23) | ||
| 49 | #define VIDCON0_L1_DATA_16BPP8 (0x5 << 23) | ||
| 50 | |||
| 51 | #define VIDCON0_L0_DATA_MASK (0x7 << 20) | ||
| 52 | #define VIDCON0_L0_DATA_SHIFT (20) | ||
| 53 | #define VIDCON0_L0_DATA_16BPP (0x0 << 20) | ||
| 54 | #define VIDCON0_L0_DATA_18BPP16 (0x1 << 20) | ||
| 55 | #define VIDCON0_L0_DATA_18BPP9 (0x2 << 20) | ||
| 56 | #define VIDCON0_L0_DATA_24BPP (0x3 << 20) | ||
| 57 | #define VIDCON0_L0_DATA_18BPP (0x4 << 20) | ||
| 58 | #define VIDCON0_L0_DATA_16BPP8 (0x5 << 20) | ||
| 59 | |||
| 60 | #define VIDCON0_PNRMODE_MASK (0x3 << 17) | ||
| 61 | #define VIDCON0_PNRMODE_SHIFT (17) | ||
| 62 | #define VIDCON0_PNRMODE_RGB (0x0 << 17) | ||
| 63 | #define VIDCON0_PNRMODE_BGR (0x1 << 17) | ||
| 64 | #define VIDCON0_PNRMODE_SERIAL_RGB (0x2 << 17) | ||
| 65 | #define VIDCON0_PNRMODE_SERIAL_BGR (0x3 << 17) | ||
| 66 | |||
| 67 | #define VIDCON0_CLKVALUP (1 << 16) | ||
| 68 | #define VIDCON0_CLKVAL_F_MASK (0xff << 6) | ||
| 69 | #define VIDCON0_CLKVAL_F_SHIFT (6) | ||
| 70 | #define VIDCON0_CLKVAL_F_LIMIT (0xff) | ||
| 71 | #define VIDCON0_CLKVAL_F(_x) ((_x) << 6) | ||
| 72 | #define VIDCON0_VLCKFREE (1 << 5) | ||
| 73 | #define VIDCON0_CLKDIR (1 << 4) | ||
| 74 | |||
| 75 | #define VIDCON0_CLKSEL_MASK (0x3 << 2) | ||
| 76 | #define VIDCON0_CLKSEL_SHIFT (2) | ||
| 77 | #define VIDCON0_CLKSEL_HCLK (0x0 << 2) | ||
| 78 | #define VIDCON0_CLKSEL_LCD (0x1 << 2) | ||
| 79 | #define VIDCON0_CLKSEL_27M (0x3 << 2) | ||
| 80 | |||
| 81 | #define VIDCON0_ENVID (1 << 1) | ||
| 82 | #define VIDCON0_ENVID_F (1 << 0) | ||
| 83 | |||
| 84 | #define VIDCON1 (0x04) | ||
| 85 | #define VIDCON1_LINECNT_MASK (0x7ff << 16) | ||
| 86 | #define VIDCON1_LINECNT_SHIFT (16) | ||
| 87 | #define VIDCON1_LINECNT_GET(_v) (((_v) >> 16) & 0x7ff) | ||
| 88 | #define VIDCON1_VSTATUS_MASK (0x3 << 13) | ||
| 89 | #define VIDCON1_VSTATUS_SHIFT (13) | ||
| 90 | #define VIDCON1_VSTATUS_VSYNC (0x0 << 13) | ||
| 91 | #define VIDCON1_VSTATUS_BACKPORCH (0x1 << 13) | ||
| 92 | #define VIDCON1_VSTATUS_ACTIVE (0x2 << 13) | ||
| 93 | #define VIDCON1_VSTATUS_FRONTPORCH (0x0 << 13) | ||
| 94 | |||
| 95 | #define VIDCON1_INV_VCLK (1 << 7) | ||
| 96 | #define VIDCON1_INV_HSYNC (1 << 6) | ||
| 97 | #define VIDCON1_INV_VSYNC (1 << 5) | ||
| 98 | #define VIDCON1_INV_VDEN (1 << 4) | ||
| 99 | |||
| 100 | /* VIDCON2 */ | ||
| 101 | |||
| 102 | #define VIDCON2 (0x08) | ||
| 103 | #define VIDCON2_EN601 (1 << 23) | ||
| 104 | #define VIDCON2_TVFMTSEL_SW (1 << 14) | ||
| 105 | |||
| 106 | #define VIDCON2_TVFMTSEL1_MASK (0x3 << 12) | ||
| 107 | #define VIDCON2_TVFMTSEL1_SHIFT (12) | ||
| 108 | #define VIDCON2_TVFMTSEL1_RGB (0x0 << 12) | ||
| 109 | #define VIDCON2_TVFMTSEL1_YUV422 (0x1 << 12) | ||
| 110 | #define VIDCON2_TVFMTSEL1_YUV444 (0x2 << 12) | ||
| 111 | |||
| 112 | #define VIDCON2_ORGYCbCr (1 << 8) | ||
| 113 | #define VIDCON2_YUVORDCrCb (1 << 7) | ||
| 114 | |||
| 115 | /* PRTCON (S3C6410, S5PC100) | ||
| 116 | * Might not be present in the S3C6410 documentation, | ||
| 117 | * but tests prove it's there almost for sure; shouldn't hurt in any case. | ||
| 118 | */ | ||
| 119 | #define PRTCON (0x0c) | ||
| 120 | #define PRTCON_PROTECT (1 << 11) | ||
| 121 | |||
| 122 | /* VIDTCON0 */ | ||
| 123 | |||
| 124 | #define VIDTCON0_VBPDE_MASK (0xff << 24) | ||
| 125 | #define VIDTCON0_VBPDE_SHIFT (24) | ||
| 126 | #define VIDTCON0_VBPDE_LIMIT (0xff) | ||
| 127 | #define VIDTCON0_VBPDE(_x) ((_x) << 24) | ||
| 128 | |||
| 129 | #define VIDTCON0_VBPD_MASK (0xff << 16) | ||
| 130 | #define VIDTCON0_VBPD_SHIFT (16) | ||
| 131 | #define VIDTCON0_VBPD_LIMIT (0xff) | ||
| 132 | #define VIDTCON0_VBPD(_x) ((_x) << 16) | ||
| 133 | |||
| 134 | #define VIDTCON0_VFPD_MASK (0xff << 8) | ||
| 135 | #define VIDTCON0_VFPD_SHIFT (8) | ||
| 136 | #define VIDTCON0_VFPD_LIMIT (0xff) | ||
| 137 | #define VIDTCON0_VFPD(_x) ((_x) << 8) | ||
| 138 | |||
| 139 | #define VIDTCON0_VSPW_MASK (0xff << 0) | ||
| 140 | #define VIDTCON0_VSPW_SHIFT (0) | ||
| 141 | #define VIDTCON0_VSPW_LIMIT (0xff) | ||
| 142 | #define VIDTCON0_VSPW(_x) ((_x) << 0) | ||
| 143 | |||
| 144 | /* VIDTCON1 */ | ||
| 145 | |||
| 146 | #define VIDTCON1_VFPDE_MASK (0xff << 24) | ||
| 147 | #define VIDTCON1_VFPDE_SHIFT (24) | ||
| 148 | #define VIDTCON1_VFPDE_LIMIT (0xff) | ||
| 149 | #define VIDTCON1_VFPDE(_x) ((_x) << 24) | ||
| 150 | |||
| 151 | #define VIDTCON1_HBPD_MASK (0xff << 16) | ||
| 152 | #define VIDTCON1_HBPD_SHIFT (16) | ||
| 153 | #define VIDTCON1_HBPD_LIMIT (0xff) | ||
| 154 | #define VIDTCON1_HBPD(_x) ((_x) << 16) | ||
| 155 | |||
| 156 | #define VIDTCON1_HFPD_MASK (0xff << 8) | ||
| 157 | #define VIDTCON1_HFPD_SHIFT (8) | ||
| 158 | #define VIDTCON1_HFPD_LIMIT (0xff) | ||
| 159 | #define VIDTCON1_HFPD(_x) ((_x) << 8) | ||
| 160 | |||
| 161 | #define VIDTCON1_HSPW_MASK (0xff << 0) | ||
| 162 | #define VIDTCON1_HSPW_SHIFT (0) | ||
| 163 | #define VIDTCON1_HSPW_LIMIT (0xff) | ||
| 164 | #define VIDTCON1_HSPW(_x) ((_x) << 0) | ||
| 165 | |||
| 166 | #define VIDTCON2 (0x18) | ||
| 167 | #define VIDTCON2_LINEVAL_MASK (0x7ff << 11) | ||
| 168 | #define VIDTCON2_LINEVAL_SHIFT (11) | ||
| 169 | #define VIDTCON2_LINEVAL_LIMIT (0x7ff) | ||
| 170 | #define VIDTCON2_LINEVAL(_x) ((_x) << 11) | ||
| 171 | |||
| 172 | #define VIDTCON2_HOZVAL_MASK (0x7ff << 0) | ||
| 173 | #define VIDTCON2_HOZVAL_SHIFT (0) | ||
| 174 | #define VIDTCON2_HOZVAL_LIMIT (0x7ff) | ||
| 175 | #define VIDTCON2_HOZVAL(_x) ((_x) << 0) | ||
| 176 | |||
| 177 | /* WINCONx */ | ||
| 178 | |||
| 179 | |||
| 180 | #define WINCONx_BITSWP (1 << 18) | ||
| 181 | #define WINCONx_BYTSWP (1 << 17) | ||
| 182 | #define WINCONx_HAWSWP (1 << 16) | ||
| 183 | #define WINCONx_WSWP (1 << 15) | ||
| 184 | #define WINCONx_BURSTLEN_MASK (0x3 << 9) | ||
| 185 | #define WINCONx_BURSTLEN_SHIFT (9) | ||
| 186 | #define WINCONx_BURSTLEN_16WORD (0x0 << 9) | ||
| 187 | #define WINCONx_BURSTLEN_8WORD (0x1 << 9) | ||
| 188 | #define WINCONx_BURSTLEN_4WORD (0x2 << 9) | ||
| 189 | |||
| 190 | #define WINCONx_ENWIN (1 << 0) | ||
| 191 | #define WINCON0_BPPMODE_MASK (0xf << 2) | ||
| 192 | #define WINCON0_BPPMODE_SHIFT (2) | ||
| 193 | #define WINCON0_BPPMODE_1BPP (0x0 << 2) | ||
| 194 | #define WINCON0_BPPMODE_2BPP (0x1 << 2) | ||
| 195 | #define WINCON0_BPPMODE_4BPP (0x2 << 2) | ||
| 196 | #define WINCON0_BPPMODE_8BPP_PALETTE (0x3 << 2) | ||
| 197 | #define WINCON0_BPPMODE_16BPP_565 (0x5 << 2) | ||
| 198 | #define WINCON0_BPPMODE_16BPP_1555 (0x7 << 2) | ||
| 199 | #define WINCON0_BPPMODE_18BPP_666 (0x8 << 2) | ||
| 200 | #define WINCON0_BPPMODE_24BPP_888 (0xb << 2) | ||
| 201 | |||
| 202 | #define WINCON1_BLD_PIX (1 << 6) | ||
| 203 | |||
| 204 | #define WINCON1_ALPHA_SEL (1 << 1) | ||
| 205 | #define WINCON1_BPPMODE_MASK (0xf << 2) | ||
| 206 | #define WINCON1_BPPMODE_SHIFT (2) | ||
| 207 | #define WINCON1_BPPMODE_1BPP (0x0 << 2) | ||
| 208 | #define WINCON1_BPPMODE_2BPP (0x1 << 2) | ||
| 209 | #define WINCON1_BPPMODE_4BPP (0x2 << 2) | ||
| 210 | #define WINCON1_BPPMODE_8BPP_PALETTE (0x3 << 2) | ||
| 211 | #define WINCON1_BPPMODE_8BPP_1232 (0x4 << 2) | ||
| 212 | #define WINCON1_BPPMODE_16BPP_565 (0x5 << 2) | ||
| 213 | #define WINCON1_BPPMODE_16BPP_A1555 (0x6 << 2) | ||
| 214 | #define WINCON1_BPPMODE_16BPP_I1555 (0x7 << 2) | ||
| 215 | #define WINCON1_BPPMODE_18BPP_666 (0x8 << 2) | ||
| 216 | #define WINCON1_BPPMODE_18BPP_A1665 (0x9 << 2) | ||
| 217 | #define WINCON1_BPPMODE_19BPP_A1666 (0xa << 2) | ||
| 218 | #define WINCON1_BPPMODE_24BPP_888 (0xb << 2) | ||
| 219 | #define WINCON1_BPPMODE_24BPP_A1887 (0xc << 2) | ||
| 220 | #define WINCON1_BPPMODE_25BPP_A1888 (0xd << 2) | ||
| 221 | #define WINCON1_BPPMODE_28BPP_A4888 (0xd << 2) | ||
| 222 | |||
| 223 | /* S5PV210 */ | ||
| 224 | #define SHADOWCON (0x34) | ||
| 225 | #define SHADOWCON_WINx_PROTECT(_win) (1 << (10 + (_win))) | ||
| 226 | /* DMA channels (all windows) */ | ||
| 227 | #define SHADOWCON_CHx_ENABLE(_win) (1 << (_win)) | ||
| 228 | /* Local input channels (windows 0-2) */ | ||
| 229 | #define SHADOWCON_CHx_LOCAL_ENABLE(_win) (1 << (5 + (_win))) | ||
| 230 | |||
| 231 | #define VIDOSDxA_TOPLEFT_X_MASK (0x7ff << 11) | ||
| 232 | #define VIDOSDxA_TOPLEFT_X_SHIFT (11) | ||
| 233 | #define VIDOSDxA_TOPLEFT_X_LIMIT (0x7ff) | ||
| 234 | #define VIDOSDxA_TOPLEFT_X(_x) ((_x) << 11) | ||
| 235 | |||
| 236 | #define VIDOSDxA_TOPLEFT_Y_MASK (0x7ff << 0) | ||
| 237 | #define VIDOSDxA_TOPLEFT_Y_SHIFT (0) | ||
| 238 | #define VIDOSDxA_TOPLEFT_Y_LIMIT (0x7ff) | ||
| 239 | #define VIDOSDxA_TOPLEFT_Y(_x) ((_x) << 0) | ||
| 240 | |||
| 241 | #define VIDOSDxB_BOTRIGHT_X_MASK (0x7ff << 11) | ||
| 242 | #define VIDOSDxB_BOTRIGHT_X_SHIFT (11) | ||
| 243 | #define VIDOSDxB_BOTRIGHT_X_LIMIT (0x7ff) | ||
| 244 | #define VIDOSDxB_BOTRIGHT_X(_x) ((_x) << 11) | ||
| 245 | |||
| 246 | #define VIDOSDxB_BOTRIGHT_Y_MASK (0x7ff << 0) | ||
| 247 | #define VIDOSDxB_BOTRIGHT_Y_SHIFT (0) | ||
| 248 | #define VIDOSDxB_BOTRIGHT_Y_LIMIT (0x7ff) | ||
| 249 | #define VIDOSDxB_BOTRIGHT_Y(_x) ((_x) << 0) | ||
| 250 | |||
| 251 | /* For VIDOSD[1..4]C */ | ||
| 252 | #define VIDISD14C_ALPHA0_R(_x) ((_x) << 20) | ||
| 253 | #define VIDISD14C_ALPHA0_G_MASK (0xf << 16) | ||
| 254 | #define VIDISD14C_ALPHA0_G_SHIFT (16) | ||
| 255 | #define VIDISD14C_ALPHA0_G_LIMIT (0xf) | ||
| 256 | #define VIDISD14C_ALPHA0_G(_x) ((_x) << 16) | ||
| 257 | #define VIDISD14C_ALPHA0_B_MASK (0xf << 12) | ||
| 258 | #define VIDISD14C_ALPHA0_B_SHIFT (12) | ||
| 259 | #define VIDISD14C_ALPHA0_B_LIMIT (0xf) | ||
| 260 | #define VIDISD14C_ALPHA0_B(_x) ((_x) << 12) | ||
| 261 | #define VIDISD14C_ALPHA1_R_MASK (0xf << 8) | ||
| 262 | #define VIDISD14C_ALPHA1_R_SHIFT (8) | ||
| 263 | #define VIDISD14C_ALPHA1_R_LIMIT (0xf) | ||
| 264 | #define VIDISD14C_ALPHA1_R(_x) ((_x) << 8) | ||
| 265 | #define VIDISD14C_ALPHA1_G_MASK (0xf << 4) | ||
| 266 | #define VIDISD14C_ALPHA1_G_SHIFT (4) | ||
| 267 | #define VIDISD14C_ALPHA1_G_LIMIT (0xf) | ||
| 268 | #define VIDISD14C_ALPHA1_G(_x) ((_x) << 4) | ||
| 269 | #define VIDISD14C_ALPHA1_B_MASK (0xf << 0) | ||
| 270 | #define VIDISD14C_ALPHA1_B_SHIFT (0) | ||
| 271 | #define VIDISD14C_ALPHA1_B_LIMIT (0xf) | ||
| 272 | #define VIDISD14C_ALPHA1_B(_x) ((_x) << 0) | ||
| 273 | |||
| 274 | /* Video buffer addresses */ | ||
| 275 | #define VIDW_BUF_START(_buff) (0xA0 + ((_buff) * 8)) | ||
| 276 | #define VIDW_BUF_START1(_buff) (0xA4 + ((_buff) * 8)) | ||
| 277 | #define VIDW_BUF_END(_buff) (0xD0 + ((_buff) * 8)) | ||
| 278 | #define VIDW_BUF_END1(_buff) (0xD4 + ((_buff) * 8)) | ||
| 279 | #define VIDW_BUF_SIZE(_buff) (0x100 + ((_buff) * 4)) | ||
| 280 | |||
| 281 | #define VIDW_BUF_SIZE_OFFSET_MASK (0x1fff << 13) | ||
| 282 | #define VIDW_BUF_SIZE_OFFSET_SHIFT (13) | ||
| 283 | #define VIDW_BUF_SIZE_OFFSET_LIMIT (0x1fff) | ||
| 284 | #define VIDW_BUF_SIZE_OFFSET(_x) ((_x) << 13) | ||
| 285 | |||
| 286 | #define VIDW_BUF_SIZE_PAGEWIDTH_MASK (0x1fff << 0) | ||
| 287 | #define VIDW_BUF_SIZE_PAGEWIDTH_SHIFT (0) | ||
| 288 | #define VIDW_BUF_SIZE_PAGEWIDTH_LIMIT (0x1fff) | ||
| 289 | #define VIDW_BUF_SIZE_PAGEWIDTH(_x) ((_x) << 0) | ||
| 290 | |||
| 291 | /* Interrupt controls and status */ | ||
| 292 | |||
| 293 | #define VIDINTCON0_FIFOINTERVAL_MASK (0x3f << 20) | ||
| 294 | #define VIDINTCON0_FIFOINTERVAL_SHIFT (20) | ||
| 295 | #define VIDINTCON0_FIFOINTERVAL_LIMIT (0x3f) | ||
| 296 | #define VIDINTCON0_FIFOINTERVAL(_x) ((_x) << 20) | ||
| 297 | |||
| 298 | #define VIDINTCON0_INT_SYSMAINCON (1 << 19) | ||
| 299 | #define VIDINTCON0_INT_SYSSUBCON (1 << 18) | ||
| 300 | #define VIDINTCON0_INT_I80IFDONE (1 << 17) | ||
| 301 | |||
| 302 | #define VIDINTCON0_FRAMESEL0_MASK (0x3 << 15) | ||
| 303 | #define VIDINTCON0_FRAMESEL0_SHIFT (15) | ||
| 304 | #define VIDINTCON0_FRAMESEL0_BACKPORCH (0x0 << 15) | ||
| 305 | #define VIDINTCON0_FRAMESEL0_VSYNC (0x1 << 15) | ||
| 306 | #define VIDINTCON0_FRAMESEL0_ACTIVE (0x2 << 15) | ||
| 307 | #define VIDINTCON0_FRAMESEL0_FRONTPORCH (0x3 << 15) | ||
| 308 | |||
| 309 | #define VIDINTCON0_FRAMESEL1 (1 << 13) | ||
| 310 | #define VIDINTCON0_FRAMESEL1_MASK (0x3 << 13) | ||
| 311 | #define VIDINTCON0_FRAMESEL1_NONE (0x0 << 13) | ||
| 312 | #define VIDINTCON0_FRAMESEL1_BACKPORCH (0x1 << 13) | ||
| 313 | #define VIDINTCON0_FRAMESEL1_VSYNC (0x2 << 13) | ||
| 314 | #define VIDINTCON0_FRAMESEL1_FRONTPORCH (0x3 << 13) | ||
| 315 | |||
| 316 | #define VIDINTCON0_INT_FRAME (1 << 12) | ||
| 317 | #define VIDINTCON0_FIFIOSEL_MASK (0x7f << 5) | ||
| 318 | #define VIDINTCON0_FIFIOSEL_SHIFT (5) | ||
| 319 | #define VIDINTCON0_FIFIOSEL_WINDOW0 (0x1 << 5) | ||
| 320 | #define VIDINTCON0_FIFIOSEL_WINDOW1 (0x2 << 5) | ||
| 321 | |||
| 322 | #define VIDINTCON0_FIFOLEVEL_MASK (0x7 << 2) | ||
| 323 | #define VIDINTCON0_FIFOLEVEL_SHIFT (2) | ||
| 324 | #define VIDINTCON0_FIFOLEVEL_TO25PC (0x0 << 2) | ||
| 325 | #define VIDINTCON0_FIFOLEVEL_TO50PC (0x1 << 2) | ||
| 326 | #define VIDINTCON0_FIFOLEVEL_TO75PC (0x2 << 2) | ||
| 327 | #define VIDINTCON0_FIFOLEVEL_EMPTY (0x3 << 2) | ||
| 328 | #define VIDINTCON0_FIFOLEVEL_FULL (0x4 << 2) | ||
| 329 | |||
| 330 | #define VIDINTCON0_INT_FIFO_MASK (0x3 << 0) | ||
| 331 | #define VIDINTCON0_INT_FIFO_SHIFT (0) | ||
| 332 | #define VIDINTCON0_INT_ENABLE (1 << 0) | ||
| 333 | |||
| 334 | #define VIDINTCON1 (0x134) | ||
| 335 | #define VIDINTCON1_INT_I180 (1 << 2) | ||
| 336 | #define VIDINTCON1_INT_FRAME (1 << 1) | ||
| 337 | #define VIDINTCON1_INT_FIFO (1 << 0) | ||
| 338 | |||
| 339 | /* Window colour-key control registers */ | ||
| 340 | #define WKEYCON (0x140) /* 6410,V210 */ | ||
| 341 | |||
| 342 | #define WKEYCON0 (0x00) | ||
| 343 | #define WKEYCON1 (0x04) | ||
| 344 | |||
| 345 | #define WxKEYCON0_KEYBL_EN (1 << 26) | ||
| 346 | #define WxKEYCON0_KEYEN_F (1 << 25) | ||
| 347 | #define WxKEYCON0_DIRCON (1 << 24) | ||
| 348 | #define WxKEYCON0_COMPKEY_MASK (0xffffff << 0) | ||
| 349 | #define WxKEYCON0_COMPKEY_SHIFT (0) | ||
| 350 | #define WxKEYCON0_COMPKEY_LIMIT (0xffffff) | ||
| 351 | #define WxKEYCON0_COMPKEY(_x) ((_x) << 0) | ||
| 352 | #define WxKEYCON1_COLVAL_MASK (0xffffff << 0) | ||
| 353 | #define WxKEYCON1_COLVAL_SHIFT (0) | ||
| 354 | #define WxKEYCON1_COLVAL_LIMIT (0xffffff) | ||
| 355 | #define WxKEYCON1_COLVAL(_x) ((_x) << 0) | ||
| 356 | |||
| 357 | |||
| 358 | /* Window blanking (MAP) */ | ||
| 359 | |||
| 360 | #define WINxMAP_MAP (1 << 24) | ||
| 361 | #define WINxMAP_MAP_COLOUR_MASK (0xffffff << 0) | ||
| 362 | #define WINxMAP_MAP_COLOUR_SHIFT (0) | ||
| 363 | #define WINxMAP_MAP_COLOUR_LIMIT (0xffffff) | ||
| 364 | #define WINxMAP_MAP_COLOUR(_x) ((_x) << 0) | ||
| 365 | |||
| 366 | #define WPALCON_PAL_UPDATE (1 << 9) | ||
| 367 | #define WPALCON_W1PAL_MASK (0x7 << 3) | ||
| 368 | #define WPALCON_W1PAL_SHIFT (3) | ||
| 369 | #define WPALCON_W1PAL_25BPP_A888 (0x0 << 3) | ||
| 370 | #define WPALCON_W1PAL_24BPP (0x1 << 3) | ||
| 371 | #define WPALCON_W1PAL_19BPP_A666 (0x2 << 3) | ||
| 372 | #define WPALCON_W1PAL_18BPP_A665 (0x3 << 3) | ||
| 373 | #define WPALCON_W1PAL_18BPP (0x4 << 3) | ||
| 374 | #define WPALCON_W1PAL_16BPP_A555 (0x5 << 3) | ||
| 375 | #define WPALCON_W1PAL_16BPP_565 (0x6 << 3) | ||
| 376 | |||
| 377 | #define WPALCON_W0PAL_MASK (0x7 << 0) | ||
| 378 | #define WPALCON_W0PAL_SHIFT (0) | ||
| 379 | #define WPALCON_W0PAL_25BPP_A888 (0x0 << 0) | ||
| 380 | #define WPALCON_W0PAL_24BPP (0x1 << 0) | ||
| 381 | #define WPALCON_W0PAL_19BPP_A666 (0x2 << 0) | ||
| 382 | #define WPALCON_W0PAL_18BPP_A665 (0x3 << 0) | ||
| 383 | #define WPALCON_W0PAL_18BPP (0x4 << 0) | ||
| 384 | #define WPALCON_W0PAL_16BPP_A555 (0x5 << 0) | ||
| 385 | #define WPALCON_W0PAL_16BPP_565 (0x6 << 0) | ||
| 386 | |||
diff --git a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h new file mode 100644 index 00000000000..dc90f5ede88 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h | |||
| @@ -0,0 +1,379 @@ | |||
| 1 | /* arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h | ||
| 2 | * | ||
| 3 | * Copyright 2008 Openmoko, Inc. | ||
| 4 | * Copyright 2008 Simtec Electronics | ||
| 5 | * http://armlinux.simtec.co.uk/ | ||
| 6 | * Ben Dooks <ben@simtec.co.uk> | ||
| 7 | * | ||
| 8 | * S3C - USB2.0 Highspeed/OtG device block registers | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef __PLAT_S3C64XX_REGS_USB_HSOTG_H | ||
| 16 | #define __PLAT_S3C64XX_REGS_USB_HSOTG_H __FILE__ | ||
| 17 | |||
| 18 | #define S3C_HSOTG_REG(x) (x) | ||
| 19 | |||
| 20 | #define S3C_GOTGCTL S3C_HSOTG_REG(0x000) | ||
| 21 | #define S3C_GOTGCTL_BSESVLD (1 << 19) | ||
| 22 | #define S3C_GOTGCTL_ASESVLD (1 << 18) | ||
| 23 | #define S3C_GOTGCTL_DBNC_SHORT (1 << 17) | ||
| 24 | #define S3C_GOTGCTL_CONID_B (1 << 16) | ||
| 25 | #define S3C_GOTGCTL_DEVHNPEN (1 << 11) | ||
| 26 | #define S3C_GOTGCTL_HSSETHNPEN (1 << 10) | ||
| 27 | #define S3C_GOTGCTL_HNPREQ (1 << 9) | ||
| 28 | #define S3C_GOTGCTL_HSTNEGSCS (1 << 8) | ||
| 29 | #define S3C_GOTGCTL_SESREQ (1 << 1) | ||
| 30 | #define S3C_GOTGCTL_SESREQSCS (1 << 0) | ||
| 31 | |||
| 32 | #define S3C_GOTGINT S3C_HSOTG_REG(0x004) | ||
| 33 | #define S3C_GOTGINT_DbnceDone (1 << 19) | ||
| 34 | #define S3C_GOTGINT_ADevTOUTChg (1 << 18) | ||
| 35 | #define S3C_GOTGINT_HstNegDet (1 << 17) | ||
| 36 | #define S3C_GOTGINT_HstnegSucStsChng (1 << 9) | ||
| 37 | #define S3C_GOTGINT_SesReqSucStsChng (1 << 8) | ||
| 38 | #define S3C_GOTGINT_SesEndDet (1 << 2) | ||
| 39 | |||
| 40 | #define S3C_GAHBCFG S3C_HSOTG_REG(0x008) | ||
| 41 | #define S3C_GAHBCFG_PTxFEmpLvl (1 << 8) | ||
| 42 | #define S3C_GAHBCFG_NPTxFEmpLvl (1 << 7) | ||
| 43 | #define S3C_GAHBCFG_DMAEn (1 << 5) | ||
| 44 | #define S3C_GAHBCFG_HBstLen_MASK (0xf << 1) | ||
| 45 | #define S3C_GAHBCFG_HBstLen_SHIFT (1) | ||
| 46 | #define S3C_GAHBCFG_HBstLen_Single (0x0 << 1) | ||
| 47 | #define S3C_GAHBCFG_HBstLen_Incr (0x1 << 1) | ||
| 48 | #define S3C_GAHBCFG_HBstLen_Incr4 (0x3 << 1) | ||
| 49 | #define S3C_GAHBCFG_HBstLen_Incr8 (0x5 << 1) | ||
| 50 | #define S3C_GAHBCFG_HBstLen_Incr16 (0x7 << 1) | ||
| 51 | #define S3C_GAHBCFG_GlblIntrEn (1 << 0) | ||
| 52 | |||
| 53 | #define S3C_GUSBCFG S3C_HSOTG_REG(0x00C) | ||
| 54 | #define S3C_GUSBCFG_PHYLPClkSel (1 << 15) | ||
| 55 | #define S3C_GUSBCFG_HNPCap (1 << 9) | ||
| 56 | #define S3C_GUSBCFG_SRPCap (1 << 8) | ||
| 57 | #define S3C_GUSBCFG_PHYIf16 (1 << 3) | ||
| 58 | #define S3C_GUSBCFG_TOutCal_MASK (0x7 << 0) | ||
| 59 | #define S3C_GUSBCFG_TOutCal_SHIFT (0) | ||
| 60 | #define S3C_GUSBCFG_TOutCal_LIMIT (0x7) | ||
| 61 | #define S3C_GUSBCFG_TOutCal(_x) ((_x) << 0) | ||
| 62 | |||
| 63 | #define S3C_GRSTCTL S3C_HSOTG_REG(0x010) | ||
| 64 | |||
| 65 | #define S3C_GRSTCTL_AHBIdle (1 << 31) | ||
| 66 | #define S3C_GRSTCTL_DMAReq (1 << 30) | ||
| 67 | #define S3C_GRSTCTL_TxFNum_MASK (0x1f << 6) | ||
| 68 | #define S3C_GRSTCTL_TxFNum_SHIFT (6) | ||
| 69 | #define S3C_GRSTCTL_TxFNum_LIMIT (0x1f) | ||
| 70 | #define S3C_GRSTCTL_TxFNum(_x) ((_x) << 6) | ||
| 71 | #define S3C_GRSTCTL_TxFFlsh (1 << 5) | ||
| 72 | #define S3C_GRSTCTL_RxFFlsh (1 << 4) | ||
| 73 | #define S3C_GRSTCTL_INTknQFlsh (1 << 3) | ||
| 74 | #define S3C_GRSTCTL_FrmCntrRst (1 << 2) | ||
| 75 | #define S3C_GRSTCTL_HSftRst (1 << 1) | ||
| 76 | #define S3C_GRSTCTL_CSftRst (1 << 0) | ||
| 77 | |||
| 78 | #define S3C_GINTSTS S3C_HSOTG_REG(0x014) | ||
| 79 | #define S3C_GINTMSK S3C_HSOTG_REG(0x018) | ||
| 80 | |||
| 81 | #define S3C_GINTSTS_WkUpInt (1 << 31) | ||
| 82 | #define S3C_GINTSTS_SessReqInt (1 << 30) | ||
| 83 | #define S3C_GINTSTS_DisconnInt (1 << 29) | ||
| 84 | #define S3C_GINTSTS_ConIDStsChng (1 << 28) | ||
| 85 | #define S3C_GINTSTS_PTxFEmp (1 << 26) | ||
| 86 | #define S3C_GINTSTS_HChInt (1 << 25) | ||
| 87 | #define S3C_GINTSTS_PrtInt (1 << 24) | ||
| 88 | #define S3C_GINTSTS_FetSusp (1 << 22) | ||
| 89 | #define S3C_GINTSTS_incompIP (1 << 21) | ||
| 90 | #define S3C_GINTSTS_IncomplSOIN (1 << 20) | ||
| 91 | #define S3C_GINTSTS_OEPInt (1 << 19) | ||
| 92 | #define S3C_GINTSTS_IEPInt (1 << 18) | ||
| 93 | #define S3C_GINTSTS_EPMis (1 << 17) | ||
| 94 | #define S3C_GINTSTS_EOPF (1 << 15) | ||
| 95 | #define S3C_GINTSTS_ISOutDrop (1 << 14) | ||
| 96 | #define S3C_GINTSTS_EnumDone (1 << 13) | ||
| 97 | #define S3C_GINTSTS_USBRst (1 << 12) | ||
| 98 | #define S3C_GINTSTS_USBSusp (1 << 11) | ||
| 99 | #define S3C_GINTSTS_ErlySusp (1 << 10) | ||
| 100 | #define S3C_GINTSTS_GOUTNakEff (1 << 7) | ||
| 101 | #define S3C_GINTSTS_GINNakEff (1 << 6) | ||
| 102 | #define S3C_GINTSTS_NPTxFEmp (1 << 5) | ||
| 103 | #define S3C_GINTSTS_RxFLvl (1 << 4) | ||
| 104 | #define S3C_GINTSTS_SOF (1 << 3) | ||
| 105 | #define S3C_GINTSTS_OTGInt (1 << 2) | ||
| 106 | #define S3C_GINTSTS_ModeMis (1 << 1) | ||
| 107 | #define S3C_GINTSTS_CurMod_Host (1 << 0) | ||
| 108 | |||
| 109 | #define S3C_GRXSTSR S3C_HSOTG_REG(0x01C) | ||
| 110 | #define S3C_GRXSTSP S3C_HSOTG_REG(0x020) | ||
| 111 | |||
| 112 | #define S3C_GRXSTS_FN_MASK (0x7f << 25) | ||
| 113 | #define S3C_GRXSTS_FN_SHIFT (25) | ||
| 114 | |||
| 115 | #define S3C_GRXSTS_PktSts_MASK (0xf << 17) | ||
| 116 | #define S3C_GRXSTS_PktSts_SHIFT (17) | ||
| 117 | #define S3C_GRXSTS_PktSts_GlobalOutNAK (0x1 << 17) | ||
| 118 | #define S3C_GRXSTS_PktSts_OutRX (0x2 << 17) | ||
| 119 | #define S3C_GRXSTS_PktSts_OutDone (0x3 << 17) | ||
| 120 | #define S3C_GRXSTS_PktSts_SetupDone (0x4 << 17) | ||
| 121 | #define S3C_GRXSTS_PktSts_SetupRX (0x6 << 17) | ||
| 122 | |||
| 123 | #define S3C_GRXSTS_DPID_MASK (0x3 << 15) | ||
| 124 | #define S3C_GRXSTS_DPID_SHIFT (15) | ||
| 125 | #define S3C_GRXSTS_ByteCnt_MASK (0x7ff << 4) | ||
| 126 | #define S3C_GRXSTS_ByteCnt_SHIFT (4) | ||
| 127 | #define S3C_GRXSTS_EPNum_MASK (0xf << 0) | ||
| 128 | #define S3C_GRXSTS_EPNum_SHIFT (0) | ||
| 129 | |||
| 130 | #define S3C_GRXFSIZ S3C_HSOTG_REG(0x024) | ||
| 131 | |||
| 132 | #define S3C_GNPTXFSIZ S3C_HSOTG_REG(0x028) | ||
| 133 | |||
| 134 | #define S3C_GNPTXFSIZ_NPTxFDep_MASK (0xffff << 16) | ||
| 135 | #define S3C_GNPTXFSIZ_NPTxFDep_SHIFT (16) | ||
| 136 | #define S3C_GNPTXFSIZ_NPTxFDep_LIMIT (0xffff) | ||
| 137 | #define S3C_GNPTXFSIZ_NPTxFDep(_x) ((_x) << 16) | ||
| 138 | #define S3C_GNPTXFSIZ_NPTxFStAddr_MASK (0xffff << 0) | ||
| 139 | #define S3C_GNPTXFSIZ_NPTxFStAddr_SHIFT (0) | ||
| 140 | #define S3C_GNPTXFSIZ_NPTxFStAddr_LIMIT (0xffff) | ||
| 141 | #define S3C_GNPTXFSIZ_NPTxFStAddr(_x) ((_x) << 0) | ||
| 142 | |||
| 143 | #define S3C_GNPTXSTS S3C_HSOTG_REG(0x02C) | ||
| 144 | |||
| 145 | #define S3C_GNPTXSTS_NPtxQTop_MASK (0x7f << 24) | ||
| 146 | #define S3C_GNPTXSTS_NPtxQTop_SHIFT (24) | ||
| 147 | |||
| 148 | #define S3C_GNPTXSTS_NPTxQSpcAvail_MASK (0xff << 16) | ||
| 149 | #define S3C_GNPTXSTS_NPTxQSpcAvail_SHIFT (16) | ||
| 150 | #define S3C_GNPTXSTS_NPTxQSpcAvail_GET(_v) (((_v) >> 16) & 0xff) | ||
| 151 | |||
| 152 | #define S3C_GNPTXSTS_NPTxFSpcAvail_MASK (0xffff << 0) | ||
| 153 | #define S3C_GNPTXSTS_NPTxFSpcAvail_SHIFT (0) | ||
| 154 | #define S3C_GNPTXSTS_NPTxFSpcAvail_GET(_v) (((_v) >> 0) & 0xffff) | ||
| 155 | |||
| 156 | |||
| 157 | #define S3C_HPTXFSIZ S3C_HSOTG_REG(0x100) | ||
| 158 | |||
| 159 | #define S3C_DPTXFSIZn(_a) S3C_HSOTG_REG(0x104 + (((_a) - 1) * 4)) | ||
| 160 | |||
| 161 | #define S3C_DPTXFSIZn_DPTxFSize_MASK (0xffff << 16) | ||
| 162 | #define S3C_DPTXFSIZn_DPTxFSize_SHIFT (16) | ||
| 163 | #define S3C_DPTXFSIZn_DPTxFSize_GET(_v) (((_v) >> 16) & 0xffff) | ||
| 164 | #define S3C_DPTXFSIZn_DPTxFSize_LIMIT (0xffff) | ||
| 165 | #define S3C_DPTXFSIZn_DPTxFSize(_x) ((_x) << 16) | ||
| 166 | |||
| 167 | #define S3C_DPTXFSIZn_DPTxFStAddr_MASK (0xffff << 0) | ||
| 168 | #define S3C_DPTXFSIZn_DPTxFStAddr_SHIFT (0) | ||
| 169 | |||
| 170 | /* Device mode registers */ | ||
| 171 | #define S3C_DCFG S3C_HSOTG_REG(0x800) | ||
| 172 | |||
| 173 | #define S3C_DCFG_EPMisCnt_MASK (0x1f << 18) | ||
| 174 | #define S3C_DCFG_EPMisCnt_SHIFT (18) | ||
| 175 | #define S3C_DCFG_EPMisCnt_LIMIT (0x1f) | ||
| 176 | #define S3C_DCFG_EPMisCnt(_x) ((_x) << 18) | ||
| 177 | |||
| 178 | #define S3C_DCFG_PerFrInt_MASK (0x3 << 11) | ||
| 179 | #define S3C_DCFG_PerFrInt_SHIFT (11) | ||
| 180 | #define S3C_DCFG_PerFrInt_LIMIT (0x3) | ||
| 181 | #define S3C_DCFG_PerFrInt(_x) ((_x) << 11) | ||
| 182 | |||
| 183 | #define S3C_DCFG_DevAddr_MASK (0x7f << 4) | ||
| 184 | #define S3C_DCFG_DevAddr_SHIFT (4) | ||
| 185 | #define S3C_DCFG_DevAddr_LIMIT (0x7f) | ||
| 186 | #define S3C_DCFG_DevAddr(_x) ((_x) << 4) | ||
| 187 | |||
| 188 | #define S3C_DCFG_NZStsOUTHShk (1 << 2) | ||
| 189 | |||
| 190 | #define S3C_DCFG_DevSpd_MASK (0x3 << 0) | ||
| 191 | #define S3C_DCFG_DevSpd_SHIFT (0) | ||
| 192 | #define S3C_DCFG_DevSpd_HS (0x0 << 0) | ||
| 193 | #define S3C_DCFG_DevSpd_FS (0x1 << 0) | ||
| 194 | #define S3C_DCFG_DevSpd_LS (0x2 << 0) | ||
| 195 | #define S3C_DCFG_DevSpd_FS48 (0x3 << 0) | ||
| 196 | |||
| 197 | #define S3C_DCTL S3C_HSOTG_REG(0x804) | ||
| 198 | |||
| 199 | #define S3C_DCTL_PWROnPrgDone (1 << 11) | ||
| 200 | #define S3C_DCTL_CGOUTNak (1 << 10) | ||
| 201 | #define S3C_DCTL_SGOUTNak (1 << 9) | ||
| 202 | #define S3C_DCTL_CGNPInNAK (1 << 8) | ||
| 203 | #define S3C_DCTL_SGNPInNAK (1 << 7) | ||
| 204 | #define S3C_DCTL_TstCtl_MASK (0x7 << 4) | ||
| 205 | #define S3C_DCTL_TstCtl_SHIFT (4) | ||
| 206 | #define S3C_DCTL_GOUTNakSts (1 << 3) | ||
| 207 | #define S3C_DCTL_GNPINNakSts (1 << 2) | ||
| 208 | #define S3C_DCTL_SftDiscon (1 << 1) | ||
| 209 | #define S3C_DCTL_RmtWkUpSig (1 << 0) | ||
| 210 | |||
| 211 | #define S3C_DSTS S3C_HSOTG_REG(0x808) | ||
| 212 | |||
| 213 | #define S3C_DSTS_SOFFN_MASK (0x3fff << 8) | ||
| 214 | #define S3C_DSTS_SOFFN_SHIFT (8) | ||
| 215 | #define S3C_DSTS_SOFFN_LIMIT (0x3fff) | ||
| 216 | #define S3C_DSTS_SOFFN(_x) ((_x) << 8) | ||
| 217 | #define S3C_DSTS_ErraticErr (1 << 3) | ||
| 218 | #define S3C_DSTS_EnumSpd_MASK (0x3 << 1) | ||
| 219 | #define S3C_DSTS_EnumSpd_SHIFT (1) | ||
| 220 | #define S3C_DSTS_EnumSpd_HS (0x0 << 1) | ||
| 221 | #define S3C_DSTS_EnumSpd_FS (0x1 << 1) | ||
| 222 | #define S3C_DSTS_EnumSpd_LS (0x2 << 1) | ||
| 223 | #define S3C_DSTS_EnumSpd_FS48 (0x3 << 1) | ||
| 224 | |||
| 225 | #define S3C_DSTS_SuspSts (1 << 0) | ||
| 226 | |||
| 227 | #define S3C_DIEPMSK S3C_HSOTG_REG(0x810) | ||
| 228 | |||
| 229 | #define S3C_DIEPMSK_TxFIFOEmpty (1 << 7) | ||
| 230 | #define S3C_DIEPMSK_INEPNakEffMsk (1 << 6) | ||
| 231 | #define S3C_DIEPMSK_INTknEPMisMsk (1 << 5) | ||
| 232 | #define S3C_DIEPMSK_INTknTXFEmpMsk (1 << 4) | ||
| 233 | #define S3C_DIEPMSK_TimeOUTMsk (1 << 3) | ||
| 234 | #define S3C_DIEPMSK_AHBErrMsk (1 << 2) | ||
| 235 | #define S3C_DIEPMSK_EPDisbldMsk (1 << 1) | ||
| 236 | #define S3C_DIEPMSK_XferComplMsk (1 << 0) | ||
| 237 | |||
| 238 | #define S3C_DOEPMSK S3C_HSOTG_REG(0x814) | ||
| 239 | |||
| 240 | #define S3C_DOEPMSK_Back2BackSetup (1 << 6) | ||
| 241 | #define S3C_DOEPMSK_OUTTknEPdisMsk (1 << 4) | ||
| 242 | #define S3C_DOEPMSK_SetupMsk (1 << 3) | ||
| 243 | #define S3C_DOEPMSK_AHBErrMsk (1 << 2) | ||
| 244 | #define S3C_DOEPMSK_EPDisbldMsk (1 << 1) | ||
| 245 | #define S3C_DOEPMSK_XferComplMsk (1 << 0) | ||
| 246 | |||
| 247 | #define S3C_DAINT S3C_HSOTG_REG(0x818) | ||
| 248 | #define S3C_DAINTMSK S3C_HSOTG_REG(0x81C) | ||
| 249 | |||
| 250 | #define S3C_DAINT_OutEP_SHIFT (16) | ||
| 251 | #define S3C_DAINT_OutEP(x) (1 << ((x) + 16)) | ||
| 252 | #define S3C_DAINT_InEP(x) (1 << (x)) | ||
| 253 | |||
| 254 | #define S3C_DTKNQR1 S3C_HSOTG_REG(0x820) | ||
| 255 | #define S3C_DTKNQR2 S3C_HSOTG_REG(0x824) | ||
| 256 | #define S3C_DTKNQR3 S3C_HSOTG_REG(0x830) | ||
| 257 | #define S3C_DTKNQR4 S3C_HSOTG_REG(0x834) | ||
| 258 | |||
| 259 | #define S3C_DVBUSDIS S3C_HSOTG_REG(0x828) | ||
| 260 | #define S3C_DVBUSPULSE S3C_HSOTG_REG(0x82C) | ||
| 261 | |||
| 262 | #define S3C_DIEPCTL0 S3C_HSOTG_REG(0x900) | ||
| 263 | #define S3C_DOEPCTL0 S3C_HSOTG_REG(0xB00) | ||
| 264 | #define S3C_DIEPCTL(_a) S3C_HSOTG_REG(0x900 + ((_a) * 0x20)) | ||
| 265 | #define S3C_DOEPCTL(_a) S3C_HSOTG_REG(0xB00 + ((_a) * 0x20)) | ||
| 266 | |||
| 267 | /* EP0 specialness: | ||
| 268 | * bits[29..28] - reserved (no SetD0PID, SetD1PID) | ||
| 269 | * bits[25..22] - should always be zero, this isn't a periodic endpoint | ||
| 270 | * bits[10..0] - MPS setting differenct for EP0 | ||
| 271 | */ | ||
| 272 | #define S3C_D0EPCTL_MPS_MASK (0x3 << 0) | ||
| 273 | #define S3C_D0EPCTL_MPS_SHIFT (0) | ||
| 274 | #define S3C_D0EPCTL_MPS_64 (0x0 << 0) | ||
| 275 | #define S3C_D0EPCTL_MPS_32 (0x1 << 0) | ||
| 276 | #define S3C_D0EPCTL_MPS_16 (0x2 << 0) | ||
| 277 | #define S3C_D0EPCTL_MPS_8 (0x3 << 0) | ||
| 278 | |||
| 279 | #define S3C_DxEPCTL_EPEna (1 << 31) | ||
| 280 | #define S3C_DxEPCTL_EPDis (1 << 30) | ||
| 281 | #define S3C_DxEPCTL_SetD1PID (1 << 29) | ||
| 282 | #define S3C_DxEPCTL_SetOddFr (1 << 29) | ||
| 283 | #define S3C_DxEPCTL_SetD0PID (1 << 28) | ||
| 284 | #define S3C_DxEPCTL_SetEvenFr (1 << 28) | ||
| 285 | #define S3C_DxEPCTL_SNAK (1 << 27) | ||
| 286 | #define S3C_DxEPCTL_CNAK (1 << 26) | ||
| 287 | #define S3C_DxEPCTL_TxFNum_MASK (0xf << 22) | ||
| 288 | #define S3C_DxEPCTL_TxFNum_SHIFT (22) | ||
| 289 | #define S3C_DxEPCTL_TxFNum_LIMIT (0xf) | ||
| 290 | #define S3C_DxEPCTL_TxFNum(_x) ((_x) << 22) | ||
| 291 | |||
| 292 | #define S3C_DxEPCTL_Stall (1 << 21) | ||
| 293 | #define S3C_DxEPCTL_Snp (1 << 20) | ||
| 294 | #define S3C_DxEPCTL_EPType_MASK (0x3 << 18) | ||
| 295 | #define S3C_DxEPCTL_EPType_SHIFT (18) | ||
| 296 | #define S3C_DxEPCTL_EPType_Control (0x0 << 18) | ||
| 297 | #define S3C_DxEPCTL_EPType_Iso (0x1 << 18) | ||
| 298 | #define S3C_DxEPCTL_EPType_Bulk (0x2 << 18) | ||
| 299 | #define S3C_DxEPCTL_EPType_Intterupt (0x3 << 18) | ||
| 300 | |||
| 301 | #define S3C_DxEPCTL_NAKsts (1 << 17) | ||
| 302 | #define S3C_DxEPCTL_DPID (1 << 16) | ||
| 303 | #define S3C_DxEPCTL_EOFrNum (1 << 16) | ||
| 304 | #define S3C_DxEPCTL_USBActEp (1 << 15) | ||
| 305 | #define S3C_DxEPCTL_NextEp_MASK (0xf << 11) | ||
| 306 | #define S3C_DxEPCTL_NextEp_SHIFT (11) | ||
| 307 | #define S3C_DxEPCTL_NextEp_LIMIT (0xf) | ||
| 308 | #define S3C_DxEPCTL_NextEp(_x) ((_x) << 11) | ||
| 309 | |||
| 310 | #define S3C_DxEPCTL_MPS_MASK (0x7ff << 0) | ||
| 311 | #define S3C_DxEPCTL_MPS_SHIFT (0) | ||
| 312 | #define S3C_DxEPCTL_MPS_LIMIT (0x7ff) | ||
| 313 | #define S3C_DxEPCTL_MPS(_x) ((_x) << 0) | ||
| 314 | |||
| 315 | #define S3C_DIEPINT(_a) S3C_HSOTG_REG(0x908 + ((_a) * 0x20)) | ||
| 316 | #define S3C_DOEPINT(_a) S3C_HSOTG_REG(0xB08 + ((_a) * 0x20)) | ||
| 317 | |||
| 318 | #define S3C_DxEPINT_INEPNakEff (1 << 6) | ||
| 319 | #define S3C_DxEPINT_Back2BackSetup (1 << 6) | ||
| 320 | #define S3C_DxEPINT_INTknEPMis (1 << 5) | ||
| 321 | #define S3C_DxEPINT_INTknTXFEmp (1 << 4) | ||
| 322 | #define S3C_DxEPINT_OUTTknEPdis (1 << 4) | ||
| 323 | #define S3C_DxEPINT_Timeout (1 << 3) | ||
| 324 | #define S3C_DxEPINT_Setup (1 << 3) | ||
| 325 | #define S3C_DxEPINT_AHBErr (1 << 2) | ||
| 326 | #define S3C_DxEPINT_EPDisbld (1 << 1) | ||
| 327 | #define S3C_DxEPINT_XferCompl (1 << 0) | ||
| 328 | |||
| 329 | #define S3C_DIEPTSIZ0 S3C_HSOTG_REG(0x910) | ||
| 330 | |||
| 331 | #define S3C_DIEPTSIZ0_PktCnt_MASK (0x3 << 19) | ||
| 332 | #define S3C_DIEPTSIZ0_PktCnt_SHIFT (19) | ||
| 333 | #define S3C_DIEPTSIZ0_PktCnt_LIMIT (0x3) | ||
| 334 | #define S3C_DIEPTSIZ0_PktCnt(_x) ((_x) << 19) | ||
| 335 | |||
| 336 | #define S3C_DIEPTSIZ0_XferSize_MASK (0x7f << 0) | ||
| 337 | #define S3C_DIEPTSIZ0_XferSize_SHIFT (0) | ||
| 338 | #define S3C_DIEPTSIZ0_XferSize_LIMIT (0x7f) | ||
| 339 | #define S3C_DIEPTSIZ0_XferSize(_x) ((_x) << 0) | ||
| 340 | |||
| 341 | |||
| 342 | #define DOEPTSIZ0 S3C_HSOTG_REG(0xB10) | ||
| 343 | #define S3C_DOEPTSIZ0_SUPCnt_MASK (0x3 << 29) | ||
| 344 | #define S3C_DOEPTSIZ0_SUPCnt_SHIFT (29) | ||
| 345 | #define S3C_DOEPTSIZ0_SUPCnt_LIMIT (0x3) | ||
| 346 | #define S3C_DOEPTSIZ0_SUPCnt(_x) ((_x) << 29) | ||
| 347 | |||
| 348 | #define S3C_DOEPTSIZ0_PktCnt (1 << 19) | ||
| 349 | #define S3C_DOEPTSIZ0_XferSize_MASK (0x7f << 0) | ||
| 350 | #define S3C_DOEPTSIZ0_XferSize_SHIFT (0) | ||
| 351 | |||
| 352 | #define S3C_DIEPTSIZ(_a) S3C_HSOTG_REG(0x910 + ((_a) * 0x20)) | ||
| 353 | #define S3C_DOEPTSIZ(_a) S3C_HSOTG_REG(0xB10 + ((_a) * 0x20)) | ||
| 354 | |||
| 355 | #define S3C_DxEPTSIZ_MC_MASK (0x3 << 29) | ||
| 356 | #define S3C_DxEPTSIZ_MC_SHIFT (29) | ||
| 357 | #define S3C_DxEPTSIZ_MC_LIMIT (0x3) | ||
| 358 | #define S3C_DxEPTSIZ_MC(_x) ((_x) << 29) | ||
| 359 | |||
| 360 | #define S3C_DxEPTSIZ_PktCnt_MASK (0x3ff << 19) | ||
| 361 | #define S3C_DxEPTSIZ_PktCnt_SHIFT (19) | ||
| 362 | #define S3C_DxEPTSIZ_PktCnt_GET(_v) (((_v) >> 19) & 0x3ff) | ||
| 363 | #define S3C_DxEPTSIZ_PktCnt_LIMIT (0x3ff) | ||
| 364 | #define S3C_DxEPTSIZ_PktCnt(_x) ((_x) << 19) | ||
| 365 | |||
| 366 | #define S3C_DxEPTSIZ_XferSize_MASK (0x7ffff << 0) | ||
| 367 | #define S3C_DxEPTSIZ_XferSize_SHIFT (0) | ||
| 368 | #define S3C_DxEPTSIZ_XferSize_GET(_v) (((_v) >> 0) & 0x7ffff) | ||
| 369 | #define S3C_DxEPTSIZ_XferSize_LIMIT (0x7ffff) | ||
| 370 | #define S3C_DxEPTSIZ_XferSize(_x) ((_x) << 0) | ||
| 371 | |||
| 372 | |||
| 373 | #define S3C_DIEPDMA(_a) S3C_HSOTG_REG(0x914 + ((_a) * 0x20)) | ||
| 374 | #define S3C_DOEPDMA(_a) S3C_HSOTG_REG(0xB14 + ((_a) * 0x20)) | ||
| 375 | #define S3C_DTXFSTS(_a) S3C_HSOTG_REG(0x918 + ((_a) * 0x20)) | ||
| 376 | |||
| 377 | #define S3C_EPFIFO(_a) S3C_HSOTG_REG(0x1000 + ((_a) * 0x1000)) | ||
| 378 | |||
| 379 | #endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_H */ | ||
diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h new file mode 100644 index 00000000000..81074421312 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h | |||
| @@ -0,0 +1,98 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2010 Samsung Electronics Co. Ltd. | ||
| 3 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef __S3C_DMA_PL330_H_ | ||
| 12 | #define __S3C_DMA_PL330_H_ | ||
| 13 | |||
| 14 | #define S3C2410_DMAF_AUTOSTART (1 << 0) | ||
| 15 | #define S3C2410_DMAF_CIRCULAR (1 << 1) | ||
| 16 | |||
| 17 | /* | ||
| 18 | * PL330 can assign any channel to communicate with | ||
| 19 | * any of the peripherals attched to the DMAC. | ||
| 20 | * For the sake of consistency across client drivers, | ||
| 21 | * We keep the channel names unchanged and only add | ||
| 22 | * missing peripherals are added. | ||
| 23 | * Order is not important since S3C PL330 API driver | ||
| 24 | * use these just as IDs. | ||
| 25 | */ | ||
| 26 | enum dma_ch { | ||
| 27 | DMACH_UART0_RX, | ||
| 28 | DMACH_UART0_TX, | ||
| 29 | DMACH_UART1_RX, | ||
| 30 | DMACH_UART1_TX, | ||
| 31 | DMACH_UART2_RX, | ||
| 32 | DMACH_UART2_TX, | ||
| 33 | DMACH_UART3_RX, | ||
| 34 | DMACH_UART3_TX, | ||
| 35 | DMACH_UART4_RX, | ||
| 36 | DMACH_UART4_TX, | ||
| 37 | DMACH_UART5_RX, | ||
| 38 | DMACH_UART5_TX, | ||
| 39 | DMACH_USI_RX, | ||
| 40 | DMACH_USI_TX, | ||
| 41 | DMACH_IRDA, | ||
| 42 | DMACH_I2S0_RX, | ||
| 43 | DMACH_I2S0_TX, | ||
| 44 | DMACH_I2S0S_TX, | ||
| 45 | DMACH_I2S1_RX, | ||
| 46 | DMACH_I2S1_TX, | ||
| 47 | DMACH_I2S2_RX, | ||
| 48 | DMACH_I2S2_TX, | ||
| 49 | DMACH_SPI0_RX, | ||
| 50 | DMACH_SPI0_TX, | ||
| 51 | DMACH_SPI1_RX, | ||
| 52 | DMACH_SPI1_TX, | ||
| 53 | DMACH_SPI2_RX, | ||
| 54 | DMACH_SPI2_TX, | ||
| 55 | DMACH_AC97_MICIN, | ||
| 56 | DMACH_AC97_PCMIN, | ||
| 57 | DMACH_AC97_PCMOUT, | ||
| 58 | DMACH_EXTERNAL, | ||
| 59 | DMACH_PWM, | ||
| 60 | DMACH_SPDIF, | ||
| 61 | DMACH_HSI_RX, | ||
| 62 | DMACH_HSI_TX, | ||
| 63 | DMACH_PCM0_TX, | ||
| 64 | DMACH_PCM0_RX, | ||
| 65 | DMACH_PCM1_TX, | ||
| 66 | DMACH_PCM1_RX, | ||
| 67 | DMACH_PCM2_TX, | ||
| 68 | DMACH_PCM2_RX, | ||
| 69 | DMACH_MSM_REQ3, | ||
| 70 | DMACH_MSM_REQ2, | ||
| 71 | DMACH_MSM_REQ1, | ||
| 72 | DMACH_MSM_REQ0, | ||
| 73 | DMACH_SLIMBUS0_RX, | ||
| 74 | DMACH_SLIMBUS0_TX, | ||
| 75 | DMACH_SLIMBUS0AUX_RX, | ||
| 76 | DMACH_SLIMBUS0AUX_TX, | ||
| 77 | DMACH_SLIMBUS1_RX, | ||
| 78 | DMACH_SLIMBUS1_TX, | ||
| 79 | DMACH_SLIMBUS2_RX, | ||
| 80 | DMACH_SLIMBUS2_TX, | ||
| 81 | DMACH_SLIMBUS3_RX, | ||
| 82 | DMACH_SLIMBUS3_TX, | ||
| 83 | DMACH_SLIMBUS4_RX, | ||
| 84 | DMACH_SLIMBUS4_TX, | ||
| 85 | DMACH_SLIMBUS5_RX, | ||
| 86 | DMACH_SLIMBUS5_TX, | ||
| 87 | /* END Marker, also used to denote a reserved channel */ | ||
| 88 | DMACH_MAX, | ||
| 89 | }; | ||
| 90 | |||
| 91 | static inline bool s3c_dma_has_circular(void) | ||
| 92 | { | ||
| 93 | return true; | ||
| 94 | } | ||
| 95 | |||
| 96 | #include <plat/dma.h> | ||
| 97 | |||
| 98 | #endif /* __S3C_DMA_PL330_H_ */ | ||
diff --git a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h new file mode 100644 index 00000000000..bf5e2a9d408 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h | ||
| 2 | * | ||
| 3 | * Copyright (C) 2010 Samsung Electronics Co. Ltd. | ||
| 4 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef __S3C_PL330_PDATA_H | ||
| 13 | #define __S3C_PL330_PDATA_H | ||
| 14 | |||
| 15 | #include <plat/s3c-dma-pl330.h> | ||
| 16 | |||
| 17 | /* | ||
| 18 | * Every PL330 DMAC has max 32 peripheral interfaces, | ||
| 19 | * of which some may be not be really used in your | ||
| 20 | * DMAC's configuration. | ||
| 21 | * Populate this array of 32 peri i/fs with relevant | ||
| 22 | * channel IDs for used peri i/f and DMACH_MAX for | ||
| 23 | * those unused. | ||
| 24 | * | ||
| 25 | * The platforms just need to provide this info | ||
| 26 | * to the S3C DMA API driver for PL330. | ||
| 27 | */ | ||
| 28 | struct s3c_pl330_platdata { | ||
| 29 | enum dma_ch peri[32]; | ||
| 30 | }; | ||
| 31 | |||
| 32 | #endif /* __S3C_PL330_PDATA_H */ | ||
diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h new file mode 100644 index 00000000000..4c16fa3621b --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h | ||
| 2 | * | ||
| 3 | * Copyright (C) 2009 Samsung Electronics Ltd. | ||
| 4 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef __S3C64XX_PLAT_SPI_H | ||
| 12 | #define __S3C64XX_PLAT_SPI_H | ||
| 13 | |||
| 14 | /** | ||
| 15 | * struct s3c64xx_spi_csinfo - ChipSelect description | ||
| 16 | * @fb_delay: Slave specific feedback delay. | ||
| 17 | * Refer to FB_CLK_SEL register definition in SPI chapter. | ||
| 18 | * @line: Custom 'identity' of the CS line. | ||
| 19 | * @set_level: CS line control. | ||
| 20 | * | ||
| 21 | * This is per SPI-Slave Chipselect information. | ||
| 22 | * Allocate and initialize one in machine init code and make the | ||
| 23 | * spi_board_info.controller_data point to it. | ||
| 24 | */ | ||
| 25 | struct s3c64xx_spi_csinfo { | ||
| 26 | u8 fb_delay; | ||
| 27 | unsigned line; | ||
| 28 | void (*set_level)(unsigned line_id, int lvl); | ||
| 29 | }; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * struct s3c64xx_spi_info - SPI Controller defining structure | ||
| 33 | * @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field. | ||
| 34 | * @src_clk_name: Platform name of the corresponding clock. | ||
| 35 | * @clk_from_cmu: If the SPI clock/prescalar control block is present | ||
| 36 | * by the platform's clock-management-unit and not in SPI controller. | ||
| 37 | * @num_cs: Number of CS this controller emulates. | ||
| 38 | * @cfg_gpio: Configure pins for this SPI controller. | ||
| 39 | * @fifo_lvl_mask: All tx fifo_lvl fields start at offset-6 | ||
| 40 | * @rx_lvl_offset: Depends on tx fifo_lvl field and bus number | ||
| 41 | * @high_speed: If the controller supports HIGH_SPEED_EN bit | ||
| 42 | * @tx_st_done: Depends on tx fifo_lvl field | ||
| 43 | */ | ||
| 44 | struct s3c64xx_spi_info { | ||
| 45 | int src_clk_nr; | ||
| 46 | char *src_clk_name; | ||
| 47 | bool clk_from_cmu; | ||
| 48 | |||
| 49 | int num_cs; | ||
| 50 | |||
| 51 | int (*cfg_gpio)(struct platform_device *pdev); | ||
| 52 | |||
| 53 | /* Following two fields are for future compatibility */ | ||
| 54 | int fifo_lvl_mask; | ||
| 55 | int rx_lvl_offset; | ||
| 56 | int high_speed; | ||
| 57 | int tx_st_done; | ||
| 58 | }; | ||
| 59 | |||
| 60 | /** | ||
| 61 | * s3c64xx_spi_set_info - SPI Controller configure callback by the board | ||
| 62 | * initialization code. | ||
| 63 | * @cntrlr: SPI controller number the configuration is for. | ||
| 64 | * @src_clk_nr: Clock the SPI controller is to use to generate SPI clocks. | ||
| 65 | * @num_cs: Number of elements in the 'cs' array. | ||
| 66 | * | ||
| 67 | * Call this from machine init code for each SPI Controller that | ||
| 68 | * has some chips attached to it. | ||
| 69 | */ | ||
| 70 | extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); | ||
| 71 | extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); | ||
| 72 | extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); | ||
| 73 | extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); | ||
| 74 | |||
| 75 | #endif /* __S3C64XX_PLAT_SPI_H */ | ||
diff --git a/arch/arm/plat-samsung/include/plat/ts.h b/arch/arm/plat-samsung/include/plat/ts.h new file mode 100644 index 00000000000..26fdb22e0fc --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/ts.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* arch/arm/plat-samsung/include/plat/ts.h | ||
| 2 | * | ||
| 3 | * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #ifndef __ASM_ARM_TS_H | ||
| 11 | #define __ASM_ARM_TS_H | ||
| 12 | |||
| 13 | struct s3c2410_ts_mach_info { | ||
| 14 | int delay; | ||
| 15 | int presc; | ||
| 16 | int oversampling_shift; | ||
| 17 | void (*cfg_gpio)(struct platform_device *dev); | ||
| 18 | }; | ||
| 19 | |||
| 20 | extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *); | ||
| 21 | |||
| 22 | /* defined by architecture to configure gpio */ | ||
| 23 | extern void s3c24xx_ts_cfg_gpio(struct platform_device *dev); | ||
| 24 | |||
| 25 | #endif /* __ASM_ARM_TS_H */ | ||
diff --git a/arch/arm/plat-samsung/include/plat/udc-hs.h b/arch/arm/plat-samsung/include/plat/udc-hs.h new file mode 100644 index 00000000000..a22a4f2eea9 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/udc-hs.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* arch/arm/plat-s3c/include/plat/udc-hs.h | ||
| 2 | * | ||
| 3 | * Copyright 2008 Openmoko, Inc. | ||
| 4 | * Copyright 2008 Simtec Electronics | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * http://armlinux.simtec.co.uk/ | ||
| 7 | * | ||
| 8 | * S3C USB2.0 High-speed / OtG platform information | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | enum s3c_hsotg_dmamode { | ||
| 16 | S3C_HSOTG_DMA_NONE, /* do not use DMA at-all */ | ||
| 17 | S3C_HSOTG_DMA_ONLY, /* always use DMA */ | ||
| 18 | S3C_HSOTG_DMA_DRV, /* DMA is chosen by driver */ | ||
| 19 | }; | ||
| 20 | |||
| 21 | /** | ||
| 22 | * struct s3c_hsotg_plat - platform data for high-speed otg/udc | ||
| 23 | * @dma: Whether to use DMA or not. | ||
| 24 | * @is_osc: The clock source is an oscillator, not a crystal | ||
| 25 | */ | ||
| 26 | struct s3c_hsotg_plat { | ||
| 27 | enum s3c_hsotg_dmamode dma; | ||
| 28 | unsigned int is_osc : 1; | ||
| 29 | }; | ||
diff --git a/arch/arm/plat-samsung/include/plat/usb-control.h b/arch/arm/plat-samsung/include/plat/usb-control.h new file mode 100644 index 00000000000..7fa1fbefc3f --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/usb-control.h | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | /* arch/arm/plat-samsung/include/plat/usb-control.h | ||
| 2 | * | ||
| 3 | * Copyright (c) 2004 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * | ||
| 6 | * S3C - USB host port information | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef __ASM_ARCH_USBCONTROL_H | ||
| 14 | #define __ASM_ARCH_USBCONTROL_H | ||
| 15 | |||
| 16 | #define S3C_HCDFLG_USED (1) | ||
| 17 | |||
| 18 | struct s3c2410_hcd_port { | ||
| 19 | unsigned char flags; | ||
| 20 | unsigned char power; | ||
| 21 | unsigned char oc_status; | ||
| 22 | unsigned char oc_changed; | ||
| 23 | }; | ||
| 24 | |||
| 25 | struct s3c2410_hcd_info { | ||
| 26 | struct usb_hcd *hcd; | ||
| 27 | struct s3c2410_hcd_port port[2]; | ||
| 28 | |||
| 29 | void (*power_control)(int port, int to); | ||
| 30 | void (*enable_oc)(struct s3c2410_hcd_info *, int on); | ||
| 31 | void (*report_oc)(struct s3c2410_hcd_info *, int ports); | ||
| 32 | }; | ||
| 33 | |||
| 34 | static void inline s3c2410_usb_report_oc(struct s3c2410_hcd_info *info, int ports) | ||
| 35 | { | ||
| 36 | if (info->report_oc != NULL) { | ||
| 37 | (info->report_oc)(info, ports); | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | extern void s3c_ohci_set_platdata(struct s3c2410_hcd_info *info); | ||
| 42 | |||
| 43 | #endif /*__ASM_ARCH_USBCONTROL_H */ | ||
diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c new file mode 100644 index 00000000000..3014c7226bd --- /dev/null +++ b/arch/arm/plat-samsung/irq-uart.c | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | /* arch/arm/plat-samsung/irq-uart.c | ||
| 2 | * originally part of arch/arm/plat-s3c64xx/irq.c | ||
| 3 | * | ||
| 4 | * Copyright 2008 Openmoko, Inc. | ||
| 5 | * Copyright 2008 Simtec Electronics | ||
| 6 | * Ben Dooks <ben@simtec.co.uk> | ||
| 7 | * http://armlinux.simtec.co.uk/ | ||
| 8 | * | ||
| 9 | * Samsung- UART Interrupt handling | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 as | ||
| 13 | * published by the Free Software Foundation. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/serial_core.h> | ||
| 19 | #include <linux/irq.h> | ||
| 20 | #include <linux/io.h> | ||
| 21 | |||
| 22 | #include <asm/mach/irq.h> | ||
| 23 | |||
| 24 | #include <mach/map.h> | ||
| 25 | #include <plat/irq-uart.h> | ||
| 26 | #include <plat/regs-serial.h> | ||
| 27 | #include <plat/cpu.h> | ||
| 28 | |||
| 29 | /* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3] | ||
| 30 | * are consecutive when looking up the interrupt in the demux routines. | ||
| 31 | */ | ||
| 32 | static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc) | ||
| 33 | { | ||
| 34 | struct s3c_uart_irq *uirq = desc->irq_data.handler_data; | ||
| 35 | struct irq_chip *chip = irq_get_chip(irq); | ||
| 36 | u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP); | ||
| 37 | int base = uirq->base_irq; | ||
| 38 | |||
| 39 | chained_irq_enter(chip, desc); | ||
| 40 | |||
| 41 | if (pend & (1 << 0)) | ||
| 42 | generic_handle_irq(base); | ||
| 43 | if (pend & (1 << 1)) | ||
| 44 | generic_handle_irq(base + 1); | ||
| 45 | if (pend & (1 << 2)) | ||
| 46 | generic_handle_irq(base + 2); | ||
| 47 | if (pend & (1 << 3)) | ||
| 48 | generic_handle_irq(base + 3); | ||
| 49 | |||
| 50 | chained_irq_exit(chip, desc); | ||
| 51 | } | ||
| 52 | |||
| 53 | static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) | ||
| 54 | { | ||
| 55 | void __iomem *reg_base = uirq->regs; | ||
| 56 | struct irq_chip_generic *gc; | ||
| 57 | struct irq_chip_type *ct; | ||
| 58 | |||
| 59 | /* mask all interrupts at the start. */ | ||
| 60 | __raw_writel(0xf, reg_base + S3C64XX_UINTM); | ||
| 61 | |||
| 62 | gc = irq_alloc_generic_chip("s3c-uart", 1, uirq->base_irq, reg_base, | ||
| 63 | handle_level_irq); | ||
| 64 | |||
| 65 | if (!gc) { | ||
| 66 | pr_err("%s: irq_alloc_generic_chip for IRQ %u failed\n", | ||
| 67 | __func__, uirq->base_irq); | ||
| 68 | return; | ||
| 69 | } | ||
| 70 | |||
| 71 | ct = gc->chip_types; | ||
| 72 | ct->chip.irq_ack = irq_gc_ack_set_bit; | ||
| 73 | ct->chip.irq_mask = irq_gc_mask_set_bit; | ||
| 74 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; | ||
| 75 | ct->regs.ack = S3C64XX_UINTP; | ||
| 76 | ct->regs.mask = S3C64XX_UINTM; | ||
| 77 | irq_setup_generic_chip(gc, IRQ_MSK(4), IRQ_GC_INIT_MASK_CACHE, | ||
| 78 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
| 79 | |||
| 80 | irq_set_handler_data(uirq->parent_irq, uirq); | ||
| 81 | irq_set_chained_handler(uirq->parent_irq, s3c_irq_demux_uart); | ||
| 82 | } | ||
| 83 | |||
| 84 | /** | ||
| 85 | * s3c_init_uart_irqs() - initialise UART IRQs and the necessary demuxing | ||
| 86 | * @irq: The interrupt data for registering | ||
| 87 | * @nr_irqs: The number of interrupt descriptions in @irq. | ||
| 88 | * | ||
| 89 | * Register the UART interrupts specified by @irq including the demuxing | ||
| 90 | * routines. This supports the S3C6400 and newer style of devices. | ||
| 91 | */ | ||
| 92 | void __init s3c_init_uart_irqs(struct s3c_uart_irq *irq, unsigned int nr_irqs) | ||
| 93 | { | ||
| 94 | for (; nr_irqs > 0; nr_irqs--, irq++) | ||
| 95 | s3c_init_uart_irq(irq); | ||
| 96 | } | ||
diff --git a/arch/arm/plat-samsung/pd.c b/arch/arm/plat-samsung/pd.c new file mode 100644 index 00000000000..efe1d564473 --- /dev/null +++ b/arch/arm/plat-samsung/pd.c | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/pd.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
| 4 | * http://www.samsung.com | ||
| 5 | * | ||
| 6 | * Samsung Power domain support | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/err.h> | ||
| 17 | #include <linux/pm_runtime.h> | ||
| 18 | |||
| 19 | #include <plat/pd.h> | ||
| 20 | |||
| 21 | static int samsung_pd_probe(struct platform_device *pdev) | ||
| 22 | { | ||
| 23 | struct samsung_pd_info *pdata = pdev->dev.platform_data; | ||
| 24 | struct device *dev = &pdev->dev; | ||
| 25 | |||
| 26 | if (!pdata) { | ||
| 27 | dev_err(dev, "no device data specified\n"); | ||
| 28 | return -ENOENT; | ||
| 29 | } | ||
| 30 | |||
| 31 | pm_runtime_set_active(dev); | ||
| 32 | pm_runtime_enable(dev); | ||
| 33 | |||
| 34 | dev_info(dev, "power domain registered\n"); | ||
| 35 | return 0; | ||
| 36 | } | ||
| 37 | |||
| 38 | static int __devexit samsung_pd_remove(struct platform_device *pdev) | ||
| 39 | { | ||
| 40 | struct device *dev = &pdev->dev; | ||
| 41 | |||
| 42 | pm_runtime_disable(dev); | ||
| 43 | return 0; | ||
| 44 | } | ||
| 45 | |||
| 46 | static int samsung_pd_runtime_suspend(struct device *dev) | ||
| 47 | { | ||
| 48 | struct samsung_pd_info *pdata = dev->platform_data; | ||
| 49 | int ret = 0; | ||
| 50 | |||
| 51 | if (pdata->disable) | ||
| 52 | ret = pdata->disable(dev); | ||
| 53 | |||
| 54 | dev_dbg(dev, "suspended\n"); | ||
| 55 | return ret; | ||
| 56 | } | ||
| 57 | |||
| 58 | static int samsung_pd_runtime_resume(struct device *dev) | ||
| 59 | { | ||
| 60 | struct samsung_pd_info *pdata = dev->platform_data; | ||
| 61 | int ret = 0; | ||
| 62 | |||
| 63 | if (pdata->enable) | ||
| 64 | ret = pdata->enable(dev); | ||
| 65 | |||
| 66 | dev_dbg(dev, "resumed\n"); | ||
| 67 | return ret; | ||
| 68 | } | ||
| 69 | |||
| 70 | static const struct dev_pm_ops samsung_pd_pm_ops = { | ||
| 71 | .runtime_suspend = samsung_pd_runtime_suspend, | ||
| 72 | .runtime_resume = samsung_pd_runtime_resume, | ||
| 73 | }; | ||
| 74 | |||
| 75 | static struct platform_driver samsung_pd_driver = { | ||
| 76 | .driver = { | ||
| 77 | .name = "samsung-pd", | ||
| 78 | .owner = THIS_MODULE, | ||
| 79 | .pm = &samsung_pd_pm_ops, | ||
| 80 | }, | ||
| 81 | .probe = samsung_pd_probe, | ||
| 82 | .remove = __devexit_p(samsung_pd_remove), | ||
| 83 | }; | ||
| 84 | |||
| 85 | static int __init samsung_pd_init(void) | ||
| 86 | { | ||
| 87 | int ret; | ||
| 88 | |||
| 89 | ret = platform_driver_register(&samsung_pd_driver); | ||
| 90 | if (ret) | ||
| 91 | printk(KERN_ERR "%s: failed to add PD driver\n", __func__); | ||
| 92 | |||
| 93 | return ret; | ||
| 94 | } | ||
| 95 | arch_initcall(samsung_pd_init); | ||
diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c new file mode 100644 index 00000000000..f37457c5206 --- /dev/null +++ b/arch/arm/plat-samsung/pwm.c | |||
| @@ -0,0 +1,413 @@ | |||
| 1 | /* arch/arm/plat-s3c/pwm.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2007 Ben Dooks | ||
| 4 | * Copyright (c) 2008 Simtec Electronics | ||
| 5 | * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org> | ||
| 6 | * | ||
| 7 | * S3C series PWM device core | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <linux/slab.h> | ||
| 18 | #include <linux/err.h> | ||
| 19 | #include <linux/clk.h> | ||
| 20 | #include <linux/io.h> | ||
| 21 | #include <linux/pwm.h> | ||
| 22 | |||
| 23 | #include <mach/map.h> | ||
| 24 | |||
| 25 | #include <plat/regs-timer.h> | ||
| 26 | |||
| 27 | struct pwm_device { | ||
| 28 | struct list_head list; | ||
| 29 | struct platform_device *pdev; | ||
| 30 | |||
| 31 | struct clk *clk_div; | ||
| 32 | struct clk *clk; | ||
| 33 | const char *label; | ||
| 34 | |||
| 35 | unsigned int period_ns; | ||
| 36 | unsigned int duty_ns; | ||
| 37 | |||
| 38 | unsigned char tcon_base; | ||
| 39 | unsigned char running; | ||
| 40 | unsigned char use_count; | ||
| 41 | unsigned char pwm_id; | ||
| 42 | }; | ||
| 43 | |||
| 44 | #define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg) | ||
| 45 | |||
| 46 | static struct clk *clk_scaler[2]; | ||
| 47 | |||
| 48 | static inline int pwm_is_tdiv(struct pwm_device *pwm) | ||
| 49 | { | ||
| 50 | return clk_get_parent(pwm->clk) == pwm->clk_div; | ||
| 51 | } | ||
| 52 | |||
| 53 | static DEFINE_MUTEX(pwm_lock); | ||
| 54 | static LIST_HEAD(pwm_list); | ||
| 55 | |||
| 56 | struct pwm_device *pwm_request(int pwm_id, const char *label) | ||
| 57 | { | ||
| 58 | struct pwm_device *pwm; | ||
| 59 | int found = 0; | ||
| 60 | |||
| 61 | mutex_lock(&pwm_lock); | ||
| 62 | |||
| 63 | list_for_each_entry(pwm, &pwm_list, list) { | ||
| 64 | if (pwm->pwm_id == pwm_id) { | ||
| 65 | found = 1; | ||
| 66 | break; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | if (found) { | ||
| 71 | if (pwm->use_count == 0) { | ||
| 72 | pwm->use_count = 1; | ||
| 73 | pwm->label = label; | ||
| 74 | } else | ||
| 75 | pwm = ERR_PTR(-EBUSY); | ||
| 76 | } else | ||
| 77 | pwm = ERR_PTR(-ENOENT); | ||
| 78 | |||
| 79 | mutex_unlock(&pwm_lock); | ||
| 80 | return pwm; | ||
| 81 | } | ||
| 82 | |||
| 83 | EXPORT_SYMBOL(pwm_request); | ||
| 84 | |||
| 85 | |||
| 86 | void pwm_free(struct pwm_device *pwm) | ||
| 87 | { | ||
| 88 | mutex_lock(&pwm_lock); | ||
| 89 | |||
| 90 | if (pwm->use_count) { | ||
| 91 | pwm->use_count--; | ||
| 92 | pwm->label = NULL; | ||
| 93 | } else | ||
| 94 | printk(KERN_ERR "PWM%d device already freed\n", pwm->pwm_id); | ||
| 95 | |||
| 96 | mutex_unlock(&pwm_lock); | ||
| 97 | } | ||
| 98 | |||
| 99 | EXPORT_SYMBOL(pwm_free); | ||
| 100 | |||
| 101 | #define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0)) | ||
| 102 | #define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2)) | ||
| 103 | #define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3)) | ||
| 104 | #define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1)) | ||
| 105 | |||
| 106 | int pwm_enable(struct pwm_device *pwm) | ||
| 107 | { | ||
| 108 | unsigned long flags; | ||
| 109 | unsigned long tcon; | ||
| 110 | |||
| 111 | local_irq_save(flags); | ||
| 112 | |||
| 113 | tcon = __raw_readl(S3C2410_TCON); | ||
| 114 | tcon |= pwm_tcon_start(pwm); | ||
| 115 | __raw_writel(tcon, S3C2410_TCON); | ||
| 116 | |||
| 117 | local_irq_restore(flags); | ||
| 118 | |||
| 119 | pwm->running = 1; | ||
| 120 | return 0; | ||
| 121 | } | ||
| 122 | |||
| 123 | EXPORT_SYMBOL(pwm_enable); | ||
| 124 | |||
| 125 | void pwm_disable(struct pwm_device *pwm) | ||
| 126 | { | ||
| 127 | unsigned long flags; | ||
| 128 | unsigned long tcon; | ||
| 129 | |||
| 130 | local_irq_save(flags); | ||
| 131 | |||
| 132 | tcon = __raw_readl(S3C2410_TCON); | ||
| 133 | tcon &= ~pwm_tcon_start(pwm); | ||
| 134 | __raw_writel(tcon, S3C2410_TCON); | ||
| 135 | |||
| 136 | local_irq_restore(flags); | ||
| 137 | |||
| 138 | pwm->running = 0; | ||
| 139 | } | ||
| 140 | |||
| 141 | EXPORT_SYMBOL(pwm_disable); | ||
| 142 | |||
| 143 | static unsigned long pwm_calc_tin(struct pwm_device *pwm, unsigned long freq) | ||
| 144 | { | ||
| 145 | unsigned long tin_parent_rate; | ||
| 146 | unsigned int div; | ||
| 147 | |||
| 148 | tin_parent_rate = clk_get_rate(clk_get_parent(pwm->clk_div)); | ||
| 149 | pwm_dbg(pwm, "tin parent at %lu\n", tin_parent_rate); | ||
| 150 | |||
| 151 | for (div = 2; div <= 16; div *= 2) { | ||
| 152 | if ((tin_parent_rate / (div << 16)) < freq) | ||
| 153 | return tin_parent_rate / div; | ||
| 154 | } | ||
| 155 | |||
| 156 | return tin_parent_rate / 16; | ||
| 157 | } | ||
| 158 | |||
| 159 | #define NS_IN_HZ (1000000000UL) | ||
| 160 | |||
| 161 | int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) | ||
| 162 | { | ||
| 163 | unsigned long tin_rate; | ||
| 164 | unsigned long tin_ns; | ||
| 165 | unsigned long period; | ||
| 166 | unsigned long flags; | ||
| 167 | unsigned long tcon; | ||
| 168 | unsigned long tcnt; | ||
| 169 | long tcmp; | ||
| 170 | |||
| 171 | /* We currently avoid using 64bit arithmetic by using the | ||
| 172 | * fact that anything faster than 1Hz is easily representable | ||
| 173 | * by 32bits. */ | ||
| 174 | |||
| 175 | if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ) | ||
| 176 | return -ERANGE; | ||
| 177 | |||
| 178 | if (duty_ns > period_ns) | ||
| 179 | return -EINVAL; | ||
| 180 | |||
| 181 | if (period_ns == pwm->period_ns && | ||
| 182 | duty_ns == pwm->duty_ns) | ||
| 183 | return 0; | ||
| 184 | |||
| 185 | /* The TCMP and TCNT can be read without a lock, they're not | ||
| 186 | * shared between the timers. */ | ||
| 187 | |||
| 188 | tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id)); | ||
| 189 | tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id)); | ||
| 190 | |||
| 191 | period = NS_IN_HZ / period_ns; | ||
| 192 | |||
| 193 | pwm_dbg(pwm, "duty_ns=%d, period_ns=%d (%lu)\n", | ||
| 194 | duty_ns, period_ns, period); | ||
| 195 | |||
| 196 | /* Check to see if we are changing the clock rate of the PWM */ | ||
| 197 | |||
| 198 | if (pwm->period_ns != period_ns) { | ||
| 199 | if (pwm_is_tdiv(pwm)) { | ||
| 200 | tin_rate = pwm_calc_tin(pwm, period); | ||
| 201 | clk_set_rate(pwm->clk_div, tin_rate); | ||
| 202 | } else | ||
| 203 | tin_rate = clk_get_rate(pwm->clk); | ||
| 204 | |||
| 205 | pwm->period_ns = period_ns; | ||
| 206 | |||
| 207 | pwm_dbg(pwm, "tin_rate=%lu\n", tin_rate); | ||
| 208 | |||
| 209 | tin_ns = NS_IN_HZ / tin_rate; | ||
| 210 | tcnt = period_ns / tin_ns; | ||
| 211 | } else | ||
| 212 | tin_ns = NS_IN_HZ / clk_get_rate(pwm->clk); | ||
| 213 | |||
| 214 | /* Note, counters count down */ | ||
| 215 | |||
| 216 | tcmp = duty_ns / tin_ns; | ||
| 217 | tcmp = tcnt - tcmp; | ||
| 218 | /* the pwm hw only checks the compare register after a decrement, | ||
| 219 | so the pin never toggles if tcmp = tcnt */ | ||
| 220 | if (tcmp == tcnt) | ||
| 221 | tcmp--; | ||
| 222 | |||
| 223 | pwm_dbg(pwm, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt); | ||
| 224 | |||
| 225 | if (tcmp < 0) | ||
| 226 | tcmp = 0; | ||
| 227 | |||
| 228 | /* Update the PWM register block. */ | ||
| 229 | |||
| 230 | local_irq_save(flags); | ||
| 231 | |||
| 232 | __raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id)); | ||
| 233 | __raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id)); | ||
| 234 | |||
| 235 | tcon = __raw_readl(S3C2410_TCON); | ||
| 236 | tcon |= pwm_tcon_manulupdate(pwm); | ||
| 237 | tcon |= pwm_tcon_autoreload(pwm); | ||
| 238 | __raw_writel(tcon, S3C2410_TCON); | ||
| 239 | |||
| 240 | tcon &= ~pwm_tcon_manulupdate(pwm); | ||
| 241 | __raw_writel(tcon, S3C2410_TCON); | ||
| 242 | |||
| 243 | local_irq_restore(flags); | ||
| 244 | |||
| 245 | return 0; | ||
| 246 | } | ||
| 247 | |||
| 248 | EXPORT_SYMBOL(pwm_config); | ||
| 249 | |||
| 250 | static int pwm_register(struct pwm_device *pwm) | ||
| 251 | { | ||
| 252 | pwm->duty_ns = -1; | ||
| 253 | pwm->period_ns = -1; | ||
| 254 | |||
| 255 | mutex_lock(&pwm_lock); | ||
| 256 | list_add_tail(&pwm->list, &pwm_list); | ||
| 257 | mutex_unlock(&pwm_lock); | ||
| 258 | |||
| 259 | return 0; | ||
| 260 | } | ||
| 261 | |||
| 262 | static int s3c_pwm_probe(struct platform_device *pdev) | ||
| 263 | { | ||
| 264 | struct device *dev = &pdev->dev; | ||
| 265 | struct pwm_device *pwm; | ||
| 266 | unsigned long flags; | ||
| 267 | unsigned long tcon; | ||
| 268 | unsigned int id = pdev->id; | ||
| 269 | int ret; | ||
| 270 | |||
| 271 | if (id == 4) { | ||
| 272 | dev_err(dev, "TIMER4 is currently not supported\n"); | ||
| 273 | return -ENXIO; | ||
| 274 | } | ||
| 275 | |||
| 276 | pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); | ||
| 277 | if (pwm == NULL) { | ||
| 278 | dev_err(dev, "failed to allocate pwm_device\n"); | ||
| 279 | return -ENOMEM; | ||
| 280 | } | ||
| 281 | |||
| 282 | pwm->pdev = pdev; | ||
| 283 | pwm->pwm_id = id; | ||
| 284 | |||
| 285 | /* calculate base of control bits in TCON */ | ||
| 286 | pwm->tcon_base = id == 0 ? 0 : (id * 4) + 4; | ||
| 287 | |||
| 288 | pwm->clk = clk_get(dev, "pwm-tin"); | ||
| 289 | if (IS_ERR(pwm->clk)) { | ||
| 290 | dev_err(dev, "failed to get pwm tin clk\n"); | ||
| 291 | ret = PTR_ERR(pwm->clk); | ||
| 292 | goto err_alloc; | ||
| 293 | } | ||
| 294 | |||
| 295 | pwm->clk_div = clk_get(dev, "pwm-tdiv"); | ||
| 296 | if (IS_ERR(pwm->clk_div)) { | ||
| 297 | dev_err(dev, "failed to get pwm tdiv clk\n"); | ||
| 298 | ret = PTR_ERR(pwm->clk_div); | ||
| 299 | goto err_clk_tin; | ||
| 300 | } | ||
| 301 | |||
| 302 | local_irq_save(flags); | ||
| 303 | |||
| 304 | tcon = __raw_readl(S3C2410_TCON); | ||
| 305 | tcon |= pwm_tcon_invert(pwm); | ||
| 306 | __raw_writel(tcon, S3C2410_TCON); | ||
| 307 | |||
| 308 | local_irq_restore(flags); | ||
| 309 | |||
| 310 | |||
| 311 | ret = pwm_register(pwm); | ||
| 312 | if (ret) { | ||
| 313 | dev_err(dev, "failed to register pwm\n"); | ||
| 314 | goto err_clk_tdiv; | ||
| 315 | } | ||
| 316 | |||
| 317 | pwm_dbg(pwm, "config bits %02x\n", | ||
| 318 | (__raw_readl(S3C2410_TCON) >> pwm->tcon_base) & 0x0f); | ||
| 319 | |||
| 320 | dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n", | ||
| 321 | clk_get_rate(pwm->clk), | ||
| 322 | clk_get_rate(pwm->clk_div), | ||
| 323 | pwm_is_tdiv(pwm) ? "div" : "ext", pwm->tcon_base); | ||
| 324 | |||
| 325 | platform_set_drvdata(pdev, pwm); | ||
| 326 | return 0; | ||
| 327 | |||
| 328 | err_clk_tdiv: | ||
| 329 | clk_put(pwm->clk_div); | ||
| 330 | |||
| 331 | err_clk_tin: | ||
| 332 | clk_put(pwm->clk); | ||
| 333 | |||
| 334 | err_alloc: | ||
| 335 | kfree(pwm); | ||
| 336 | return ret; | ||
| 337 | } | ||
| 338 | |||
| 339 | static int __devexit s3c_pwm_remove(struct platform_device *pdev) | ||
| 340 | { | ||
| 341 | struct pwm_device *pwm = platform_get_drvdata(pdev); | ||
| 342 | |||
| 343 | clk_put(pwm->clk_div); | ||
| 344 | clk_put(pwm->clk); | ||
| 345 | kfree(pwm); | ||
| 346 | |||
| 347 | return 0; | ||
| 348 | } | ||
| 349 | |||
| 350 | #ifdef CONFIG_PM | ||
| 351 | static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state) | ||
| 352 | { | ||
| 353 | struct pwm_device *pwm = platform_get_drvdata(pdev); | ||
| 354 | |||
| 355 | /* No one preserve these values during suspend so reset them | ||
| 356 | * Otherwise driver leaves PWM unconfigured if same values | ||
| 357 | * passed to pwm_config | ||
| 358 | */ | ||
| 359 | pwm->period_ns = 0; | ||
| 360 | pwm->duty_ns = 0; | ||
| 361 | |||
| 362 | return 0; | ||
| 363 | } | ||
| 364 | |||
| 365 | static int s3c_pwm_resume(struct platform_device *pdev) | ||
| 366 | { | ||
| 367 | struct pwm_device *pwm = platform_get_drvdata(pdev); | ||
| 368 | unsigned long tcon; | ||
| 369 | |||
| 370 | /* Restore invertion */ | ||
| 371 | tcon = __raw_readl(S3C2410_TCON); | ||
| 372 | tcon |= pwm_tcon_invert(pwm); | ||
| 373 | __raw_writel(tcon, S3C2410_TCON); | ||
| 374 | |||
| 375 | return 0; | ||
| 376 | } | ||
| 377 | |||
| 378 | #else | ||
| 379 | #define s3c_pwm_suspend NULL | ||
| 380 | #define s3c_pwm_resume NULL | ||
| 381 | #endif | ||
| 382 | |||
| 383 | static struct platform_driver s3c_pwm_driver = { | ||
| 384 | .driver = { | ||
| 385 | .name = "s3c24xx-pwm", | ||
| 386 | .owner = THIS_MODULE, | ||
| 387 | }, | ||
| 388 | .probe = s3c_pwm_probe, | ||
| 389 | .remove = __devexit_p(s3c_pwm_remove), | ||
| 390 | .suspend = s3c_pwm_suspend, | ||
| 391 | .resume = s3c_pwm_resume, | ||
| 392 | }; | ||
| 393 | |||
| 394 | static int __init pwm_init(void) | ||
| 395 | { | ||
| 396 | int ret; | ||
| 397 | |||
| 398 | clk_scaler[0] = clk_get(NULL, "pwm-scaler0"); | ||
| 399 | clk_scaler[1] = clk_get(NULL, "pwm-scaler1"); | ||
| 400 | |||
| 401 | if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) { | ||
| 402 | printk(KERN_ERR "%s: failed to get scaler clocks\n", __func__); | ||
| 403 | return -EINVAL; | ||
| 404 | } | ||
| 405 | |||
| 406 | ret = platform_driver_register(&s3c_pwm_driver); | ||
| 407 | if (ret) | ||
| 408 | printk(KERN_ERR "%s: failed to add pwm driver\n", __func__); | ||
| 409 | |||
| 410 | return ret; | ||
| 411 | } | ||
| 412 | |||
| 413 | arch_initcall(pwm_init); | ||
diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c new file mode 100644 index 00000000000..f85638c6f5a --- /dev/null +++ b/arch/arm/plat-samsung/s3c-pl330.c | |||
| @@ -0,0 +1,1244 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/s3c-pl330.c | ||
| 2 | * | ||
| 3 | * Copyright (C) 2010 Samsung Electronics Co. Ltd. | ||
| 4 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/interrupt.h> | ||
| 15 | #include <linux/io.h> | ||
| 16 | #include <linux/slab.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | #include <linux/clk.h> | ||
| 19 | #include <linux/err.h> | ||
| 20 | |||
| 21 | #include <asm/hardware/pl330.h> | ||
| 22 | |||
| 23 | #include <plat/s3c-pl330-pdata.h> | ||
| 24 | |||
| 25 | /** | ||
| 26 | * struct s3c_pl330_dmac - Logical representation of a PL330 DMAC. | ||
| 27 | * @busy_chan: Number of channels currently busy. | ||
| 28 | * @peri: List of IDs of peripherals this DMAC can work with. | ||
| 29 | * @node: To attach to the global list of DMACs. | ||
| 30 | * @pi: PL330 configuration info for the DMAC. | ||
| 31 | * @kmcache: Pool to quickly allocate xfers for all channels in the dmac. | ||
| 32 | * @clk: Pointer of DMAC operation clock. | ||
| 33 | */ | ||
| 34 | struct s3c_pl330_dmac { | ||
| 35 | unsigned busy_chan; | ||
| 36 | enum dma_ch *peri; | ||
| 37 | struct list_head node; | ||
| 38 | struct pl330_info *pi; | ||
| 39 | struct kmem_cache *kmcache; | ||
| 40 | struct clk *clk; | ||
| 41 | }; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * struct s3c_pl330_xfer - A request submitted by S3C DMA clients. | ||
| 45 | * @token: Xfer ID provided by the client. | ||
| 46 | * @node: To attach to the list of xfers on a channel. | ||
| 47 | * @px: Xfer for PL330 core. | ||
| 48 | * @chan: Owner channel of this xfer. | ||
| 49 | */ | ||
| 50 | struct s3c_pl330_xfer { | ||
| 51 | void *token; | ||
| 52 | struct list_head node; | ||
| 53 | struct pl330_xfer px; | ||
| 54 | struct s3c_pl330_chan *chan; | ||
| 55 | }; | ||
| 56 | |||
| 57 | /** | ||
| 58 | * struct s3c_pl330_chan - Logical channel to communicate with | ||
| 59 | * a Physical peripheral. | ||
| 60 | * @pl330_chan_id: Token of a hardware channel thread of PL330 DMAC. | ||
| 61 | * NULL if the channel is available to be acquired. | ||
| 62 | * @id: ID of the peripheral that this channel can communicate with. | ||
| 63 | * @options: Options specified by the client. | ||
| 64 | * @sdaddr: Address provided via s3c2410_dma_devconfig. | ||
| 65 | * @node: To attach to the global list of channels. | ||
| 66 | * @lrq: Pointer to the last submitted pl330_req to PL330 core. | ||
| 67 | * @xfer_list: To manage list of xfers enqueued. | ||
| 68 | * @req: Two requests to communicate with the PL330 engine. | ||
| 69 | * @callback_fn: Callback function to the client. | ||
| 70 | * @rqcfg: Channel configuration for the xfers. | ||
| 71 | * @xfer_head: Pointer to the xfer to be next executed. | ||
| 72 | * @dmac: Pointer to the DMAC that manages this channel, NULL if the | ||
| 73 | * channel is available to be acquired. | ||
| 74 | * @client: Client of this channel. NULL if the | ||
| 75 | * channel is available to be acquired. | ||
| 76 | */ | ||
| 77 | struct s3c_pl330_chan { | ||
| 78 | void *pl330_chan_id; | ||
| 79 | enum dma_ch id; | ||
| 80 | unsigned int options; | ||
| 81 | unsigned long sdaddr; | ||
| 82 | struct list_head node; | ||
| 83 | struct pl330_req *lrq; | ||
| 84 | struct list_head xfer_list; | ||
| 85 | struct pl330_req req[2]; | ||
| 86 | s3c2410_dma_cbfn_t callback_fn; | ||
| 87 | struct pl330_reqcfg rqcfg; | ||
| 88 | struct s3c_pl330_xfer *xfer_head; | ||
| 89 | struct s3c_pl330_dmac *dmac; | ||
| 90 | struct s3c2410_dma_client *client; | ||
| 91 | }; | ||
| 92 | |||
| 93 | /* All DMACs in the platform */ | ||
| 94 | static LIST_HEAD(dmac_list); | ||
| 95 | |||
| 96 | /* All channels to peripherals in the platform */ | ||
| 97 | static LIST_HEAD(chan_list); | ||
| 98 | |||
| 99 | /* | ||
| 100 | * Since we add resources(DMACs and Channels) to the global pool, | ||
| 101 | * we need to guard access to the resources using a global lock | ||
| 102 | */ | ||
| 103 | static DEFINE_SPINLOCK(res_lock); | ||
| 104 | |||
| 105 | /* Returns the channel with ID 'id' in the chan_list */ | ||
| 106 | static struct s3c_pl330_chan *id_to_chan(const enum dma_ch id) | ||
| 107 | { | ||
| 108 | struct s3c_pl330_chan *ch; | ||
| 109 | |||
| 110 | list_for_each_entry(ch, &chan_list, node) | ||
| 111 | if (ch->id == id) | ||
| 112 | return ch; | ||
| 113 | |||
| 114 | return NULL; | ||
| 115 | } | ||
| 116 | |||
| 117 | /* Allocate a new channel with ID 'id' and add to chan_list */ | ||
| 118 | static void chan_add(const enum dma_ch id) | ||
| 119 | { | ||
| 120 | struct s3c_pl330_chan *ch = id_to_chan(id); | ||
| 121 | |||
| 122 | /* Return if the channel already exists */ | ||
| 123 | if (ch) | ||
| 124 | return; | ||
| 125 | |||
| 126 | ch = kmalloc(sizeof(*ch), GFP_KERNEL); | ||
| 127 | /* Return silently to work with other channels */ | ||
| 128 | if (!ch) | ||
| 129 | return; | ||
| 130 | |||
| 131 | ch->id = id; | ||
| 132 | ch->dmac = NULL; | ||
| 133 | |||
| 134 | list_add_tail(&ch->node, &chan_list); | ||
| 135 | } | ||
| 136 | |||
| 137 | /* If the channel is not yet acquired by any client */ | ||
| 138 | static bool chan_free(struct s3c_pl330_chan *ch) | ||
| 139 | { | ||
| 140 | if (!ch) | ||
| 141 | return false; | ||
| 142 | |||
| 143 | /* Channel points to some DMAC only when it's acquired */ | ||
| 144 | return ch->dmac ? false : true; | ||
| 145 | } | ||
| 146 | |||
| 147 | /* | ||
| 148 | * Returns 0 is peripheral i/f is invalid or not present on the dmac. | ||
| 149 | * Index + 1, otherwise. | ||
| 150 | */ | ||
| 151 | static unsigned iface_of_dmac(struct s3c_pl330_dmac *dmac, enum dma_ch ch_id) | ||
| 152 | { | ||
| 153 | enum dma_ch *id = dmac->peri; | ||
| 154 | int i; | ||
| 155 | |||
| 156 | /* Discount invalid markers */ | ||
| 157 | if (ch_id == DMACH_MAX) | ||
| 158 | return 0; | ||
| 159 | |||
| 160 | for (i = 0; i < PL330_MAX_PERI; i++) | ||
| 161 | if (id[i] == ch_id) | ||
| 162 | return i + 1; | ||
| 163 | |||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | |||
| 167 | /* If all channel threads of the DMAC are busy */ | ||
| 168 | static inline bool dmac_busy(struct s3c_pl330_dmac *dmac) | ||
| 169 | { | ||
| 170 | struct pl330_info *pi = dmac->pi; | ||
| 171 | |||
| 172 | return (dmac->busy_chan < pi->pcfg.num_chan) ? false : true; | ||
| 173 | } | ||
| 174 | |||
| 175 | /* | ||
| 176 | * Returns the number of free channels that | ||
| 177 | * can be handled by this dmac only. | ||
| 178 | */ | ||
| 179 | static unsigned ch_onlyby_dmac(struct s3c_pl330_dmac *dmac) | ||
| 180 | { | ||
| 181 | enum dma_ch *id = dmac->peri; | ||
| 182 | struct s3c_pl330_dmac *d; | ||
| 183 | struct s3c_pl330_chan *ch; | ||
| 184 | unsigned found, count = 0; | ||
| 185 | enum dma_ch p; | ||
| 186 | int i; | ||
| 187 | |||
| 188 | for (i = 0; i < PL330_MAX_PERI; i++) { | ||
| 189 | p = id[i]; | ||
| 190 | ch = id_to_chan(p); | ||
| 191 | |||
| 192 | if (p == DMACH_MAX || !chan_free(ch)) | ||
| 193 | continue; | ||
| 194 | |||
| 195 | found = 0; | ||
| 196 | list_for_each_entry(d, &dmac_list, node) { | ||
| 197 | if (d != dmac && iface_of_dmac(d, ch->id)) { | ||
| 198 | found = 1; | ||
| 199 | break; | ||
| 200 | } | ||
| 201 | } | ||
| 202 | if (!found) | ||
| 203 | count++; | ||
| 204 | } | ||
| 205 | |||
| 206 | return count; | ||
| 207 | } | ||
| 208 | |||
| 209 | /* | ||
| 210 | * Measure of suitability of 'dmac' handling 'ch' | ||
| 211 | * | ||
| 212 | * 0 indicates 'dmac' can not handle 'ch' either | ||
| 213 | * because it is not supported by the hardware or | ||
| 214 | * because all dmac channels are currently busy. | ||
| 215 | * | ||
| 216 | * >0 vlaue indicates 'dmac' has the capability. | ||
| 217 | * The bigger the value the more suitable the dmac. | ||
| 218 | */ | ||
| 219 | #define MAX_SUIT UINT_MAX | ||
| 220 | #define MIN_SUIT 0 | ||
| 221 | |||
| 222 | static unsigned suitablility(struct s3c_pl330_dmac *dmac, | ||
| 223 | struct s3c_pl330_chan *ch) | ||
| 224 | { | ||
| 225 | struct pl330_info *pi = dmac->pi; | ||
| 226 | enum dma_ch *id = dmac->peri; | ||
| 227 | struct s3c_pl330_dmac *d; | ||
| 228 | unsigned s; | ||
| 229 | int i; | ||
| 230 | |||
| 231 | s = MIN_SUIT; | ||
| 232 | /* If all the DMAC channel threads are busy */ | ||
| 233 | if (dmac_busy(dmac)) | ||
| 234 | return s; | ||
| 235 | |||
| 236 | for (i = 0; i < PL330_MAX_PERI; i++) | ||
| 237 | if (id[i] == ch->id) | ||
| 238 | break; | ||
| 239 | |||
| 240 | /* If the 'dmac' can't talk to 'ch' */ | ||
| 241 | if (i == PL330_MAX_PERI) | ||
| 242 | return s; | ||
| 243 | |||
| 244 | s = MAX_SUIT; | ||
| 245 | list_for_each_entry(d, &dmac_list, node) { | ||
| 246 | /* | ||
| 247 | * If some other dmac can talk to this | ||
| 248 | * peri and has some channel free. | ||
| 249 | */ | ||
| 250 | if (d != dmac && iface_of_dmac(d, ch->id) && !dmac_busy(d)) { | ||
| 251 | s = 0; | ||
| 252 | break; | ||
| 253 | } | ||
| 254 | } | ||
| 255 | if (s) | ||
| 256 | return s; | ||
| 257 | |||
| 258 | s = 100; | ||
| 259 | |||
| 260 | /* Good if free chans are more, bad otherwise */ | ||
| 261 | s += (pi->pcfg.num_chan - dmac->busy_chan) - ch_onlyby_dmac(dmac); | ||
| 262 | |||
| 263 | return s; | ||
| 264 | } | ||
| 265 | |||
| 266 | /* More than one DMAC may have capability to transfer data with the | ||
| 267 | * peripheral. This function assigns most suitable DMAC to manage the | ||
| 268 | * channel and hence communicate with the peripheral. | ||
| 269 | */ | ||
| 270 | static struct s3c_pl330_dmac *map_chan_to_dmac(struct s3c_pl330_chan *ch) | ||
| 271 | { | ||
| 272 | struct s3c_pl330_dmac *d, *dmac = NULL; | ||
| 273 | unsigned sn, sl = MIN_SUIT; | ||
| 274 | |||
| 275 | list_for_each_entry(d, &dmac_list, node) { | ||
| 276 | sn = suitablility(d, ch); | ||
| 277 | |||
| 278 | if (sn == MAX_SUIT) | ||
| 279 | return d; | ||
| 280 | |||
| 281 | if (sn > sl) | ||
| 282 | dmac = d; | ||
| 283 | } | ||
| 284 | |||
| 285 | return dmac; | ||
| 286 | } | ||
| 287 | |||
| 288 | /* Acquire the channel for peripheral 'id' */ | ||
| 289 | static struct s3c_pl330_chan *chan_acquire(const enum dma_ch id) | ||
| 290 | { | ||
| 291 | struct s3c_pl330_chan *ch = id_to_chan(id); | ||
| 292 | struct s3c_pl330_dmac *dmac; | ||
| 293 | |||
| 294 | /* If the channel doesn't exist or is already acquired */ | ||
| 295 | if (!ch || !chan_free(ch)) { | ||
| 296 | ch = NULL; | ||
| 297 | goto acq_exit; | ||
| 298 | } | ||
| 299 | |||
| 300 | dmac = map_chan_to_dmac(ch); | ||
| 301 | /* If couldn't map */ | ||
| 302 | if (!dmac) { | ||
| 303 | ch = NULL; | ||
| 304 | goto acq_exit; | ||
| 305 | } | ||
| 306 | |||
| 307 | dmac->busy_chan++; | ||
| 308 | ch->dmac = dmac; | ||
| 309 | |||
| 310 | acq_exit: | ||
| 311 | return ch; | ||
| 312 | } | ||
| 313 | |||
| 314 | /* Delete xfer from the queue */ | ||
| 315 | static inline void del_from_queue(struct s3c_pl330_xfer *xfer) | ||
| 316 | { | ||
| 317 | struct s3c_pl330_xfer *t; | ||
| 318 | struct s3c_pl330_chan *ch; | ||
| 319 | int found; | ||
| 320 | |||
| 321 | if (!xfer) | ||
| 322 | return; | ||
| 323 | |||
| 324 | ch = xfer->chan; | ||
| 325 | |||
| 326 | /* Make sure xfer is in the queue */ | ||
| 327 | found = 0; | ||
| 328 | list_for_each_entry(t, &ch->xfer_list, node) | ||
| 329 | if (t == xfer) { | ||
| 330 | found = 1; | ||
| 331 | break; | ||
| 332 | } | ||
| 333 | |||
| 334 | if (!found) | ||
| 335 | return; | ||
| 336 | |||
| 337 | /* If xfer is last entry in the queue */ | ||
| 338 | if (xfer->node.next == &ch->xfer_list) | ||
| 339 | t = list_entry(ch->xfer_list.next, | ||
| 340 | struct s3c_pl330_xfer, node); | ||
| 341 | else | ||
| 342 | t = list_entry(xfer->node.next, | ||
| 343 | struct s3c_pl330_xfer, node); | ||
| 344 | |||
| 345 | /* If there was only one node left */ | ||
| 346 | if (t == xfer) | ||
| 347 | ch->xfer_head = NULL; | ||
| 348 | else if (ch->xfer_head == xfer) | ||
| 349 | ch->xfer_head = t; | ||
| 350 | |||
| 351 | list_del(&xfer->node); | ||
| 352 | } | ||
| 353 | |||
| 354 | /* Provides pointer to the next xfer in the queue. | ||
| 355 | * If CIRCULAR option is set, the list is left intact, | ||
| 356 | * otherwise the xfer is removed from the list. | ||
| 357 | * Forced delete 'pluck' can be set to override the CIRCULAR option. | ||
| 358 | */ | ||
| 359 | static struct s3c_pl330_xfer *get_from_queue(struct s3c_pl330_chan *ch, | ||
| 360 | int pluck) | ||
| 361 | { | ||
| 362 | struct s3c_pl330_xfer *xfer = ch->xfer_head; | ||
| 363 | |||
| 364 | if (!xfer) | ||
| 365 | return NULL; | ||
| 366 | |||
| 367 | /* If xfer is last entry in the queue */ | ||
| 368 | if (xfer->node.next == &ch->xfer_list) | ||
| 369 | ch->xfer_head = list_entry(ch->xfer_list.next, | ||
| 370 | struct s3c_pl330_xfer, node); | ||
| 371 | else | ||
| 372 | ch->xfer_head = list_entry(xfer->node.next, | ||
| 373 | struct s3c_pl330_xfer, node); | ||
| 374 | |||
| 375 | if (pluck || !(ch->options & S3C2410_DMAF_CIRCULAR)) | ||
| 376 | del_from_queue(xfer); | ||
| 377 | |||
| 378 | return xfer; | ||
| 379 | } | ||
| 380 | |||
| 381 | static inline void add_to_queue(struct s3c_pl330_chan *ch, | ||
| 382 | struct s3c_pl330_xfer *xfer, int front) | ||
| 383 | { | ||
| 384 | struct pl330_xfer *xt; | ||
| 385 | |||
| 386 | /* If queue empty */ | ||
| 387 | if (ch->xfer_head == NULL) | ||
| 388 | ch->xfer_head = xfer; | ||
| 389 | |||
| 390 | xt = &ch->xfer_head->px; | ||
| 391 | /* If the head already submitted (CIRCULAR head) */ | ||
| 392 | if (ch->options & S3C2410_DMAF_CIRCULAR && | ||
| 393 | (xt == ch->req[0].x || xt == ch->req[1].x)) | ||
| 394 | ch->xfer_head = xfer; | ||
| 395 | |||
| 396 | /* If this is a resubmission, it should go at the head */ | ||
| 397 | if (front) { | ||
| 398 | ch->xfer_head = xfer; | ||
| 399 | list_add(&xfer->node, &ch->xfer_list); | ||
| 400 | } else { | ||
| 401 | list_add_tail(&xfer->node, &ch->xfer_list); | ||
| 402 | } | ||
| 403 | } | ||
| 404 | |||
| 405 | static inline void _finish_off(struct s3c_pl330_xfer *xfer, | ||
| 406 | enum s3c2410_dma_buffresult res, int ffree) | ||
| 407 | { | ||
| 408 | struct s3c_pl330_chan *ch; | ||
| 409 | |||
| 410 | if (!xfer) | ||
| 411 | return; | ||
| 412 | |||
| 413 | ch = xfer->chan; | ||
| 414 | |||
| 415 | /* Do callback */ | ||
| 416 | if (ch->callback_fn) | ||
| 417 | ch->callback_fn(NULL, xfer->token, xfer->px.bytes, res); | ||
| 418 | |||
| 419 | /* Force Free or if buffer is not needed anymore */ | ||
| 420 | if (ffree || !(ch->options & S3C2410_DMAF_CIRCULAR)) | ||
| 421 | kmem_cache_free(ch->dmac->kmcache, xfer); | ||
| 422 | } | ||
| 423 | |||
| 424 | static inline int s3c_pl330_submit(struct s3c_pl330_chan *ch, | ||
| 425 | struct pl330_req *r) | ||
| 426 | { | ||
| 427 | struct s3c_pl330_xfer *xfer; | ||
| 428 | int ret = 0; | ||
| 429 | |||
| 430 | /* If already submitted */ | ||
| 431 | if (r->x) | ||
| 432 | return 0; | ||
| 433 | |||
| 434 | xfer = get_from_queue(ch, 0); | ||
| 435 | if (xfer) { | ||
| 436 | r->x = &xfer->px; | ||
| 437 | |||
| 438 | /* Use max bandwidth for M<->M xfers */ | ||
| 439 | if (r->rqtype == MEMTOMEM) { | ||
| 440 | struct pl330_info *pi = xfer->chan->dmac->pi; | ||
| 441 | int burst = 1 << ch->rqcfg.brst_size; | ||
| 442 | u32 bytes = r->x->bytes; | ||
| 443 | int bl; | ||
| 444 | |||
| 445 | bl = pi->pcfg.data_bus_width / 8; | ||
| 446 | bl *= pi->pcfg.data_buf_dep; | ||
| 447 | bl /= burst; | ||
| 448 | |||
| 449 | /* src/dst_burst_len can't be more than 16 */ | ||
| 450 | if (bl > 16) | ||
| 451 | bl = 16; | ||
| 452 | |||
| 453 | while (bl > 1) { | ||
| 454 | if (!(bytes % (bl * burst))) | ||
| 455 | break; | ||
| 456 | bl--; | ||
| 457 | } | ||
| 458 | |||
| 459 | ch->rqcfg.brst_len = bl; | ||
| 460 | } else { | ||
| 461 | ch->rqcfg.brst_len = 1; | ||
| 462 | } | ||
| 463 | |||
| 464 | ret = pl330_submit_req(ch->pl330_chan_id, r); | ||
| 465 | |||
| 466 | /* If submission was successful */ | ||
| 467 | if (!ret) { | ||
| 468 | ch->lrq = r; /* latest submitted req */ | ||
| 469 | return 0; | ||
| 470 | } | ||
| 471 | |||
| 472 | r->x = NULL; | ||
| 473 | |||
| 474 | /* If both of the PL330 ping-pong buffers filled */ | ||
| 475 | if (ret == -EAGAIN) { | ||
| 476 | dev_err(ch->dmac->pi->dev, "%s:%d!\n", | ||
| 477 | __func__, __LINE__); | ||
| 478 | /* Queue back again */ | ||
| 479 | add_to_queue(ch, xfer, 1); | ||
| 480 | ret = 0; | ||
| 481 | } else { | ||
| 482 | dev_err(ch->dmac->pi->dev, "%s:%d!\n", | ||
| 483 | __func__, __LINE__); | ||
| 484 | _finish_off(xfer, S3C2410_RES_ERR, 0); | ||
| 485 | } | ||
| 486 | } | ||
| 487 | |||
| 488 | return ret; | ||
| 489 | } | ||
| 490 | |||
| 491 | static void s3c_pl330_rq(struct s3c_pl330_chan *ch, | ||
| 492 | struct pl330_req *r, enum pl330_op_err err) | ||
| 493 | { | ||
| 494 | unsigned long flags; | ||
| 495 | struct s3c_pl330_xfer *xfer; | ||
| 496 | struct pl330_xfer *xl = r->x; | ||
| 497 | enum s3c2410_dma_buffresult res; | ||
| 498 | |||
| 499 | spin_lock_irqsave(&res_lock, flags); | ||
| 500 | |||
| 501 | r->x = NULL; | ||
| 502 | |||
| 503 | s3c_pl330_submit(ch, r); | ||
| 504 | |||
| 505 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 506 | |||
| 507 | /* Map result to S3C DMA API */ | ||
| 508 | if (err == PL330_ERR_NONE) | ||
| 509 | res = S3C2410_RES_OK; | ||
| 510 | else if (err == PL330_ERR_ABORT) | ||
| 511 | res = S3C2410_RES_ABORT; | ||
| 512 | else | ||
| 513 | res = S3C2410_RES_ERR; | ||
| 514 | |||
| 515 | /* If last request had some xfer */ | ||
| 516 | if (xl) { | ||
| 517 | xfer = container_of(xl, struct s3c_pl330_xfer, px); | ||
| 518 | _finish_off(xfer, res, 0); | ||
| 519 | } else { | ||
| 520 | dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n", | ||
| 521 | __func__, __LINE__); | ||
| 522 | } | ||
| 523 | } | ||
| 524 | |||
| 525 | static void s3c_pl330_rq0(void *token, enum pl330_op_err err) | ||
| 526 | { | ||
| 527 | struct pl330_req *r = token; | ||
| 528 | struct s3c_pl330_chan *ch = container_of(r, | ||
| 529 | struct s3c_pl330_chan, req[0]); | ||
| 530 | s3c_pl330_rq(ch, r, err); | ||
| 531 | } | ||
| 532 | |||
| 533 | static void s3c_pl330_rq1(void *token, enum pl330_op_err err) | ||
| 534 | { | ||
| 535 | struct pl330_req *r = token; | ||
| 536 | struct s3c_pl330_chan *ch = container_of(r, | ||
| 537 | struct s3c_pl330_chan, req[1]); | ||
| 538 | s3c_pl330_rq(ch, r, err); | ||
| 539 | } | ||
| 540 | |||
| 541 | /* Release an acquired channel */ | ||
| 542 | static void chan_release(struct s3c_pl330_chan *ch) | ||
| 543 | { | ||
| 544 | struct s3c_pl330_dmac *dmac; | ||
| 545 | |||
| 546 | if (chan_free(ch)) | ||
| 547 | return; | ||
| 548 | |||
| 549 | dmac = ch->dmac; | ||
| 550 | ch->dmac = NULL; | ||
| 551 | dmac->busy_chan--; | ||
| 552 | } | ||
| 553 | |||
| 554 | int s3c2410_dma_ctrl(enum dma_ch id, enum s3c2410_chan_op op) | ||
| 555 | { | ||
| 556 | struct s3c_pl330_xfer *xfer; | ||
| 557 | enum pl330_chan_op pl330op; | ||
| 558 | struct s3c_pl330_chan *ch; | ||
| 559 | unsigned long flags; | ||
| 560 | int idx, ret; | ||
| 561 | |||
| 562 | spin_lock_irqsave(&res_lock, flags); | ||
| 563 | |||
| 564 | ch = id_to_chan(id); | ||
| 565 | |||
| 566 | if (!ch || chan_free(ch)) { | ||
| 567 | ret = -EINVAL; | ||
| 568 | goto ctrl_exit; | ||
| 569 | } | ||
| 570 | |||
| 571 | switch (op) { | ||
| 572 | case S3C2410_DMAOP_START: | ||
| 573 | /* Make sure both reqs are enqueued */ | ||
| 574 | idx = (ch->lrq == &ch->req[0]) ? 1 : 0; | ||
| 575 | s3c_pl330_submit(ch, &ch->req[idx]); | ||
| 576 | s3c_pl330_submit(ch, &ch->req[1 - idx]); | ||
| 577 | pl330op = PL330_OP_START; | ||
| 578 | break; | ||
| 579 | |||
| 580 | case S3C2410_DMAOP_STOP: | ||
| 581 | pl330op = PL330_OP_ABORT; | ||
| 582 | break; | ||
| 583 | |||
| 584 | case S3C2410_DMAOP_FLUSH: | ||
| 585 | pl330op = PL330_OP_FLUSH; | ||
| 586 | break; | ||
| 587 | |||
| 588 | case S3C2410_DMAOP_PAUSE: | ||
| 589 | case S3C2410_DMAOP_RESUME: | ||
| 590 | case S3C2410_DMAOP_TIMEOUT: | ||
| 591 | case S3C2410_DMAOP_STARTED: | ||
| 592 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 593 | return 0; | ||
| 594 | |||
| 595 | default: | ||
| 596 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 597 | return -EINVAL; | ||
| 598 | } | ||
| 599 | |||
| 600 | ret = pl330_chan_ctrl(ch->pl330_chan_id, pl330op); | ||
| 601 | |||
| 602 | if (pl330op == PL330_OP_START) { | ||
| 603 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 604 | return ret; | ||
| 605 | } | ||
| 606 | |||
| 607 | idx = (ch->lrq == &ch->req[0]) ? 1 : 0; | ||
| 608 | |||
| 609 | /* Abort the current xfer */ | ||
| 610 | if (ch->req[idx].x) { | ||
| 611 | xfer = container_of(ch->req[idx].x, | ||
| 612 | struct s3c_pl330_xfer, px); | ||
| 613 | |||
| 614 | /* Drop xfer during FLUSH */ | ||
| 615 | if (pl330op == PL330_OP_FLUSH) | ||
| 616 | del_from_queue(xfer); | ||
| 617 | |||
| 618 | ch->req[idx].x = NULL; | ||
| 619 | |||
| 620 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 621 | _finish_off(xfer, S3C2410_RES_ABORT, | ||
| 622 | pl330op == PL330_OP_FLUSH ? 1 : 0); | ||
| 623 | spin_lock_irqsave(&res_lock, flags); | ||
| 624 | } | ||
| 625 | |||
| 626 | /* Flush the whole queue */ | ||
| 627 | if (pl330op == PL330_OP_FLUSH) { | ||
| 628 | |||
| 629 | if (ch->req[1 - idx].x) { | ||
| 630 | xfer = container_of(ch->req[1 - idx].x, | ||
| 631 | struct s3c_pl330_xfer, px); | ||
| 632 | |||
| 633 | del_from_queue(xfer); | ||
| 634 | |||
| 635 | ch->req[1 - idx].x = NULL; | ||
| 636 | |||
| 637 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 638 | _finish_off(xfer, S3C2410_RES_ABORT, 1); | ||
| 639 | spin_lock_irqsave(&res_lock, flags); | ||
| 640 | } | ||
| 641 | |||
| 642 | /* Finish off the remaining in the queue */ | ||
| 643 | xfer = ch->xfer_head; | ||
| 644 | while (xfer) { | ||
| 645 | |||
| 646 | del_from_queue(xfer); | ||
| 647 | |||
| 648 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 649 | _finish_off(xfer, S3C2410_RES_ABORT, 1); | ||
| 650 | spin_lock_irqsave(&res_lock, flags); | ||
| 651 | |||
| 652 | xfer = ch->xfer_head; | ||
| 653 | } | ||
| 654 | } | ||
| 655 | |||
| 656 | ctrl_exit: | ||
| 657 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 658 | |||
| 659 | return ret; | ||
| 660 | } | ||
| 661 | EXPORT_SYMBOL(s3c2410_dma_ctrl); | ||
| 662 | |||
| 663 | int s3c2410_dma_enqueue(enum dma_ch id, void *token, | ||
| 664 | dma_addr_t addr, int size) | ||
| 665 | { | ||
| 666 | struct s3c_pl330_chan *ch; | ||
| 667 | struct s3c_pl330_xfer *xfer; | ||
| 668 | unsigned long flags; | ||
| 669 | int idx, ret = 0; | ||
| 670 | |||
| 671 | spin_lock_irqsave(&res_lock, flags); | ||
| 672 | |||
| 673 | ch = id_to_chan(id); | ||
| 674 | |||
| 675 | /* Error if invalid or free channel */ | ||
| 676 | if (!ch || chan_free(ch)) { | ||
| 677 | ret = -EINVAL; | ||
| 678 | goto enq_exit; | ||
| 679 | } | ||
| 680 | |||
| 681 | /* Error if size is unaligned */ | ||
| 682 | if (ch->rqcfg.brst_size && size % (1 << ch->rqcfg.brst_size)) { | ||
| 683 | ret = -EINVAL; | ||
| 684 | goto enq_exit; | ||
| 685 | } | ||
| 686 | |||
| 687 | xfer = kmem_cache_alloc(ch->dmac->kmcache, GFP_ATOMIC); | ||
| 688 | if (!xfer) { | ||
| 689 | ret = -ENOMEM; | ||
| 690 | goto enq_exit; | ||
| 691 | } | ||
| 692 | |||
| 693 | xfer->token = token; | ||
| 694 | xfer->chan = ch; | ||
| 695 | xfer->px.bytes = size; | ||
| 696 | xfer->px.next = NULL; /* Single request */ | ||
| 697 | |||
| 698 | /* For S3C DMA API, direction is always fixed for all xfers */ | ||
| 699 | if (ch->req[0].rqtype == MEMTODEV) { | ||
| 700 | xfer->px.src_addr = addr; | ||
| 701 | xfer->px.dst_addr = ch->sdaddr; | ||
| 702 | } else { | ||
| 703 | xfer->px.src_addr = ch->sdaddr; | ||
| 704 | xfer->px.dst_addr = addr; | ||
| 705 | } | ||
| 706 | |||
| 707 | add_to_queue(ch, xfer, 0); | ||
| 708 | |||
| 709 | /* Try submitting on either request */ | ||
| 710 | idx = (ch->lrq == &ch->req[0]) ? 1 : 0; | ||
| 711 | |||
| 712 | if (!ch->req[idx].x) | ||
| 713 | s3c_pl330_submit(ch, &ch->req[idx]); | ||
| 714 | else | ||
| 715 | s3c_pl330_submit(ch, &ch->req[1 - idx]); | ||
| 716 | |||
| 717 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 718 | |||
| 719 | if (ch->options & S3C2410_DMAF_AUTOSTART) | ||
| 720 | s3c2410_dma_ctrl(id, S3C2410_DMAOP_START); | ||
| 721 | |||
| 722 | return 0; | ||
| 723 | |||
| 724 | enq_exit: | ||
| 725 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 726 | |||
| 727 | return ret; | ||
| 728 | } | ||
| 729 | EXPORT_SYMBOL(s3c2410_dma_enqueue); | ||
| 730 | |||
| 731 | int s3c2410_dma_request(enum dma_ch id, | ||
| 732 | struct s3c2410_dma_client *client, | ||
| 733 | void *dev) | ||
| 734 | { | ||
| 735 | struct s3c_pl330_dmac *dmac; | ||
| 736 | struct s3c_pl330_chan *ch; | ||
| 737 | unsigned long flags; | ||
| 738 | int ret = 0; | ||
| 739 | |||
| 740 | spin_lock_irqsave(&res_lock, flags); | ||
| 741 | |||
| 742 | ch = chan_acquire(id); | ||
| 743 | if (!ch) { | ||
| 744 | ret = -EBUSY; | ||
| 745 | goto req_exit; | ||
| 746 | } | ||
| 747 | |||
| 748 | dmac = ch->dmac; | ||
| 749 | |||
| 750 | ch->pl330_chan_id = pl330_request_channel(dmac->pi); | ||
| 751 | if (!ch->pl330_chan_id) { | ||
| 752 | chan_release(ch); | ||
| 753 | ret = -EBUSY; | ||
| 754 | goto req_exit; | ||
| 755 | } | ||
| 756 | |||
| 757 | ch->client = client; | ||
| 758 | ch->options = 0; /* Clear any option */ | ||
| 759 | ch->callback_fn = NULL; /* Clear any callback */ | ||
| 760 | ch->lrq = NULL; | ||
| 761 | |||
| 762 | ch->rqcfg.brst_size = 2; /* Default word size */ | ||
| 763 | ch->rqcfg.swap = SWAP_NO; | ||
| 764 | ch->rqcfg.scctl = SCCTRL0; /* Noncacheable and nonbufferable */ | ||
| 765 | ch->rqcfg.dcctl = DCCTRL0; /* Noncacheable and nonbufferable */ | ||
| 766 | ch->rqcfg.privileged = 0; | ||
| 767 | ch->rqcfg.insnaccess = 0; | ||
| 768 | |||
| 769 | /* Set invalid direction */ | ||
| 770 | ch->req[0].rqtype = DEVTODEV; | ||
| 771 | ch->req[1].rqtype = ch->req[0].rqtype; | ||
| 772 | |||
| 773 | ch->req[0].cfg = &ch->rqcfg; | ||
| 774 | ch->req[1].cfg = ch->req[0].cfg; | ||
| 775 | |||
| 776 | ch->req[0].peri = iface_of_dmac(dmac, id) - 1; /* Original index */ | ||
| 777 | ch->req[1].peri = ch->req[0].peri; | ||
| 778 | |||
| 779 | ch->req[0].token = &ch->req[0]; | ||
| 780 | ch->req[0].xfer_cb = s3c_pl330_rq0; | ||
| 781 | ch->req[1].token = &ch->req[1]; | ||
| 782 | ch->req[1].xfer_cb = s3c_pl330_rq1; | ||
| 783 | |||
| 784 | ch->req[0].x = NULL; | ||
| 785 | ch->req[1].x = NULL; | ||
| 786 | |||
| 787 | /* Reset xfer list */ | ||
| 788 | INIT_LIST_HEAD(&ch->xfer_list); | ||
| 789 | ch->xfer_head = NULL; | ||
| 790 | |||
| 791 | req_exit: | ||
| 792 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 793 | |||
| 794 | return ret; | ||
| 795 | } | ||
| 796 | EXPORT_SYMBOL(s3c2410_dma_request); | ||
| 797 | |||
| 798 | int s3c2410_dma_free(enum dma_ch id, struct s3c2410_dma_client *client) | ||
| 799 | { | ||
| 800 | struct s3c_pl330_chan *ch; | ||
| 801 | struct s3c_pl330_xfer *xfer; | ||
| 802 | unsigned long flags; | ||
| 803 | int ret = 0; | ||
| 804 | unsigned idx; | ||
| 805 | |||
| 806 | spin_lock_irqsave(&res_lock, flags); | ||
| 807 | |||
| 808 | ch = id_to_chan(id); | ||
| 809 | |||
| 810 | if (!ch || chan_free(ch)) | ||
| 811 | goto free_exit; | ||
| 812 | |||
| 813 | /* Refuse if someone else wanted to free the channel */ | ||
| 814 | if (ch->client != client) { | ||
| 815 | ret = -EBUSY; | ||
| 816 | goto free_exit; | ||
| 817 | } | ||
| 818 | |||
| 819 | /* Stop any active xfer, Flushe the queue and do callbacks */ | ||
| 820 | pl330_chan_ctrl(ch->pl330_chan_id, PL330_OP_FLUSH); | ||
| 821 | |||
| 822 | /* Abort the submitted requests */ | ||
| 823 | idx = (ch->lrq == &ch->req[0]) ? 1 : 0; | ||
| 824 | |||
| 825 | if (ch->req[idx].x) { | ||
| 826 | xfer = container_of(ch->req[idx].x, | ||
| 827 | struct s3c_pl330_xfer, px); | ||
| 828 | |||
| 829 | ch->req[idx].x = NULL; | ||
| 830 | del_from_queue(xfer); | ||
| 831 | |||
| 832 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 833 | _finish_off(xfer, S3C2410_RES_ABORT, 1); | ||
| 834 | spin_lock_irqsave(&res_lock, flags); | ||
| 835 | } | ||
| 836 | |||
| 837 | if (ch->req[1 - idx].x) { | ||
| 838 | xfer = container_of(ch->req[1 - idx].x, | ||
| 839 | struct s3c_pl330_xfer, px); | ||
| 840 | |||
| 841 | ch->req[1 - idx].x = NULL; | ||
| 842 | del_from_queue(xfer); | ||
| 843 | |||
| 844 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 845 | _finish_off(xfer, S3C2410_RES_ABORT, 1); | ||
| 846 | spin_lock_irqsave(&res_lock, flags); | ||
| 847 | } | ||
| 848 | |||
| 849 | /* Pluck and Abort the queued requests in order */ | ||
| 850 | do { | ||
| 851 | xfer = get_from_queue(ch, 1); | ||
| 852 | |||
| 853 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 854 | _finish_off(xfer, S3C2410_RES_ABORT, 1); | ||
| 855 | spin_lock_irqsave(&res_lock, flags); | ||
| 856 | } while (xfer); | ||
| 857 | |||
| 858 | ch->client = NULL; | ||
| 859 | |||
| 860 | pl330_release_channel(ch->pl330_chan_id); | ||
| 861 | |||
| 862 | ch->pl330_chan_id = NULL; | ||
| 863 | |||
| 864 | chan_release(ch); | ||
| 865 | |||
| 866 | free_exit: | ||
| 867 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 868 | |||
| 869 | return ret; | ||
| 870 | } | ||
| 871 | EXPORT_SYMBOL(s3c2410_dma_free); | ||
| 872 | |||
| 873 | int s3c2410_dma_config(enum dma_ch id, int xferunit) | ||
| 874 | { | ||
| 875 | struct s3c_pl330_chan *ch; | ||
| 876 | struct pl330_info *pi; | ||
| 877 | unsigned long flags; | ||
| 878 | int i, dbwidth, ret = 0; | ||
| 879 | |||
| 880 | spin_lock_irqsave(&res_lock, flags); | ||
| 881 | |||
| 882 | ch = id_to_chan(id); | ||
| 883 | |||
| 884 | if (!ch || chan_free(ch)) { | ||
| 885 | ret = -EINVAL; | ||
| 886 | goto cfg_exit; | ||
| 887 | } | ||
| 888 | |||
| 889 | pi = ch->dmac->pi; | ||
| 890 | dbwidth = pi->pcfg.data_bus_width / 8; | ||
| 891 | |||
| 892 | /* Max size of xfer can be pcfg.data_bus_width */ | ||
| 893 | if (xferunit > dbwidth) { | ||
| 894 | ret = -EINVAL; | ||
| 895 | goto cfg_exit; | ||
| 896 | } | ||
| 897 | |||
| 898 | i = 0; | ||
| 899 | while (xferunit != (1 << i)) | ||
| 900 | i++; | ||
| 901 | |||
| 902 | /* If valid value */ | ||
| 903 | if (xferunit == (1 << i)) | ||
| 904 | ch->rqcfg.brst_size = i; | ||
| 905 | else | ||
| 906 | ret = -EINVAL; | ||
| 907 | |||
| 908 | cfg_exit: | ||
| 909 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 910 | |||
| 911 | return ret; | ||
| 912 | } | ||
| 913 | EXPORT_SYMBOL(s3c2410_dma_config); | ||
| 914 | |||
| 915 | /* Options that are supported by this driver */ | ||
| 916 | #define S3C_PL330_FLAGS (S3C2410_DMAF_CIRCULAR | S3C2410_DMAF_AUTOSTART) | ||
| 917 | |||
| 918 | int s3c2410_dma_setflags(enum dma_ch id, unsigned int options) | ||
| 919 | { | ||
| 920 | struct s3c_pl330_chan *ch; | ||
| 921 | unsigned long flags; | ||
| 922 | int ret = 0; | ||
| 923 | |||
| 924 | spin_lock_irqsave(&res_lock, flags); | ||
| 925 | |||
| 926 | ch = id_to_chan(id); | ||
| 927 | |||
| 928 | if (!ch || chan_free(ch) || options & ~(S3C_PL330_FLAGS)) | ||
| 929 | ret = -EINVAL; | ||
| 930 | else | ||
| 931 | ch->options = options; | ||
| 932 | |||
| 933 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 934 | |||
| 935 | return 0; | ||
| 936 | } | ||
| 937 | EXPORT_SYMBOL(s3c2410_dma_setflags); | ||
| 938 | |||
| 939 | int s3c2410_dma_set_buffdone_fn(enum dma_ch id, s3c2410_dma_cbfn_t rtn) | ||
| 940 | { | ||
| 941 | struct s3c_pl330_chan *ch; | ||
| 942 | unsigned long flags; | ||
| 943 | int ret = 0; | ||
| 944 | |||
| 945 | spin_lock_irqsave(&res_lock, flags); | ||
| 946 | |||
| 947 | ch = id_to_chan(id); | ||
| 948 | |||
| 949 | if (!ch || chan_free(ch)) | ||
| 950 | ret = -EINVAL; | ||
| 951 | else | ||
| 952 | ch->callback_fn = rtn; | ||
| 953 | |||
| 954 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 955 | |||
| 956 | return ret; | ||
| 957 | } | ||
| 958 | EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn); | ||
| 959 | |||
| 960 | int s3c2410_dma_devconfig(enum dma_ch id, enum s3c2410_dmasrc source, | ||
| 961 | unsigned long address) | ||
| 962 | { | ||
| 963 | struct s3c_pl330_chan *ch; | ||
| 964 | unsigned long flags; | ||
| 965 | int ret = 0; | ||
| 966 | |||
| 967 | spin_lock_irqsave(&res_lock, flags); | ||
| 968 | |||
| 969 | ch = id_to_chan(id); | ||
| 970 | |||
| 971 | if (!ch || chan_free(ch)) { | ||
| 972 | ret = -EINVAL; | ||
| 973 | goto devcfg_exit; | ||
| 974 | } | ||
| 975 | |||
| 976 | switch (source) { | ||
| 977 | case S3C2410_DMASRC_HW: /* P->M */ | ||
| 978 | ch->req[0].rqtype = DEVTOMEM; | ||
| 979 | ch->req[1].rqtype = DEVTOMEM; | ||
| 980 | ch->rqcfg.src_inc = 0; | ||
| 981 | ch->rqcfg.dst_inc = 1; | ||
| 982 | break; | ||
| 983 | case S3C2410_DMASRC_MEM: /* M->P */ | ||
| 984 | ch->req[0].rqtype = MEMTODEV; | ||
| 985 | ch->req[1].rqtype = MEMTODEV; | ||
| 986 | ch->rqcfg.src_inc = 1; | ||
| 987 | ch->rqcfg.dst_inc = 0; | ||
| 988 | break; | ||
| 989 | default: | ||
| 990 | ret = -EINVAL; | ||
| 991 | goto devcfg_exit; | ||
| 992 | } | ||
| 993 | |||
| 994 | ch->sdaddr = address; | ||
| 995 | |||
| 996 | devcfg_exit: | ||
| 997 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 998 | |||
| 999 | return ret; | ||
| 1000 | } | ||
| 1001 | EXPORT_SYMBOL(s3c2410_dma_devconfig); | ||
| 1002 | |||
| 1003 | int s3c2410_dma_getposition(enum dma_ch id, dma_addr_t *src, dma_addr_t *dst) | ||
| 1004 | { | ||
| 1005 | struct s3c_pl330_chan *ch = id_to_chan(id); | ||
| 1006 | struct pl330_chanstatus status; | ||
| 1007 | int ret; | ||
| 1008 | |||
| 1009 | if (!ch || chan_free(ch)) | ||
| 1010 | return -EINVAL; | ||
| 1011 | |||
| 1012 | ret = pl330_chan_status(ch->pl330_chan_id, &status); | ||
| 1013 | if (ret < 0) | ||
| 1014 | return ret; | ||
| 1015 | |||
| 1016 | *src = status.src_addr; | ||
| 1017 | *dst = status.dst_addr; | ||
| 1018 | |||
| 1019 | return 0; | ||
| 1020 | } | ||
| 1021 | EXPORT_SYMBOL(s3c2410_dma_getposition); | ||
| 1022 | |||
| 1023 | static irqreturn_t pl330_irq_handler(int irq, void *data) | ||
| 1024 | { | ||
| 1025 | if (pl330_update(data)) | ||
| 1026 | return IRQ_HANDLED; | ||
| 1027 | else | ||
| 1028 | return IRQ_NONE; | ||
| 1029 | } | ||
| 1030 | |||
| 1031 | static int pl330_probe(struct platform_device *pdev) | ||
| 1032 | { | ||
| 1033 | struct s3c_pl330_dmac *s3c_pl330_dmac; | ||
| 1034 | struct s3c_pl330_platdata *pl330pd; | ||
| 1035 | struct pl330_info *pl330_info; | ||
| 1036 | struct resource *res; | ||
| 1037 | int i, ret, irq; | ||
| 1038 | |||
| 1039 | pl330pd = pdev->dev.platform_data; | ||
| 1040 | |||
| 1041 | /* Can't do without the list of _32_ peripherals */ | ||
| 1042 | if (!pl330pd || !pl330pd->peri) { | ||
| 1043 | dev_err(&pdev->dev, "platform data missing!\n"); | ||
| 1044 | return -ENODEV; | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | pl330_info = kzalloc(sizeof(*pl330_info), GFP_KERNEL); | ||
| 1048 | if (!pl330_info) | ||
| 1049 | return -ENOMEM; | ||
| 1050 | |||
| 1051 | pl330_info->pl330_data = NULL; | ||
| 1052 | pl330_info->dev = &pdev->dev; | ||
| 1053 | |||
| 1054 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 1055 | if (!res) { | ||
| 1056 | ret = -ENODEV; | ||
| 1057 | goto probe_err1; | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | request_mem_region(res->start, resource_size(res), pdev->name); | ||
| 1061 | |||
| 1062 | pl330_info->base = ioremap(res->start, resource_size(res)); | ||
| 1063 | if (!pl330_info->base) { | ||
| 1064 | ret = -ENXIO; | ||
| 1065 | goto probe_err2; | ||
| 1066 | } | ||
| 1067 | |||
| 1068 | irq = platform_get_irq(pdev, 0); | ||
| 1069 | if (irq < 0) { | ||
| 1070 | ret = irq; | ||
| 1071 | goto probe_err3; | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | ret = request_irq(irq, pl330_irq_handler, 0, | ||
| 1075 | dev_name(&pdev->dev), pl330_info); | ||
| 1076 | if (ret) | ||
| 1077 | goto probe_err4; | ||
| 1078 | |||
| 1079 | /* Allocate a new DMAC */ | ||
| 1080 | s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL); | ||
| 1081 | if (!s3c_pl330_dmac) { | ||
| 1082 | ret = -ENOMEM; | ||
| 1083 | goto probe_err5; | ||
| 1084 | } | ||
| 1085 | |||
| 1086 | /* Get operation clock and enable it */ | ||
| 1087 | s3c_pl330_dmac->clk = clk_get(&pdev->dev, "pdma"); | ||
| 1088 | if (IS_ERR(s3c_pl330_dmac->clk)) { | ||
| 1089 | dev_err(&pdev->dev, "Cannot get operation clock.\n"); | ||
| 1090 | ret = -EINVAL; | ||
| 1091 | goto probe_err6; | ||
| 1092 | } | ||
| 1093 | clk_enable(s3c_pl330_dmac->clk); | ||
| 1094 | |||
| 1095 | ret = pl330_add(pl330_info); | ||
| 1096 | if (ret) | ||
| 1097 | goto probe_err7; | ||
| 1098 | |||
| 1099 | /* Hook the info */ | ||
| 1100 | s3c_pl330_dmac->pi = pl330_info; | ||
| 1101 | |||
| 1102 | /* No busy channels */ | ||
| 1103 | s3c_pl330_dmac->busy_chan = 0; | ||
| 1104 | |||
| 1105 | s3c_pl330_dmac->kmcache = kmem_cache_create(dev_name(&pdev->dev), | ||
| 1106 | sizeof(struct s3c_pl330_xfer), 0, 0, NULL); | ||
| 1107 | |||
| 1108 | if (!s3c_pl330_dmac->kmcache) { | ||
| 1109 | ret = -ENOMEM; | ||
| 1110 | goto probe_err8; | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | /* Get the list of peripherals */ | ||
| 1114 | s3c_pl330_dmac->peri = pl330pd->peri; | ||
| 1115 | |||
| 1116 | /* Attach to the list of DMACs */ | ||
| 1117 | list_add_tail(&s3c_pl330_dmac->node, &dmac_list); | ||
| 1118 | |||
| 1119 | /* Create a channel for each peripheral in the DMAC | ||
| 1120 | * that is, if it doesn't already exist | ||
| 1121 | */ | ||
| 1122 | for (i = 0; i < PL330_MAX_PERI; i++) | ||
| 1123 | if (s3c_pl330_dmac->peri[i] != DMACH_MAX) | ||
| 1124 | chan_add(s3c_pl330_dmac->peri[i]); | ||
| 1125 | |||
| 1126 | printk(KERN_INFO | ||
| 1127 | "Loaded driver for PL330 DMAC-%d %s\n", pdev->id, pdev->name); | ||
| 1128 | printk(KERN_INFO | ||
| 1129 | "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n", | ||
| 1130 | pl330_info->pcfg.data_buf_dep, | ||
| 1131 | pl330_info->pcfg.data_bus_width / 8, pl330_info->pcfg.num_chan, | ||
| 1132 | pl330_info->pcfg.num_peri, pl330_info->pcfg.num_events); | ||
| 1133 | |||
| 1134 | return 0; | ||
| 1135 | |||
| 1136 | probe_err8: | ||
| 1137 | pl330_del(pl330_info); | ||
| 1138 | probe_err7: | ||
| 1139 | clk_disable(s3c_pl330_dmac->clk); | ||
| 1140 | clk_put(s3c_pl330_dmac->clk); | ||
| 1141 | probe_err6: | ||
| 1142 | kfree(s3c_pl330_dmac); | ||
| 1143 | probe_err5: | ||
| 1144 | free_irq(irq, pl330_info); | ||
| 1145 | probe_err4: | ||
| 1146 | probe_err3: | ||
| 1147 | iounmap(pl330_info->base); | ||
| 1148 | probe_err2: | ||
| 1149 | release_mem_region(res->start, resource_size(res)); | ||
| 1150 | probe_err1: | ||
| 1151 | kfree(pl330_info); | ||
| 1152 | |||
| 1153 | return ret; | ||
| 1154 | } | ||
| 1155 | |||
| 1156 | static int pl330_remove(struct platform_device *pdev) | ||
| 1157 | { | ||
| 1158 | struct s3c_pl330_dmac *dmac, *d; | ||
| 1159 | struct s3c_pl330_chan *ch; | ||
| 1160 | unsigned long flags; | ||
| 1161 | int del, found; | ||
| 1162 | |||
| 1163 | if (!pdev->dev.platform_data) | ||
| 1164 | return -EINVAL; | ||
| 1165 | |||
| 1166 | spin_lock_irqsave(&res_lock, flags); | ||
| 1167 | |||
| 1168 | found = 0; | ||
| 1169 | list_for_each_entry(d, &dmac_list, node) | ||
| 1170 | if (d->pi->dev == &pdev->dev) { | ||
| 1171 | found = 1; | ||
| 1172 | break; | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | if (!found) { | ||
| 1176 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 1177 | return 0; | ||
| 1178 | } | ||
| 1179 | |||
| 1180 | dmac = d; | ||
| 1181 | |||
| 1182 | /* Remove all Channels that are managed only by this DMAC */ | ||
| 1183 | list_for_each_entry(ch, &chan_list, node) { | ||
| 1184 | |||
| 1185 | /* Only channels that are handled by this DMAC */ | ||
| 1186 | if (iface_of_dmac(dmac, ch->id)) | ||
| 1187 | del = 1; | ||
| 1188 | else | ||
| 1189 | continue; | ||
| 1190 | |||
| 1191 | /* Don't remove if some other DMAC has it too */ | ||
| 1192 | list_for_each_entry(d, &dmac_list, node) | ||
| 1193 | if (d != dmac && iface_of_dmac(d, ch->id)) { | ||
| 1194 | del = 0; | ||
| 1195 | break; | ||
| 1196 | } | ||
| 1197 | |||
| 1198 | if (del) { | ||
| 1199 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 1200 | s3c2410_dma_free(ch->id, ch->client); | ||
| 1201 | spin_lock_irqsave(&res_lock, flags); | ||
| 1202 | list_del(&ch->node); | ||
| 1203 | kfree(ch); | ||
| 1204 | } | ||
| 1205 | } | ||
| 1206 | |||
| 1207 | /* Disable operation clock */ | ||
| 1208 | clk_disable(dmac->clk); | ||
| 1209 | clk_put(dmac->clk); | ||
| 1210 | |||
| 1211 | /* Remove the DMAC */ | ||
| 1212 | list_del(&dmac->node); | ||
| 1213 | kfree(dmac); | ||
| 1214 | |||
| 1215 | spin_unlock_irqrestore(&res_lock, flags); | ||
| 1216 | |||
| 1217 | return 0; | ||
| 1218 | } | ||
| 1219 | |||
| 1220 | static struct platform_driver pl330_driver = { | ||
| 1221 | .driver = { | ||
| 1222 | .owner = THIS_MODULE, | ||
| 1223 | .name = "s3c-pl330", | ||
| 1224 | }, | ||
| 1225 | .probe = pl330_probe, | ||
| 1226 | .remove = pl330_remove, | ||
| 1227 | }; | ||
| 1228 | |||
| 1229 | static int __init pl330_init(void) | ||
| 1230 | { | ||
| 1231 | return platform_driver_register(&pl330_driver); | ||
| 1232 | } | ||
| 1233 | module_init(pl330_init); | ||
| 1234 | |||
| 1235 | static void __exit pl330_exit(void) | ||
| 1236 | { | ||
| 1237 | platform_driver_unregister(&pl330_driver); | ||
| 1238 | return; | ||
| 1239 | } | ||
| 1240 | module_exit(pl330_exit); | ||
| 1241 | |||
| 1242 | MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>"); | ||
| 1243 | MODULE_DESCRIPTION("Driver for PL330 DMA Controller"); | ||
| 1244 | MODULE_LICENSE("GPL"); | ||
