diff options
author | codeworkx <daniel.hillenbrand@codeworkx.de> | 2012-06-02 13:09:29 +0200 |
---|---|---|
committer | codeworkx <daniel.hillenbrand@codeworkx.de> | 2012-06-02 13:09:29 +0200 |
commit | c6da2cfeb05178a11c6d062a06f8078150ee492f (patch) | |
tree | f3b4021d252c52d6463a9b3c1bb7245e399b009c /arch/arm/plat-s5p | |
parent | c6d7c4dbff353eac7919342ae6b3299a378160a6 (diff) | |
download | kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.zip kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.gz kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.bz2 |
samsung update 1
Diffstat (limited to 'arch/arm/plat-s5p')
84 files changed, 8771 insertions, 493 deletions
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index e98f5c5..3398d3b 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -7,10 +7,10 @@ config PLAT_S5P bool - depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS4) + depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) default y - select ARM_VIC if !ARCH_EXYNOS4 - select ARM_GIC if ARCH_EXYNOS4 + select ARM_VIC if !ARCH_EXYNOS + select ARM_GIC if ARCH_EXYNOS select NO_IOPORT select ARCH_REQUIRE_GPIOLIB select S3C_GPIO_TRACK @@ -39,58 +39,239 @@ config S5P_GPIO_INT config S5P_HRT bool + select SAMSUNG_DEV_PWM help Use the High Resolution timer support -comment "System MMU" - config S5P_SYSTEM_MMU - bool "S5P SYSTEM MMU" + bool "System MMU for Exynos families" depends on ARCH_EXYNOS4 + select IOMMU_EXYNOS4_API + select IOVMM help Say Y here if you want to enable System MMU +config S5P_SYSTEM_MMU_REFCOUNT + bool "Counting System MMU activations" + depends on S5P_SYSTEM_MMU + help + Say Y here if you want to enable counting System MMU enabling and + disabling. + +config S5P_SYSTEM_MMU_DEBUG + bool "Enables verbose debugging message about System MMU" + depends on S5P_SYSTEM_MMU + help + Say Y here if you need detailed message while System MMU driver works + +config S5P_SYSTEM_MMU_WA5250ERR + bool "Ensure 64KB-aligned mapping for DMA I/O buffers" + depends on S5P_SYSTEM_MMU && CPU_EXYNOS5250 + default y + help + Select this to avoid unexpected fault occurred by System MMU v3.0. + This is just a makeshift option for those problems. + + If unsure, n here. + +config IOVMM + bool + select GENERIC_ALLOCATOR + +config IOMMU_EXYNOS4_API + bool + +config S3C_DEV_FIMC + bool + depends on VIDEO_FIMC + default y + help + Compile in platform device definitions for FIMC + config S5P_DEV_FIMC0 bool + depends on VIDEO_SAMSUNG_S5P_FIMC + default y help Compile in platform device definitions for FIMC controller 0 config S5P_DEV_FIMC1 bool + depends on VIDEO_SAMSUNG_S5P_FIMC + default y help Compile in platform device definitions for FIMC controller 1 config S5P_DEV_FIMC2 bool + depends on VIDEO_SAMSUNG_S5P_FIMC + default y help Compile in platform device definitions for FIMC controller 2 config S5P_DEV_FIMC3 bool + depends on VIDEO_SAMSUNG_S5P_FIMC + default y help Compile in platform device definitions for FIMC controller 3 +config S5P_DEV_I2C_HDMIPHY + bool + help + Compile in platform device definitions for I2C HDMIPHY controller + +config S5P_DEV_TV + bool + help + Compile in platform device definition for TV interface + +config S5P_DEV_MFC + bool + help + Compile in platform device definitions for MFC + +config S5P_DEV_FIMD0 + bool + help + Compile in platform device definitions for FIMD controller 0 + +config S5P_DEV_FIMD1 + bool + help + Compile in platform device definitions for FIMD controller 1 + +config S5P_DEV_DP + bool + help + Compile in platform device definitions for DP controller + +config S5P_DEV_TVOUT + bool + depends on VIDEO_TVOUT + default y + help + Compile in platform device definitions for TVOUT + +config S5P_DEV_FIMG2D + bool + help + Compile in platform device definitions for FIMG2D controller + +config S5P_DEV_ROTATOR + bool + help + Compile in platform device definitions for ROTATOR + config S5P_DEV_ONENAND bool help Compile in platform device definition for OneNAND controller +config S5P_DEV_CSIS + bool + depends on VIDEO_FIMC_MIPI + default y + help + Compile in platform device definitions for MIPI-CSIS + config S5P_DEV_CSIS0 bool + depends on (VIDEO_S5P_MIPI_CSIS || VIDEO_EXYNOS_MIPI_CSIS) + default y help Compile in platform device definitions for MIPI-CSIS channel 0 config S5P_DEV_CSIS1 bool + depends on (VIDEO_S5P_MIPI_CSIS || VIDEO_EXYNOS_MIPI_CSIS) + default y help Compile in platform device definitions for MIPI-CSIS channel 1 +config S5P_DEV_JPEG + bool + depends on VIDEO_JPEG || VIDEO_JPEG_V2X + default y + help + Compile in platform device definitions for JPEG + config S5P_DEV_USB_EHCI bool help Compile in platform device definition for USB EHCI +config S5P_DEV_FIMD_S5P + bool + help + Compile in platform device definitions for FIMD controller + +config S5P_DEV_USBGADGET + bool + help + compile in platform device definitions for USB-GADGET + +config S5P_DEV_USB_SWITCH + bool + help + compile in platform device definitions for USB-SWITCH + config S5P_SETUP_MIPIPHY bool + depends on (VIDEO_S5P_MIPI_CSIS || S5P_MIPI_DSI2 || VIDEO_EXYNOS_MIPI_CSIS) + default y help Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices + +config S5P_MEM_CMA + bool "Fixed memory through CMA" + select CMA + help + Use CMA(Contiguous memory allocator) to reserve machine specific memory. + +config S5P_DEV_THERMAL + bool + help + Compile in platform device definitions for THERMAL management unit. + +config S5P_DEV_ACE + bool + help + Compile in common setup code for Crypto Engine devices. + +config S5P_DEV_MIPI_DSI + bool + depends on FB_S5P_MIPI_DSIM + default y + help + Compile in platform device definitions for MIPI_DSI + +config S5P_DEV_DSIM02 + bool + help + Compile in platform device definitions for MIPI-DSIM channel 0 + +config S5P_DEV_DSIM12 + bool + help + Compile in platform device definitions for MIPI-DSIM channel 1 + +config S5P_BTS + bool "S5P BTS driver" + default n + help + Use Bus Traffic Shaper Driver + +config S5P_DEV_MIPI_DSIM + bool + depends on FB_MIPI_DSIM + default y + help + Compile in platform device definitions for MIPI_DSIM + to support mainlile style fimd + +config S3C_DEV_TSI + boolean "DEV TSI" + default n + ---help--- + Compile in platform device definitions for S3C_DEV_TSI controller diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index e234cc4..282efc6 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -17,21 +17,51 @@ obj-y += dev-uart.o obj-y += cpu.o obj-y += clock.o obj-y += irq.o +obj-y += reset.o +obj-y += reserve_mem.o obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o -obj-$(CONFIG_S5P_SYSTEM_MMU) += sysmmu.o +obj-$(CONFIG_S5P_SYSTEM_MMU) += s5p-sysmmu.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_PM) += irq-pm.o obj-$(CONFIG_S5P_HRT) += s5p-time.o +obj-$(CONFIG_S5P_BTS) += bts.o # devices +obj-$(CONFIG_S3C_DEV_FIMC) += dev-fimc-s5p.o obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o obj-$(CONFIG_S5P_DEV_FIMC3) += dev-fimc3.o +obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.o +obj-$(CONFIG_S5P_DEV_FIMD0) += dev-fimd0.o +obj-$(CONFIG_S5P_DEV_FIMD1) += dev-fimd1.o +obj-$(CONFIG_S5P_DEV_I2C_HDMIPHY) += dev-i2c-hdmiphy.o +obj-$(CONFIG_S5P_DEV_DP) += dev-dp.o +obj-$(CONFIG_S5P_DEV_FIMD_S5P) += dev-fimd-s5p.o +obj-$(CONFIG_S5P_DEV_TVOUT) += dev-tvout.o +obj-$(CONFIG_S5P_DEV_TV) += dev-tv.o +obj-$(CONFIG_S5P_DEV_FIMG2D) += dev-fimg2d.o +obj-$(CONFIG_S5P_DEV_ROTATOR) += dev-rotator.o obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o +obj-$(CONFIG_S5P_DEV_CSIS) += dev-csis-s5p.o +obj-$(CONFIG_S5P_DEV_JPEG) += dev-jpeg.o obj-$(CONFIG_S5P_DEV_USB_EHCI) += dev-ehci.o +obj-$(CONFIG_S5P_DEV_USB_SWITCH) += dev-usb-switch.o +obj-$(CONFIG_S5P_DEV_USBGADGET) += dev-usbgadget.o +obj-$(CONFIG_S5P_DEV_MIPI_DSI) += dev-dsim.o +obj-$(CONFIG_S5P_DEV_DSIM02) += dev-dsim02.o +obj-$(CONFIG_S5P_DEV_DSIM12) += dev-dsim12.o +obj-$(CONFIG_S5P_DEV_MIPI_DSIM) += dev-mipidsim.o obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o +obj-$(CONFIG_EXYNOS4_SETUP_THERMAL) += dev-tmu.o +obj-$(CONFIG_S5P_DEV_ACE) += dev-ace.o +ifeq ($(CONFIG_ARCH_EXYNOS4), y) +obj-$(CONFIG_IOMMU_EXYNOS4_API) += s5p_iommu.o +obj-$(CONFIG_IOVMM) += s5p_iovmm.o +endif +obj-$(CONFIG_S5P_DEV_I2C_HDMIPHY) += dev-i2c-hdmiphy.o +obj-$(CONFIG_S3C_DEV_TSI) += dev-tsi.o diff --git a/arch/arm/plat-s5p/bts.c b/arch/arm/plat-s5p/bts.c new file mode 100644 index 0000000..c0dba21 --- /dev/null +++ b/arch/arm/plat-s5p/bts.c @@ -0,0 +1,393 @@ +/* linux/arch/arm/plat-s5p/bts.c + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/slab.h> +#include <linux/clk.h> +#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME)) +#include <linux/pm_runtime.h> +#include <plat/pd.h> +#endif +#include <plat/devs.h> +#include <plat/cpu.h> +#include <plat/bts.h> +#include <mach/map.h> + +/* BTS register */ +#define BTS_CONTROL 0x0 +#define BTS_SHAPING_ON_OFF_REG0 0x4 +#define BTS_MASTER_PRIORITY 0x8 +#define BTS_SHAPING_ON_OFF_REG2 0xc +#define BTS_SHAPING_ON_OFF_REG1 0x44 +#define BTS_DEBLOCKING_SOURCE_SELECTION 0x50 + +/* FBM register */ +#define FBM_MODESEL0 0x0 +#define FBM_THRESHOLDSEL0 0x40 + +/* BTS priority values */ +#define BTS_PRIOR_HARDTIME 15 +#define BTS_PRIOR_BESTEFFORT 8 + +/* Fields of BTS_CONTROL register */ +#define BTS_ON_OFF (1<<0) +#define BLOCKING_ON_OFF (1<<2) +#define FLEXIBLE_ON_OFF (1<<7) + +/* Fields of FLEXIBLE_BLOCKING_CONTROL register */ +#define SEL_GRP0 (1<<0) +#define SEL_LEFT0 (1<<4) +#define SEL_RIGHT0 (1<<5) +#define SEL_GRP1 (1<<8) +#define SEL_LEFT1 (1<<12) +#define SEL_RIGHT1 (1<<13) +#define SEL_GRP2 (1<<16) +#define SEL_LEFT2 (1<<20) +#define SEL_RIGHT2 (1<<21) + +/* Fields of FBM MODESEL0 register */ +#define RD_COUNTER 0 +#define WT_COUNTER 1 +#define RDWT_COUNTER 2 + +/* Values of FBM THRESHOLDSEL0 register */ +#define FBM_THR_HARDTIME 0x3 +#define FBM_THR_BE 0x4 + +/* Shaping Value for Low priority */ +#define LOW_SHAPING_VAL0 0x100010 +#define LOW_SHAPING_VAL1 0x3ff +#define LOW_SHAPING_VAL2_BE 0x200 +#define LOW_SHAPING_VAL2_HARDTIME 0x3 +#define MASTER_PRIOR_BE_NUMBER (1<<16) +#define MASTER_PRIOR_HARDTIME_NUMBER (3<<16) + +static LIST_HEAD(fbm_list); +static LIST_HEAD(bts_list); + +struct exynos_bts_local_data { + enum exynos_bts_id id; + void __iomem *base; + enum bts_priority def_priority; +}; + +struct exynos_bts_data { + struct list_head node; + struct device *dev; + struct exynos_bts_local_data *bts_local_data; + struct clk *clk; + enum exynos_pd_block pd_block; + u32 listnum; +}; + +struct exynos_fbm_data { + struct exynos_fbm_resource fbm; + struct list_head node; +}; + +static void bts_set_control(void __iomem *base, enum bts_priority prior) +{ + u32 val = BTS_ON_OFF; + + if (prior == BTS_BE) + val |= BLOCKING_ON_OFF|FLEXIBLE_ON_OFF; + + writel(val, base + BTS_CONTROL); +} + +static void bts_set_master_priority(void __iomem *base, + enum bts_priority prior) +{ + u32 val = 0; + int priority = BTS_PRIOR_BESTEFFORT; + + if (prior == BTS_BE) { + val = MASTER_PRIOR_BE_NUMBER; + } else if (prior == BTS_HARDTIME) { + val = MASTER_PRIOR_HARDTIME_NUMBER; + priority = BTS_PRIOR_HARDTIME; + } + + val |= (priority<<8) | (priority<<4) | (priority); + writel(val, base + BTS_MASTER_PRIORITY); +} + +static void bts_set_besteffort_shaping(void __iomem *base, + enum bts_priority prior) +{ + if (prior == BTS_BE) { + writel(LOW_SHAPING_VAL0, base + BTS_SHAPING_ON_OFF_REG0); + writel(LOW_SHAPING_VAL1, base + BTS_SHAPING_ON_OFF_REG1); + writel(LOW_SHAPING_VAL2_BE, base + BTS_SHAPING_ON_OFF_REG2); + } else if (prior == BTS_HARDTIME) { + writel(LOW_SHAPING_VAL2_HARDTIME, + base + BTS_SHAPING_ON_OFF_REG2); + } +} + +static void bts_set_deblocking(void __iomem *base, + enum bts_fbm_group deblocking) +{ + u32 val = 0; + + if (deblocking & BTS_FBM_G0_L) + val |= SEL_GRP0 | SEL_LEFT0; + if (deblocking & BTS_FBM_G0_R) + val |= SEL_GRP0 | SEL_RIGHT0; + if (deblocking & BTS_FBM_G1_L) + val |= SEL_GRP1 | SEL_LEFT1; + if (deblocking & BTS_FBM_G1_R) + val |= SEL_GRP1 | SEL_RIGHT1; + if (deblocking & BTS_FBM_G2_L) + val |= SEL_GRP2 | SEL_LEFT2; + if (deblocking & BTS_FBM_G2_R) + val |= SEL_GRP2 | SEL_RIGHT2; + + writel(val, base + BTS_DEBLOCKING_SOURCE_SELECTION); +} + +static enum bts_fbm_group find_fbm_group(enum bts_priority prior) +{ + struct exynos_fbm_data *fbm_data; + enum bts_fbm_group fbm_group = 0; + + list_for_each_entry(fbm_data, &fbm_list, node) { + if (prior == BTS_BE) { + if (fbm_data->fbm.priority == BTS_HARDTIME) + fbm_group |= fbm_data->fbm.fbm_group; + } else if (prior == BTS_HARDTIME) { + if ((fbm_data->fbm.priority == BTS_BE) || + (fbm_data->fbm.priority == BTS_HARDTIME)) + fbm_group |= fbm_data->fbm.fbm_group; + } + } + + return fbm_group; +} + +static void fbm_init_config(void __iomem *base, enum bts_priority prior) +{ + if (prior == BTS_BE) { + writel(RD_COUNTER, base + FBM_MODESEL0); + writel(FBM_THR_BE, base + FBM_THRESHOLDSEL0); + } else if (prior == BTS_HARDTIME) { + writel(RDWT_COUNTER, base + FBM_MODESEL0); + writel(FBM_THR_HARDTIME, base + FBM_THRESHOLDSEL0); + } +} + +static void bts_init_config(void __iomem *base, enum bts_priority prior) +{ + if (prior == BTS_BE) { + bts_set_besteffort_shaping(base, prior); + bts_set_deblocking(base, find_fbm_group(prior)); + bts_set_master_priority(base, prior); + bts_set_control(base, prior); + } else if (prior == BTS_HARDTIME) { + bts_set_besteffort_shaping(base, prior); + bts_set_master_priority(base, prior); + bts_set_control(base, prior); + } +} + +static void __exynos_bts_enable(struct exynos_bts_data *bts_data) +{ + struct exynos_bts_local_data *bts_local_data; + int i; + + if (bts_data->clk) + clk_enable(bts_data->clk); + + bts_local_data = bts_data->bts_local_data; + for (i = 0; i < bts_data->listnum; i++) { + bts_init_config(bts_local_data->base, + bts_local_data->def_priority); + bts_local_data++; + } + + if (bts_data->clk) + clk_disable(bts_data->clk); +} + +void exynos_bts_set_priority(enum bts_priority prior) +{ + struct exynos_bts_data *bts_data; + struct exynos_bts_local_data *bts_local_data; + int i; + + list_for_each_entry(bts_data, &bts_list, node) { + bts_local_data = bts_data->bts_local_data; + for (i = 0; i < bts_data->listnum; i++) { + bts_local_data = bts_data->bts_local_data; + if ((bts_local_data->id == BTS_CPU) | + (bts_local_data->id == BTS_G3D_ACP) | + (bts_local_data->id == BTS_ROTATOR)) + bts_set_deblocking(bts_local_data->base, + find_fbm_group(prior)); + bts_local_data++; + } + } +} + +void exynos_bts_enable(enum exynos_pd_block pd_block) +{ + struct exynos_bts_data *bts_data; + struct exynos_fbm_data *fbm_data; + + if (pd_block == PD_TOP) { + list_for_each_entry(fbm_data, &fbm_list, node) + fbm_init_config((void __iomem *)fbm_data->fbm.base, + fbm_data->fbm.priority); + } + + list_for_each_entry(bts_data, &bts_list, node) { + if (bts_data->pd_block == pd_block) + __exynos_bts_enable(bts_data); + } +} + +static int bts_probe(struct platform_device *pdev) +{ + struct exynos_bts_pdata *bts_pdata; + struct exynos_fbm_resource *fbm_res; + struct exynos_bts_data *bts_data; + struct exynos_bts_local_data *bts_local_data, *bts_local_data_h; + struct exynos_fbm_data *fbm_data; + struct resource *res = NULL; + void __iomem *base; + struct clk *clk = NULL; + int i, ret = 0; + + bts_pdata = pdev->dev.platform_data; + fbm_res = bts_pdata->fbm->res; + + if (!bts_pdata) { + dev_err(&pdev->dev, "platform data is missed!\n"); + return -ENODEV; + } + + if (list_empty(&fbm_list)) { + for (i = 0; i < bts_pdata->fbm->res_num; i++) { + base = ioremap(fbm_res->base, FBM_THRESHOLDSEL0); + if (!base) + return -ENODEV; + fbm_init_config(base, fbm_res->priority); + fbm_data = kzalloc(sizeof(struct exynos_fbm_data), + GFP_KERNEL); + fbm_data->fbm.base = (u32)base; + fbm_data->fbm.fbm_group = fbm_res->fbm_group; + fbm_data->fbm.priority = fbm_res->priority; + list_add_tail(&fbm_data->node, &fbm_list); + fbm_res++; + } + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "can't get resource!\n"); + return -ENODEV; + } + + if (bts_pdata->clk_name) { + clk = clk_get(pdev->dev.parent, bts_pdata->clk_name); + if (IS_ERR(clk)) + return -EINVAL; + clk_enable(clk); + } + + bts_data = kzalloc(sizeof(struct exynos_bts_data), GFP_KERNEL); + bts_data->listnum = bts_pdata->res_num; + bts_local_data_h = bts_local_data = + kzalloc(sizeof(struct exynos_bts_local_data)*bts_data->listnum, + GFP_KERNEL); + + for (i = 0; i < bts_data->listnum; i++) { + bts_local_data->id = bts_pdata->id; + bts_local_data->base = ioremap(res->start, resource_size(res)); + bts_local_data->def_priority = bts_pdata->def_priority; + if (!bts_local_data->base) { + ret = -ENXIO; + goto probe_err; + } + bts_init_config(bts_local_data->base, + bts_local_data->def_priority); + bts_local_data++; + res++; + } + + bts_data->bts_local_data = bts_local_data_h; + bts_data->pd_block = bts_pdata->pd_block; + bts_data->clk = clk; + bts_data->dev = &pdev->dev; + list_add_tail(&bts_data->node, &bts_list); + pdev->dev.platform_data = bts_data; + +probe_err: + + if (bts_pdata->clk_name) + clk_disable(clk); + + return ret; +} + +static int bts_remove(struct platform_device *pdev) +{ + struct exynos_fbm_data *fbm_data; + struct exynos_bts_data *bts_data = pdev->dev.platform_data; + struct exynos_bts_local_data *bts_local_data; + int i; + + bts_local_data = bts_data->bts_local_data; + for (i = 0; i < bts_data->listnum; i++) { + bts_local_data++; + iounmap(bts_local_data->base); + } + kfree(bts_data->bts_local_data); + list_del(&bts_data->node); + kfree(bts_data); + + if (list_empty(&bts_list)) + list_for_each_entry(fbm_data, &fbm_list, node) { + iounmap((void __iomem *)fbm_data->fbm.base); + kfree(fbm_data); + list_del(&fbm_data->node); + } + + if (bts_data->clk) + clk_put(bts_data->clk); + + return 0; +} + +static struct platform_driver bts_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "exynos-bts" + }, + .probe = bts_probe, + .remove = bts_remove, +}; + +static int __init bts_init(void) +{ + return platform_driver_register(&bts_driver); +} +arch_initcall(bts_init); diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c index 8d081d9..7b4ec47 100644 --- a/arch/arm/plat-s5p/clock.c +++ b/arch/arm/plat-s5p/clock.c @@ -40,6 +40,11 @@ struct clk clk_xusbxti = { .id = -1, }; +struct clk clk_xxti = { + .name = "xxti", + .id = -1, +}; + struct clk s5p_clk_27m = { .name = "clk_27m", .id = -1, @@ -73,6 +78,7 @@ struct clk clk_fout_mpll = { struct clk clk_fout_epll = { .name = "fout_epll", .id = -1, + .parent = &clk_ext_xtal_mux, .ctrlbit = (1 << 31), }; @@ -168,6 +174,41 @@ unsigned long s5p_epll_get_rate(struct clk *clk) return clk->rate; } +int s5p_spdif_set_rate(struct clk *clk, unsigned long rate) +{ + struct clk *pclk; + int ret; + + pclk = clk_get_parent(clk); + if (IS_ERR(pclk)) + return -EINVAL; + + ret = pclk->ops->set_rate(pclk, rate); + clk_put(pclk); + + return ret; +} + +unsigned long s5p_spdif_get_rate(struct clk *clk) +{ + struct clk *pclk; + int rate; + + pclk = clk_get_parent(clk); + if (IS_ERR(pclk)) + return -EINVAL; + + rate = pclk->ops->get_rate(pclk); + clk_put(pclk); + + return rate; +} + +struct clk_ops s5p_sclk_spdif_ops = { + .set_rate = s5p_spdif_set_rate, + .get_rate = s5p_spdif_get_rate, +}; + static struct clk *s5p_clks[] __initdata = { &clk_ext_xtal_mux, &clk_48m, @@ -179,6 +220,7 @@ static struct clk *s5p_clks[] __initdata = { &clk_fout_vpll, &clk_vpll, &clk_xusbxti, + &clk_xxti, }; void __init s5p_register_clocks(unsigned long xtal_freq) diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c index bbc2aa7..15c3a39 100644 --- a/arch/arm/plat-s5p/cpu.c +++ b/arch/arm/plat-s5p/cpu.c @@ -25,6 +25,7 @@ #include <plat/s5pc100.h> #include <plat/s5pv210.h> #include <plat/exynos4.h> +#include <plat/exynos5.h> /* table of supported CPUs */ @@ -33,48 +34,85 @@ static const char name_s5p6450[] = "S5P6450"; static const char name_s5pc100[] = "S5PC100"; static const char name_s5pv210[] = "S5PV210/S5PC110"; static const char name_exynos4210[] = "EXYNOS4210"; +static const char name_exynos4212[] = "EXYNOS4212"; +static const char name_exynos4412[] = "EXYNOS4412"; +static const char name_exynos5210[] = "EXYNOS5210"; +static const char name_exynos5250[] = "EXYNOS5250"; static struct cpu_table cpu_ids[] __initdata = { { - .idcode = 0x56440100, - .idmask = 0xfffff000, + .idcode = S5P6440_CPU_ID, + .idmask = S5P64XX_CPU_MASK, .map_io = s5p6440_map_io, .init_clocks = s5p6440_init_clocks, .init_uarts = s5p6440_init_uarts, .init = s5p64x0_init, .name = name_s5p6440, }, { - .idcode = 0x36450000, - .idmask = 0xfffff000, + .idcode = S5P6450_CPU_ID, + .idmask = S5P64XX_CPU_MASK, .map_io = s5p6450_map_io, .init_clocks = s5p6450_init_clocks, .init_uarts = s5p6450_init_uarts, .init = s5p64x0_init, .name = name_s5p6450, }, { - .idcode = 0x43100000, - .idmask = 0xfffff000, + .idcode = S5PC100_CPU_ID, + .idmask = S5PC100_CPU_MASK, .map_io = s5pc100_map_io, .init_clocks = s5pc100_init_clocks, .init_uarts = s5pc100_init_uarts, .init = s5pc100_init, .name = name_s5pc100, }, { - .idcode = 0x43110000, - .idmask = 0xfffff000, + .idcode = S5PV210_CPU_ID, + .idmask = S5PV210_CPU_MASK, .map_io = s5pv210_map_io, .init_clocks = s5pv210_init_clocks, .init_uarts = s5pv210_init_uarts, .init = s5pv210_init, .name = name_s5pv210, }, { - .idcode = 0x43210000, - .idmask = 0xfffe0000, + .idcode = EXYNOS4210_CPU_ID, + .idmask = EXYNOS_CPU_MASK, .map_io = exynos4_map_io, .init_clocks = exynos4_init_clocks, .init_uarts = exynos4_init_uarts, .init = exynos4_init, .name = name_exynos4210, + }, { + .idcode = EXYNOS4212_CPU_ID, + .idmask = EXYNOS_CPU_MASK, + .map_io = exynos4_map_io, + .init_clocks = exynos4_init_clocks, + .init_uarts = exynos4_init_uarts, + .init = exynos4_init, + .name = name_exynos4212, + }, { + .idcode = EXYNOS4412_CPU_ID, + .idmask = EXYNOS_CPU_MASK, + .map_io = exynos4_map_io, + .init_clocks = exynos4_init_clocks, + .init_uarts = exynos4_init_uarts, + .init = exynos4_init, + .name = name_exynos4412, + + }, { + .idcode = EXYNOS5210_CPU_ID, + .idmask = EXYNOS_CPU_MASK, + .map_io = exynos5_map_io, + .init_clocks = exynos5_init_clocks, + .init_uarts = exynos5_init_uarts, + .init = exynos5_init, + .name = name_exynos5210, + }, { + .idcode = EXYNOS5250_CPU_ID, + .idmask = EXYNOS_CPU_MASK, + .map_io = exynos5_map_io, + .init_clocks = exynos5_init_clocks, + .init_uarts = exynos5_init_uarts, + .init = exynos5_init, + .name = name_exynos5250, }, }; @@ -106,21 +144,27 @@ static struct map_desc s5p_iodesc[] __initdata = { .pfn = __phys_to_pfn(S5P_PA_SROMC), .length = SZ_4K, .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_HSPHY, + .pfn = __phys_to_pfn(S5P_PA_HSPHY), + .length = SZ_4K, + .type = MT_DEVICE, }, }; /* read cpu identification code */ +unsigned long cpu_idcode; void __init s5p_init_io(struct map_desc *mach_desc, int size, void __iomem *cpuid_addr) { - unsigned long idcode; - /* initialize the io descriptors we need for initialization */ iotable_init(s5p_iodesc, ARRAY_SIZE(s5p_iodesc)); if (mach_desc) iotable_init(mach_desc, size); - idcode = __raw_readl(cpuid_addr); - s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids)); + /* detect cpu id and rev. */ + s5p_init_cpu(cpuid_addr); + + s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids)); } diff --git a/arch/arm/plat-s5p/dev-ace.c b/arch/arm/plat-s5p/dev-ace.c new file mode 100644 index 0000000..7a9dcd7 --- /dev/null +++ b/arch/arm/plat-s5p/dev-ace.c @@ -0,0 +1,45 @@ +/* + * linux/arch/arm/plat-s5p/dev-ace.c + * + * Copyright (C) 2011 Samsung Electronics + * + * Base S5P Crypto Engine resource and device definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/platform_device.h> + +#include <mach/map.h> +#include <mach/irqs.h> + +static struct resource s5p_ace_resource[] = { + [0] = { + .start = S5P_PA_ACE, + .end = S5P_PA_ACE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, +#if defined(CONFIG_ARCH_S5PV210) + [1] = { + .start = IRQ_SSS_INT, + .end = IRQ_SSS_HASH, + .flags = IORESOURCE_IRQ, + }, +#elif defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5) + [1] = { + .start = IRQ_INTFEEDCTRL_SSS, + .end = IRQ_INTFEEDCTRL_SSS, + .flags = IORESOURCE_IRQ, + }, +#endif +}; + +struct platform_device s5p_device_ace = { + .name = "s5p-ace", + .id = 0, + .num_resources = ARRAY_SIZE(s5p_ace_resource), + .resource = s5p_ace_resource, +}; +EXPORT_SYMBOL(s5p_device_ace); diff --git a/arch/arm/plat-s5p/dev-csis-s5p.c b/arch/arm/plat-s5p/dev-csis-s5p.c new file mode 100644 index 0000000..f3a12a7 --- /dev/null +++ b/arch/arm/plat-s5p/dev-csis-s5p.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd. + * + * S5P series device definition for MIPI-CSIS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <asm/irq.h> +#include <mach/map.h> +#include <plat/devs.h> +#include <plat/cpu.h> +#include <plat/csis.h> + +static struct resource s3c_csis0_resource[] = { + [0] = { + .start = S5P_PA_MIPI_CSIS0, + .end = S5P_PA_MIPI_CSIS0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MIPICSI0, + .end = IRQ_MIPICSI0, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s3c_device_csis0 = { + .name = "s3c-csis", + .id = 0, + .num_resources = ARRAY_SIZE(s3c_csis0_resource), + .resource = s3c_csis0_resource, +}; + +static struct s3c_platform_csis default_csis0_data __initdata = { + .srclk_name = "mout_mpll", + .clk_name = "sclk_csis", + .clk_rate = 166000000, +}; + +void __init s3c_csis0_set_platdata(struct s3c_platform_csis *pd) +{ + struct s3c_platform_csis *npd; + + if (!pd) + pd = &default_csis0_data; + + npd = kmemdup(pd, sizeof(struct s3c_platform_csis), GFP_KERNEL); + if (!npd) { + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + return; + } + + if (soc_is_exynos4212() || soc_is_exynos4412()) + npd->srclk_name = "mout_mpll_user"; + npd->cfg_gpio = s3c_csis0_cfg_gpio; + npd->cfg_phy_global = s3c_csis0_cfg_phy_global; + npd->clk_on = s3c_csis_clk_on; + npd->clk_off = s3c_csis_clk_off; + s3c_device_csis0.dev.platform_data = npd; +} +static struct resource s3c_csis1_resource[] = { + [0] = { + .start = S5P_PA_MIPI_CSIS1, + .end = S5P_PA_MIPI_CSIS1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MIPICSI1, + .end = IRQ_MIPICSI1, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s3c_device_csis1 = { + .name = "s3c-csis", + .id = 1, + .num_resources = ARRAY_SIZE(s3c_csis1_resource), + .resource = s3c_csis1_resource, +}; + +static struct s3c_platform_csis default_csis1_data __initdata = { + .srclk_name = "mout_mpll", + .clk_name = "sclk_csis", + .clk_rate = 166000000, +}; + +void __init s3c_csis1_set_platdata(struct s3c_platform_csis *pd) +{ + struct s3c_platform_csis *npd; + + if (!pd) + pd = &default_csis1_data; + + npd = kmemdup(pd, sizeof(struct s3c_platform_csis), GFP_KERNEL); + if (!npd) { + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + return; + } + + if (soc_is_exynos4212() || soc_is_exynos4412()) + npd->srclk_name = "mout_mpll_user"; + npd->cfg_gpio = s3c_csis1_cfg_gpio; + npd->cfg_phy_global = s3c_csis1_cfg_phy_global; + npd->clk_on = s3c_csis_clk_on; + npd->clk_off = s3c_csis_clk_off; + s3c_device_csis1.dev.platform_data = npd; +} diff --git a/arch/arm/plat-s5p/dev-csis0.c b/arch/arm/plat-s5p/dev-csis0.c index e3aabef..a071c7b 100644 --- a/arch/arm/plat-s5p/dev-csis0.c +++ b/arch/arm/plat-s5p/dev-csis0.c @@ -12,16 +12,17 @@ #include <linux/interrupt.h> #include <linux/platform_device.h> #include <mach/map.h> +#include <plat/mipi_csis.h> static struct resource s5p_mipi_csis0_resource[] = { [0] = { .start = S5P_PA_MIPI_CSIS0, - .end = S5P_PA_MIPI_CSIS0 + SZ_4K - 1, + .end = S5P_PA_MIPI_CSIS0 + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = IRQ_MIPI_CSIS0, - .end = IRQ_MIPI_CSIS0, + .start = IRQ_MIPICSI0, + .end = IRQ_MIPICSI0, .flags = IORESOURCE_IRQ, } }; @@ -32,3 +33,11 @@ struct platform_device s5p_device_mipi_csis0 = { .num_resources = ARRAY_SIZE(s5p_mipi_csis0_resource), .resource = s5p_mipi_csis0_resource, }; + +struct s5p_platform_mipi_csis s5p_mipi_csis0_default_data __initdata = { + .clk_rate = 166000000, + .lanes = 2, + .alignment = 32, + .hs_settle = 12, + .phy_enable = s5p_csis_phy_enable, +}; diff --git a/arch/arm/plat-s5p/dev-csis1.c b/arch/arm/plat-s5p/dev-csis1.c index 08b91b5..5cf9efa 100644 --- a/arch/arm/plat-s5p/dev-csis1.c +++ b/arch/arm/plat-s5p/dev-csis1.c @@ -12,16 +12,17 @@ #include <linux/interrupt.h> #include <linux/platform_device.h> #include <mach/map.h> +#include <plat/mipi_csis.h> static struct resource s5p_mipi_csis1_resource[] = { [0] = { .start = S5P_PA_MIPI_CSIS1, - .end = S5P_PA_MIPI_CSIS1 + SZ_4K - 1, + .end = S5P_PA_MIPI_CSIS1 + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = IRQ_MIPI_CSIS1, - .end = IRQ_MIPI_CSIS1, + .start = IRQ_MIPICSI1, + .end = IRQ_MIPICSI1, .flags = IORESOURCE_IRQ, }, }; @@ -32,3 +33,11 @@ struct platform_device s5p_device_mipi_csis1 = { .num_resources = ARRAY_SIZE(s5p_mipi_csis1_resource), .resource = s5p_mipi_csis1_resource, }; + +struct s5p_platform_mipi_csis s5p_mipi_csis1_default_data __initdata = { + .clk_rate = 166000000, + .lanes = 2, + .alignment = 32, + .hs_settle = 12, + .phy_enable = s5p_csis_phy_enable, +}; diff --git a/arch/arm/plat-s5p/dev-dp.c b/arch/arm/plat-s5p/dev-dp.c new file mode 100644 index 0000000..1132e78 --- /dev/null +++ b/arch/arm/plat-s5p/dev-dp.c @@ -0,0 +1,52 @@ +/* linux/arch/arm/plat-s5p/dev-dp.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Base S5P DP resource and device definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <video/s5p-dp.h> +#include <mach/map.h> +#include <plat/devs.h> +#include <plat/dp.h> + +static struct resource s5p_dp_resource[] = { + [0] = { + .start = S5P_PA_DP, + .end = S5P_PA_DP + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_DP, + .end = IRQ_DP, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 s5p_dp_dma_mask = DMA_BIT_MASK(32); + +struct platform_device s5p_device_dp = { + .name = "s5p-dp", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_dp_resource), + .resource = s5p_dp_resource, + .dev = { + .dma_mask = &s5p_dp_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s5p_dp_set_platdata(struct s5p_dp_platdata *pd) +{ + s3c_set_platdata(pd, sizeof(struct s5p_dp_platdata), + &s5p_device_dp); +} diff --git a/arch/arm/plat-s5p/dev-dsim.c b/arch/arm/plat-s5p/dev-dsim.c new file mode 100644 index 0000000..0467c63 --- /dev/null +++ b/arch/arm/plat-s5p/dev-dsim.c @@ -0,0 +1,110 @@ +/* linux/arch/arm/plat-s5p/dev-dsim.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * DSIM controller configuration + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <asm/irq.h> +#include <plat/devs.h> +#include <plat/cpu.h> +#include <mach/map.h> +#include <mach/dsim.h> +#include <mach/mipi_ddi.h> +#include <linux/regulator/machine.h> + +static struct dsim_config dsim_info = { + .auto_flush = false, /* main frame fifo auto flush at VSYNC pulse */ + + .eot_disable = false, /* only DSIM_1_02 or DSIM_1_03 */ + + .auto_vertical_cnt = false, + .hse = false, + .hfp = true, + .hbp = false, + .hsa = false, + + .e_no_data_lane = DSIM_DATA_LANE_4, + .e_byte_clk = DSIM_PLL_OUT_DIV8, + +#ifdef CONFIG_MACH_JENGA + .p = 3, + .m = 75, + .s = 0, +#endif + + .pll_stable_time = 500, /* D-PHY PLL stable time spec :min = 200usec ~ max 400usec */ + +#ifdef CONFIG_MACH_JENGA + .esc_clk = 10 * 1000000, /* escape clk : 10MHz */ +#else + .esc_clk = 20 * 1000000, /* escape clk : 10MHz */ +#endif + + .stop_holding_cnt = 0, /* stop state holding counter after bta change count 0 ~ 0xfff */ + .bta_timeout = 0xff, /* bta timeout 0 ~ 0xff */ + .rx_timeout = 0xffff, /* lp rx timeout 0 ~ 0xffff */ + + .e_lane_swap = DSIM_NO_CHANGE, +}; + +/* define ddi platform data based on MIPI-DSI. */ +static struct mipi_ddi_platform_data mipi_ddi_pd = { + .backlight_on = NULL, +}; + +static struct dsim_lcd_config dsim_lcd_info = { + .e_interface = DSIM_VIDEO, + + .parameter[DSI_VIRTUAL_CH_ID] = (unsigned int) DSIM_VIRTUAL_CH_0, + .parameter[DSI_FORMAT] = (unsigned int) DSIM_24BPP_888, + .parameter[DSI_VIDEO_MODE_SEL] = (unsigned int) DSIM_BURST_SYNC_EVENT, + .mipi_ddi_pd = (void *) &mipi_ddi_pd, +}; + +static struct resource s5p_dsim_resource[] = { + [0] = { + .start = S5P_PA_DSIM0, + .end = S5P_PA_DSIM0 + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MIPIDSI0, + .end = IRQ_MIPIDSI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s5p_platform_dsim dsim_platform_data = { + .clk_name = "dsim0", + .dsim_info = &dsim_info, + .dsim_lcd_info = &dsim_lcd_info, + .mipi_power = NULL, + .enable_clk = s5p_dsim_enable_clk, + .part_reset = s5p_dsim_part_reset, + .init_d_phy = s5p_dsim_init_d_phy, + .exit_d_phy = s5p_dsim_exit_d_phy, + + /* default platform revision is 0(evt0). */ + .platform_rev = 0, + .cfg_gpio = exynos4_dsim_gpio_setup_24bpp, +}; + +struct platform_device s5p_device_dsim = { + .name = "s5p-dsim", + .id = 0, + .num_resources = ARRAY_SIZE(s5p_dsim_resource), + .resource = s5p_dsim_resource, + .dev = { + .platform_data = (void *) &dsim_platform_data, + }, +}; diff --git a/arch/arm/plat-s5p/dev-dsim02.c b/arch/arm/plat-s5p/dev-dsim02.c new file mode 100644 index 0000000..2216446 --- /dev/null +++ b/arch/arm/plat-s5p/dev-dsim02.c @@ -0,0 +1,47 @@ +/* linux/arch/arm/plat-s5pc11x/dev-dsim0.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd + * + * InKi Dae <inki.dae@samsung.com> + * + * device definitions for Samsung SoC MIPI-DSIM. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/fb.h> + +#include <mach/map.h> +#include <asm/irq.h> + +#include <plat/devs.h> +#include <plat/cpu.h> +#include <plat/fb.h> + +#include <plat/mipi_dsim2.h> + +static struct resource s5p_mipi_dsim_resource[] = { + [0] = { + .start = EXYNOS4_PA_DSIM0, + .end = EXYNOS4_PA_DSIM0 + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MIPIDSI0, + .end = IRQ_MIPIDSI0, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s5p_device_mipi_dsim0 = { + .name = "s5p-mipi-dsim", + .id = 0, + .num_resources = ARRAY_SIZE(s5p_mipi_dsim_resource), + .resource = s5p_mipi_dsim_resource, +}; diff --git a/arch/arm/plat-s5p/dev-dsim12.c b/arch/arm/plat-s5p/dev-dsim12.c new file mode 100644 index 0000000..35409c9 --- /dev/null +++ b/arch/arm/plat-s5p/dev-dsim12.c @@ -0,0 +1,52 @@ +/* linux/arch/arm/plat-s5pc11x/dev-dsim1.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd + * + * InKi Dae <inki.dae@samsung.com> + * + * device definitions for Samsung SoC MIPI-DSIM. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/fb.h> + +#include <mach/map.h> +#include <asm/irq.h> + +#include <plat/devs.h> +#include <plat/cpu.h> +#include <plat/fb.h> + +#include <plat/mipi_dsim2.h> + +static struct resource s5p_mipi_dsim_resource[] = { + [0] = { + .start = S5P_PA_MIPI_DSIM1, + .end = S5P_PA_MIPI_DSIM1 + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MIPIDSI, + .end = IRQ_MIPIDSI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s5p_platform_mipi_dsim dsim_platform_data = { + .phy_enable = s5p_dsim_phy_enable, + .dsim_config = &dsim_config, +}; + +struct platform_device s5p_device_mipi_dsim1 = { + .name = "s5p-mipi-dsim", + .id = 1, + .num_resources = ARRAY_SIZE(s5p_mipi_dsim_resource), + .resource = s5p_mipi_dsim_resource, +}; diff --git a/arch/arm/plat-s5p/dev-ehci.c b/arch/arm/plat-s5p/dev-ehci.c index 94080ff..5c5f5a5 100644 --- a/arch/arm/plat-s5p/dev-ehci.c +++ b/arch/arm/plat-s5p/dev-ehci.c @@ -12,9 +12,13 @@ #include <linux/platform_device.h> #include <mach/irqs.h> #include <mach/map.h> +#include <mach/gpio.h> #include <plat/devs.h> #include <plat/ehci.h> #include <plat/usb-phy.h> +#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) +#include <mach/sec_modem.h> +#endif /* USB EHCI Host Controller registration */ static struct resource s5p_ehci_resource[] = { @@ -54,4 +58,58 @@ void __init s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd) npd->phy_init = s5p_usb_phy_init; if (!npd->phy_exit) npd->phy_exit = s5p_usb_phy_exit; + if (!npd->phy_suspend) + npd->phy_suspend = s5p_usb_phy_suspend; + if (!npd->phy_resume) + npd->phy_resume = s5p_usb_phy_resume; +#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) + if (!npd->noti_host_states) + npd->noti_host_states = set_host_states; + if (!npd->get_cp_active_state) + npd->get_cp_active_state = get_cp_active_state; +#endif +} + +/* USB Host Controlle OHCI registrations */ +static struct resource s5p_ohci_resource[] = { + [0] = { + .start = S5P_PA_OHCI, + .end = S5P_PA_OHCI + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USB_HOST, + .end = IRQ_USB_HOST, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 s5p_device_ohci_dmamask = 0xffffffffUL; + +struct platform_device s5p_device_ohci = { + .name = "s5p-ohci", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_ohci_resource), + .resource = s5p_ohci_resource, + .dev = { + .dma_mask = &s5p_device_ohci_dmamask, + .coherent_dma_mask = 0xffffffffUL + } +}; + +void __init s5p_ohci_set_platdata(struct s5p_ohci_platdata *pd) +{ + struct s5p_ohci_platdata *npd; + + npd = s3c_set_platdata(pd, sizeof(struct s5p_ohci_platdata), + &s5p_device_ohci); + + if (!npd->phy_init) + npd->phy_init = s5p_usb_phy_init; + if (!npd->phy_exit) + npd->phy_exit = s5p_usb_phy_exit; + if (!npd->phy_suspend) + npd->phy_suspend = s5p_usb_phy_suspend; + if (!npd->phy_resume) + npd->phy_resume = s5p_usb_phy_resume; } diff --git a/arch/arm/plat-s5p/dev-fimc-s5p.c b/arch/arm/plat-s5p/dev-fimc-s5p.c new file mode 100644 index 0000000..53a256d --- /dev/null +++ b/arch/arm/plat-s5p/dev-fimc-s5p.c @@ -0,0 +1,225 @@ +/* linux/arch/arm/plat-s5p/dev-fimc-s5p.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Device definition for FIMC device + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <mach/map.h> +#include <asm/irq.h> +#include <plat/devs.h> +#include <plat/cpu.h> +#include <plat/fimc.h> + +static struct resource s3c_fimc0_resource[] = { + [0] = { + .start = S5P_PA_FIMC0, + .end = S5P_PA_FIMC0 + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_FIMC0, + .end = IRQ_FIMC0, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s3c_device_fimc0 = { + .name = "s3c-fimc", + .id = 0, + .num_resources = ARRAY_SIZE(s3c_fimc0_resource), + .resource = s3c_fimc0_resource, +}; + +static struct s3c_platform_fimc default_fimc0_data __initdata = { + .default_cam = CAMERA_PAR_A, + .hw_ver = 0x51, +}; + +void __init s3c_fimc0_set_platdata(struct s3c_platform_fimc *pd) +{ + struct s3c_platform_fimc *npd; + + if (!pd) + pd = &default_fimc0_data; + + npd = kmemdup(pd, sizeof(struct s3c_platform_fimc), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + else { + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_fimc0_cfg_gpio; + + if (!npd->clk_on) + npd->clk_on = s3c_fimc_clk_on; + + if (!npd->clk_off) + npd->clk_off = s3c_fimc_clk_off; + + npd->hw_ver = 0x51; + npd->use_cam = true; + s3c_device_fimc0.dev.platform_data = npd; + } +} + +static struct resource s3c_fimc1_resource[] = { + [0] = { + .start = S5P_PA_FIMC1, + .end = S5P_PA_FIMC1 + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_FIMC1, + .end = IRQ_FIMC1, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s3c_device_fimc1 = { + .name = "s3c-fimc", + .id = 1, + .num_resources = ARRAY_SIZE(s3c_fimc1_resource), + .resource = s3c_fimc1_resource, +}; + +static struct s3c_platform_fimc default_fimc1_data __initdata = { + .default_cam = CAMERA_PAR_A, + .hw_ver = 0x51, +}; + +void __init s3c_fimc1_set_platdata(struct s3c_platform_fimc *pd) +{ + struct s3c_platform_fimc *npd; + + if (!pd) + pd = &default_fimc1_data; + + npd = kmemdup(pd, sizeof(struct s3c_platform_fimc), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + else { + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_fimc1_cfg_gpio; + + if (!npd->clk_on) + npd->clk_on = s3c_fimc_clk_on; + + if (!npd->clk_off) + npd->clk_off = s3c_fimc_clk_off; + + npd->hw_ver = 0x51; + npd->use_cam = false; + s3c_device_fimc1.dev.platform_data = npd; + } +} + +static struct resource s3c_fimc2_resource[] = { + [0] = { + .start = S5P_PA_FIMC2, + .end = S5P_PA_FIMC2 + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_FIMC2, + .end = IRQ_FIMC2, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s3c_device_fimc2 = { + .name = "s3c-fimc", + .id = 2, + .num_resources = ARRAY_SIZE(s3c_fimc2_resource), + .resource = s3c_fimc2_resource, +}; + +static struct s3c_platform_fimc default_fimc2_data __initdata = { + .default_cam = CAMERA_PAR_A, + .hw_ver = 0x51, +}; + +void __init s3c_fimc2_set_platdata(struct s3c_platform_fimc *pd) +{ + struct s3c_platform_fimc *npd; + + if (!pd) + pd = &default_fimc2_data; + + npd = kmemdup(pd, sizeof(struct s3c_platform_fimc), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + else { + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_fimc2_cfg_gpio; + + if (!npd->clk_on) + npd->clk_on = s3c_fimc_clk_on; + + if (!npd->clk_off) + npd->clk_off = s3c_fimc_clk_off; + + npd->hw_ver = 0x51; + npd->use_cam = false; + s3c_device_fimc2.dev.platform_data = npd; + } +} + +static struct resource s3c_fimc3_resource[] = { + [0] = { + .start = S5P_PA_FIMC3, + .end = S5P_PA_FIMC3 + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_FIMC3, + .end = IRQ_FIMC3, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s3c_device_fimc3 = { + .name = "s3c-fimc", + .id = 3, + .num_resources = ARRAY_SIZE(s3c_fimc3_resource), + .resource = s3c_fimc3_resource, +}; + +static struct s3c_platform_fimc default_fimc3_data __initdata = { + .default_cam = CAMERA_PAR_A, + .hw_ver = 0x51, +}; + +void __init s3c_fimc3_set_platdata(struct s3c_platform_fimc *pd) +{ + struct s3c_platform_fimc *npd; + + if (!pd) + pd = &default_fimc3_data; + + npd = kmemdup(pd, sizeof(struct s3c_platform_fimc), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + else { + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_fimc3_cfg_gpio; + + if (!npd->clk_on) + npd->clk_on = s3c_fimc_clk_on; + + if (!npd->clk_off) + npd->clk_off = s3c_fimc_clk_off; + + npd->hw_ver = 0x51; + npd->use_cam = false; + s3c_device_fimc3.dev.platform_data = npd; + } +} + diff --git a/arch/arm/plat-s5p/dev-fimc0.c b/arch/arm/plat-s5p/dev-fimc0.c index 608770f..4045b9a 100644 --- a/arch/arm/plat-s5p/dev-fimc0.c +++ b/arch/arm/plat-s5p/dev-fimc0.c @@ -15,6 +15,7 @@ #include <linux/interrupt.h> #include <linux/ioport.h> #include <mach/map.h> +#include <media/s5p_fimc.h> static struct resource s5p_fimc0_resource[] = { [0] = { @@ -41,3 +42,5 @@ struct platform_device s5p_device_fimc0 = { .coherent_dma_mask = DMA_BIT_MASK(32), }, }; + +struct s5p_platform_fimc s3c_fimc0_default_data __initdata; diff --git a/arch/arm/plat-s5p/dev-fimc1.c b/arch/arm/plat-s5p/dev-fimc1.c index 76e3a97..c33fbce 100644 --- a/arch/arm/plat-s5p/dev-fimc1.c +++ b/arch/arm/plat-s5p/dev-fimc1.c @@ -15,6 +15,7 @@ #include <linux/interrupt.h> #include <linux/ioport.h> #include <mach/map.h> +#include <media/s5p_fimc.h> static struct resource s5p_fimc1_resource[] = { [0] = { @@ -41,3 +42,5 @@ struct platform_device s5p_device_fimc1 = { .coherent_dma_mask = DMA_BIT_MASK(32), }, }; + +struct s5p_platform_fimc s3c_fimc1_default_data __initdata; diff --git a/arch/arm/plat-s5p/dev-fimc2.c b/arch/arm/plat-s5p/dev-fimc2.c index 24d2981..ed98127 100644 --- a/arch/arm/plat-s5p/dev-fimc2.c +++ b/arch/arm/plat-s5p/dev-fimc2.c @@ -15,6 +15,7 @@ #include <linux/interrupt.h> #include <linux/ioport.h> #include <mach/map.h> +#include <media/s5p_fimc.h> static struct resource s5p_fimc2_resource[] = { [0] = { @@ -41,3 +42,5 @@ struct platform_device s5p_device_fimc2 = { .coherent_dma_mask = DMA_BIT_MASK(32), }, }; + +struct s5p_platform_fimc s3c_fimc2_default_data __initdata; diff --git a/arch/arm/plat-s5p/dev-fimc3.c b/arch/arm/plat-s5p/dev-fimc3.c index ef31bec..8fb3f01 100644 --- a/arch/arm/plat-s5p/dev-fimc3.c +++ b/arch/arm/plat-s5p/dev-fimc3.c @@ -15,6 +15,7 @@ #include <linux/interrupt.h> #include <linux/ioport.h> #include <mach/map.h> +#include <media/s5p_fimc.h> static struct resource s5p_fimc3_resource[] = { [0] = { @@ -41,3 +42,5 @@ struct platform_device s5p_device_fimc3 = { .coherent_dma_mask = DMA_BIT_MASK(32), }, }; + +struct s5p_platform_fimc s3c_fimc3_default_data __initdata; diff --git a/arch/arm/plat-s5p/dev-fimd-s5p.c b/arch/arm/plat-s5p/dev-fimd-s5p.c new file mode 100644 index 0000000..80d0bfd --- /dev/null +++ b/arch/arm/plat-s5p/dev-fimd-s5p.c @@ -0,0 +1,104 @@ +/* linux/arch/arm/plat-s5p/dev-fimd-s5p.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Base S5P platform device definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/interrupt.h> +#include <linux/platform_device.h> + +#include <mach/map.h> +#include <plat/fb-s5p.h> + +#ifdef CONFIG_FB_S5P +static struct resource s3cfb_resource[] = { + [0] = { + .start = S5P_PA_FIMD0, + .end = S5P_PA_FIMD0 + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_FIMD0_VSYNC, + .end = IRQ_FIMD0_VSYNC, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_FIMD0_FIFO, + .end = IRQ_FIMD0_FIFO, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 fb_dma_mask = 0xffffffffUL; + +struct platform_device s3c_device_fb = { + .name = "s3cfb", +#if defined(CONFIG_ARCH_EXYNOS4) + .id = 0, +#else + .id = -1, +#endif + .num_resources = ARRAY_SIZE(s3cfb_resource), + .resource = s3cfb_resource, + .dev = { + .dma_mask = &fb_dma_mask, + .coherent_dma_mask = 0xffffffffUL + } +}; + +static struct s3c_platform_fb default_fb_data __initdata = { +#if defined(CONFIG_ARCH_EXYNOS4) + .hw_ver = 0x70, +#else + .hw_ver = 0x62, +#endif + .nr_wins = 5, +#if defined(CONFIG_FB_S5P_DEFAULT_WINDOW) + .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW, +#else + .default_win = 0, +#endif + .swap = FB_SWAP_WORD | FB_SWAP_HWORD, +}; + +void __init s3cfb_set_platdata(struct s3c_platform_fb *pd) +{ + struct s3c_platform_fb *npd; + int i; + + if (!pd) + pd = &default_fb_data; + + npd = kmemdup(pd, sizeof(struct s3c_platform_fb), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + else { + for (i = 0; i < npd->nr_wins; i++) + npd->nr_buffers[i] = 1; + +#if defined(CONFIG_FB_S5P_NR_BUFFERS) + npd->nr_buffers[npd->default_win] = CONFIG_FB_S5P_NR_BUFFERS; +#else + npd->nr_buffers[npd->default_win] = 1; +#endif + + s3cfb_get_clk_name(npd->clk_name); + npd->cfg_gpio = s3cfb_cfg_gpio; + npd->backlight_on = s3cfb_backlight_on; + npd->backlight_off = s3cfb_backlight_off; + npd->lcd_on = s3cfb_lcd_on; + npd->lcd_off = s3cfb_lcd_off; + npd->clk_on = s3cfb_clk_on; + npd->clk_off = s3cfb_clk_off; + + s3c_device_fb.dev.platform_data = npd; + } +} +#endif + diff --git a/arch/arm/plat-s5p/dev-fimd0.c b/arch/arm/plat-s5p/dev-fimd0.c new file mode 100644 index 0000000..9e7176c --- /dev/null +++ b/arch/arm/plat-s5p/dev-fimd0.c @@ -0,0 +1,67 @@ +/* linux/arch/arm/plat-s5p/dev-fimd0.c + * + * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Core file for Samsung Display Controller (FIMD) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <linux/fb.h> +#include <linux/gfp.h> +#include <linux/dma-mapping.h> + +#include <mach/irqs.h> +#include <mach/map.h> + +#include <plat/fb.h> +#include <plat/devs.h> +#include <plat/cpu.h> + +static struct resource s5p_fimd0_resource[] = { + [0] = { + .start = S5P_PA_FIMD0, + .end = S5P_PA_FIMD0 + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_FIMD0_VSYNC, + .end = IRQ_FIMD0_VSYNC, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_FIMD0_FIFO, + .end = IRQ_FIMD0_FIFO, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_FIMD0_SYSTEM, + .end = IRQ_FIMD0_SYSTEM, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 fimd0_dmamask = DMA_BIT_MASK(32); + +struct platform_device s5p_device_fimd0 = { + .name = "s5p-fb", + .id = 0, + .num_resources = ARRAY_SIZE(s5p_fimd0_resource), + .resource = s5p_fimd0_resource, + .dev = { + .dma_mask = &fimd0_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd) +{ + s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata), + &s5p_device_fimd0); +} diff --git a/arch/arm/plat-s5p/dev-fimd1.c b/arch/arm/plat-s5p/dev-fimd1.c new file mode 100644 index 0000000..e00b635 --- /dev/null +++ b/arch/arm/plat-s5p/dev-fimd1.c @@ -0,0 +1,71 @@ +/* linux/arch/arm/plat-s5p/dev-fimd1.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Core file for Samsung Display Controller (FIMD) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <linux/fb.h> +#include <linux/gfp.h> +#include <linux/dma-mapping.h> + +#include <mach/irqs.h> +#include <mach/map.h> + +#include <plat/fb.h> +#include <plat/devs.h> +#include <plat/cpu.h> + +static struct resource s5p_fimd1_resource[] = { + [0] = { + .start = S5P_PA_FIMD1, +#ifdef CONFIG_FB_EXYNOS_FIMD_V8 + .end = S5P_PA_FIMD1 + SZ_256K - 1, +#else + .end = S5P_PA_FIMD1 + SZ_32K - 1, +#endif + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_FIMD1_VSYNC, + .end = IRQ_FIMD1_VSYNC, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_FIMD1_FIFO, + .end = IRQ_FIMD1_FIFO, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_FIMD1_SYSTEM, + .end = IRQ_FIMD1_SYSTEM, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 fimd1_dmamask = DMA_BIT_MASK(32); + +struct platform_device s5p_device_fimd1 = { + .name = "s5p-fb", + .id = 1, + .num_resources = ARRAY_SIZE(s5p_fimd1_resource), + .resource = s5p_fimd1_resource, + .dev = { + .dma_mask = &fimd1_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s5p_fimd1_set_platdata(struct s3c_fb_platdata *pd) +{ + s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata), + &s5p_device_fimd1); +} diff --git a/arch/arm/plat-s5p/dev-fimg2d.c b/arch/arm/plat-s5p/dev-fimg2d.c new file mode 100644 index 0000000..35896ff --- /dev/null +++ b/arch/arm/plat-s5p/dev-fimg2d.c @@ -0,0 +1,75 @@ +/* linux/arch/arm/plat-s5p/dev-fimg2d.c + * + * Copyright (c) 2010 Samsung Electronics + * + * Base S5P FIMG2D resource and device definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <plat/fimg2d.h> +#include <plat/cpu.h> +#include <mach/map.h> + +#define S5P_PA_FIMG2D_OFFSET 0x02000000 +#define S5P_PA_FIMG2D_3X (S5P_PA_FIMG2D+S5P_PA_FIMG2D_OFFSET) + +static struct resource s5p_fimg2d_resource[] = { + [0] = { + .start = S5P_PA_FIMG2D, + .end = S5P_PA_FIMG2D + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_2D, + .end = IRQ_2D, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 s5p_device_fimg2d_dmamask = 0xffffffffUL; + +struct platform_device s5p_device_fimg2d = { + .name = "s5p-fimg2d", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_fimg2d_resource), + .resource = s5p_fimg2d_resource, + .dev = { + .dma_mask = &s5p_device_fimg2d_dmamask, + .coherent_dma_mask = 0xffffffffUL, + }, +}; +EXPORT_SYMBOL(s5p_device_fimg2d); + +static struct fimg2d_platdata default_fimg2d_data __initdata = { + .parent_clkname = "mout_g2d0", + .clkname = "sclk_fimg2d", + .gate_clkname = "fimg2d", + .clkrate = 250 * 1000000, +}; + +void __init s5p_fimg2d_set_platdata(struct fimg2d_platdata *pd) +{ + struct fimg2d_platdata *npd; + + if (soc_is_exynos4210()) { + s5p_fimg2d_resource[0].start = S5P_PA_FIMG2D_3X; + s5p_fimg2d_resource[0].end = S5P_PA_FIMG2D_3X + SZ_4K - 1; + } + + if (!pd) + pd = &default_fimg2d_data; + + npd = kmemdup(pd, sizeof(*pd), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "no memory for fimg2d platform data\n"); + else + s5p_device_fimg2d.dev.platform_data = npd; +} diff --git a/arch/arm/plat-s5p/dev-i2c-hdmiphy.c b/arch/arm/plat-s5p/dev-i2c-hdmiphy.c new file mode 100644 index 0000000..9dd0ff3 --- /dev/null +++ b/arch/arm/plat-s5p/dev-i2c-hdmiphy.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P series device definition for i2c for hdmiphy device + * + * Based on plat-samsung/dev-i2c7.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/gfp.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/platform_device.h> + +#include <mach/irqs.h> +#include <mach/map.h> +#include <mach/iic-hdmiphy.h> + +#include <plat/regs-iic.h> +#include <plat/devs.h> +#include <plat/cpu.h> +#include <plat/iic.h> + +static struct resource s5p_i2c_resource[] = { + [0] = { + .start = S5P_PA_IIC_HDMIPHY, + .end = S5P_PA_IIC_HDMIPHY + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IIC_HDMIPHY, + .end = IRQ_IIC_HDMIPHY, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s5p_device_i2c_hdmiphy = { + .name = "s3c2440-hdmiphy-i2c", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_i2c_resource), + .resource = s5p_i2c_resource, +}; +EXPORT_SYMBOL(s5p_device_i2c_hdmiphy); + +void __init s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *pd) +{ + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = S5P_IIC_HDMIPHY_BUS_NUM; + } + + s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c), + &s5p_device_i2c_hdmiphy); +} +EXPORT_SYMBOL(s5p_i2c_hdmiphy_set_platdata); diff --git a/arch/arm/plat-s5p/dev-jpeg.c b/arch/arm/plat-s5p/dev-jpeg.c new file mode 100644 index 0000000..b14eca5 --- /dev/null +++ b/arch/arm/plat-s5p/dev-jpeg.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd. + * + * S5P series device definition for JPEG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <mach/map.h> + +static struct resource s5p_jpeg_resource[] = { + [0] = { + .start = S5P_PA_JPEG, + .end = S5P_PA_JPEG + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_JPEG, + .end = IRQ_JPEG, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device s5p_device_jpeg = { + .name = "s5p-jpeg", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_jpeg_resource), + .resource = s5p_jpeg_resource, +}; +EXPORT_SYMBOL(s5p_device_jpeg); diff --git a/arch/arm/plat-s5p/dev-mfc.c b/arch/arm/plat-s5p/dev-mfc.c new file mode 100644 index 0000000..e6b9483 --- /dev/null +++ b/arch/arm/plat-s5p/dev-mfc.c @@ -0,0 +1,38 @@ +/* linux/arch/arm/plat-s5p/dev-mfc.c + * + * Copyright (c) 2011 Samsung Electronics + * + * Base S5P MFC resource and device definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <mach/map.h> + +static struct resource s5p_mfc_resource[] = { + [0] = { + .start = S5P_PA_MFC, + .end = S5P_PA_MFC + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MFC, + .end = IRQ_MFC, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s5p_device_mfc = { + .name = "s3c-mfc", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_mfc_resource), + .resource = s5p_mfc_resource, +}; + diff --git a/arch/arm/plat-s5p/dev-mipidsim.c b/arch/arm/plat-s5p/dev-mipidsim.c new file mode 100644 index 0000000..c8c38b5 --- /dev/null +++ b/arch/arm/plat-s5p/dev-mipidsim.c @@ -0,0 +1,53 @@ +/* linux/arch/arm/plat-s5p/dev-mipidsim.c + * + * Copyright (c) 2011 Samsung Electronics + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/fb.h> + +#include <mach/map.h> +#include <mach/irqs.h> +#include <mach/regs-clock.h> + +#include <plat/devs.h> +#include <plat/cpu.h> +#include <plat/fb.h> + +#include <plat/dsim.h> +#include <plat/mipi_dsi.h> + +static struct resource s5p_dsim_resource[] = { + [0] = { + .start = S5P_PA_DSIM0, + .end = S5P_PA_DSIM0 + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MIPIDSI0, + .end = IRQ_MIPIDSI0, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s5p_device_mipi_dsim = { + .name = "s5p-mipi-dsim", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_dsim_resource), + .resource = s5p_dsim_resource, + .dev = { + .platform_data = NULL, + }, +}; + +void __init s5p_dsim_set_platdata(struct s5p_platform_mipi_dsim *pd) { + s3c_set_platdata(pd, sizeof(struct s5p_platform_mipi_dsim), &s5p_device_mipi_dsim); +} diff --git a/arch/arm/plat-s5p/dev-pmu.c b/arch/arm/plat-s5p/dev-pmu.c index a08576d..2880f47 100644 --- a/arch/arm/plat-s5p/dev-pmu.c +++ b/arch/arm/plat-s5p/dev-pmu.c @@ -15,22 +15,49 @@ #include <asm/pmu.h> #include <mach/irqs.h> -static struct resource s5p_pmu_resource = { - .start = IRQ_PMU, - .end = IRQ_PMU, - .flags = IORESOURCE_IRQ, +static struct resource s5p_pmu_resource[] = { + { + .start = IRQ_PMU, + .end = IRQ_PMU, + .flags = IORESOURCE_IRQ, + }, +#if CONFIG_NR_CPUS > 1 + { + .start = IRQ_PMU_CPU1, + .end = IRQ_PMU_CPU1, + .flags = IORESOURCE_IRQ, + }, +#endif +#if CONFIG_NR_CPUS > 2 + { + .start = IRQ_PMU_CPU2, + .end = IRQ_PMU_CPU2, + .flags = IORESOURCE_IRQ, + }, { + .start = IRQ_PMU_CPU3, + .end = IRQ_PMU_CPU3, + .flags = IORESOURCE_IRQ, + }, +#endif }; struct platform_device s5p_device_pmu = { .name = "arm-pmu", .id = ARM_PMU_DEVICE_CPU, - .num_resources = 1, - .resource = &s5p_pmu_resource, + .num_resources = ARRAY_SIZE(s5p_pmu_resource), + .resource = s5p_pmu_resource, }; static int __init s5p_pmu_init(void) { - platform_device_register(&s5p_device_pmu); + int ret; + + ret = platform_device_register(&s5p_device_pmu); + if (ret) { + pr_warning("s5p_pmu_init: pmu device not registered.\n"); + return ret; + } + return 0; } arch_initcall(s5p_pmu_init); diff --git a/arch/arm/plat-s5p/dev-rotator.c b/arch/arm/plat-s5p/dev-rotator.c new file mode 100644 index 0000000..5ff8e70 --- /dev/null +++ b/arch/arm/plat-s5p/dev-rotator.c @@ -0,0 +1,42 @@ +/* linux/arch/arm/plat-s5p/dev-rotator.c + * + * Copyright (c) 2011 Samsung Electronics + * + * Base S5P Rotator resource and device definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <mach/map.h> + +static struct resource exynos_rot_resource[] = { + [0] = { + .start = EXYNOS_PA_ROTATOR, + .end = EXYNOS_PA_ROTATOR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_ROTATOR, + .end = IRQ_ROTATOR, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 exynos_rot_dma_mask = DMA_BIT_MASK(32); + +struct platform_device exynos_device_rotator = { + .name = "exynos-rot", + .id = -1, + .num_resources = ARRAY_SIZE(exynos_rot_resource), + .resource = exynos_rot_resource, + .dev = { + .dma_mask = &exynos_rot_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; diff --git a/arch/arm/plat-s5p/dev-tmu.c b/arch/arm/plat-s5p/dev-tmu.c new file mode 100644 index 0000000..ea330cd --- /dev/null +++ b/arch/arm/plat-s5p/dev-tmu.c @@ -0,0 +1,118 @@ +/* linux/arch/arm/plat-s5p/dev-tmu.c + * + * Copyright 2009 by SAMSUNG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +#include <asm/irq.h> + +#include <mach/irqs.h> +#include <mach/map.h> + +#include <plat/devs.h> +#include <plat/s5p-tmu.h> + +static struct resource s5p_tmu_resource[] = { + [0] = { + .start = S5P_PA_TMU, + .end = S5P_PA_TMU + 0xFFFF - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TMU, + .end = IRQ_TMU, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device s5p_device_tmu = { + .name = "s5p-tmu", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_tmu_resource), + .resource = s5p_tmu_resource, +}; + +/* + * The below temperature value is derived from testing smdk4x12 board + * in chamber + * 78 degree : threshold temp + * 87 degree : throttling temperature + * 103 degree : Waring temperature + * 110 degree : Tripping temperature + * 85 degree : Memory throttling + * 120 degree : To protect chip,forcely kernel panic +*/ +static struct s5p_platform_tmu default_tmu_data __initdata = { + .ts = { + .stop_1st_throttle = 78, + .start_1st_throttle = 80, + .stop_2nd_throttle = 87, + .start_2nd_throttle = 103, + .start_tripping = 110, + .start_emergency = 120, + .stop_mem_throttle = 80, + .start_mem_throttle = 85, + }, + .cpufreq = { + .limit_1st_throttle = 800000, + .limit_2nd_throttle = 200000, + }, + .mp = { + .rclk = 24000000, + .period_bank_refresh = 3900, + }, + .cfg = { + .mode = 1, + .slope = 80, + .sampling_rate = 1000, + .monitoring_rate = 10000, + }, +}; + +int s5p_tmu_get_irqno(int num) +{ + return platform_get_irq(&s5p_device_tmu, num); +} + +struct s5p_tmu *s5p_tmu_get_platdata(void) +{ + return platform_get_drvdata(&s5p_device_tmu); +} + +void __init s5p_tmu_set_platdata(struct s5p_platform_tmu *pd) +{ + struct s5p_platform_tmu *npd; + + npd = kmalloc(sizeof(struct s5p_platform_tmu), GFP_KERNEL); + if (!npd) { + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + } else { + if (!pd->ts.stop_1st_throttle) + memcpy(&npd->ts, &default_tmu_data.ts, + sizeof(struct temperature_params)); + else + memcpy(&npd->ts, &pd->ts, + sizeof(struct temperature_params)); + + if (!(pd->cpufreq.limit_1st_throttle)) + memcpy(&npd->cpufreq, &default_tmu_data.cpufreq, + sizeof(struct cpufreq_params)); + else + memcpy(&npd->cpufreq, &pd->cpufreq, + sizeof(struct cpufreq_params)); + + if (pd->temp_compensate.arm_volt) + memcpy(&npd->temp_compensate, &pd->temp_compensate, + sizeof(struct temp_compensate_params)); + + s5p_device_tmu.dev.platform_data = npd; + } +} diff --git a/arch/arm/plat-s5p/dev-tsi.c b/arch/arm/plat-s5p/dev-tsi.c new file mode 100644 index 0000000..9ac42cc --- /dev/null +++ b/arch/arm/plat-s5p/dev-tsi.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd. + * + * S5P series device definition for TSI + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <mach/map.h> +#include <linux/dma-mapping.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> + +/*TSI Interface*/ +static u64 tsi_dma_mask = 0xffffffffUL; + +static struct resource s3c_tsi_resource[] = { + [0] = { + .start = S5P_PA_TSI, + .end = S5P_PA_TSI + S5P_SZ_TSI - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TSI, + .end = IRQ_TSI, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device s3c_device_tsi = { + .name = "s3c-tsi", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_tsi_resource), + .resource = s3c_tsi_resource, + .dev = { + .dma_mask = &tsi_dma_mask, + .coherent_dma_mask = 0xffffffffUL + } + + +}; +EXPORT_SYMBOL(s3c_device_tsi); diff --git a/arch/arm/plat-s5p/dev-tv.c b/arch/arm/plat-s5p/dev-tv.c new file mode 100644 index 0000000..2bb955c --- /dev/null +++ b/arch/arm/plat-s5p/dev-tv.c @@ -0,0 +1,185 @@ +/* linux/arch/arm/plat-s5p/dev-tv.c + * + * Copyright (C) 2011 Samsung Electronics Co.Ltd + * Author: Tomasz Stanislawski <t.stanislaws@samsung.com> + * + * S5P series device definition for TV device + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/dma-mapping.h> + +#include <mach/irqs.h> +#include <mach/map.h> + +#include <plat/cpu.h> +#include <plat/devs.h> +#include <plat/hdmi.h> +#include <plat/tvout.h> + +/* HDMI interface */ +static struct resource s5p_hdmi_resources[] = { + [0] = { + .start = S5P_PA_HDMI, + .end = S5P_PA_HDMI + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TVOUT_HPD, + .end = IRQ_TVOUT_HPD, + .flags = IORESOURCE_IRQ, + .name = "external_irq" + }, + [2] = { + .start = IRQ_HDMI, + .end = IRQ_HDMI, + .flags = IORESOURCE_IRQ, + .name = "internal_irq" + }, +}; + +struct platform_device s5p_device_hdmi = { + .name = "s5p-hdmi", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_hdmi_resources), + .resource = s5p_hdmi_resources, +}; +EXPORT_SYMBOL(s5p_device_hdmi); + +void __init s5p_hdmi_set_platdata(struct s5p_hdmi_platdata *pd) +{ + struct s5p_hdmi_platdata *npd; + + npd = s3c_set_platdata(pd, sizeof(struct s5p_hdmi_platdata), + &s5p_device_hdmi); + if (!npd) + return; + + if (soc_is_s5pv210() || soc_is_exynos4210()) + npd->is_v13 = true; + + if (!npd->cfg_hpd) + npd->cfg_hpd = s5p_hdmi_cfg_hpd; + if (!npd->get_hpd) + npd->get_hpd = s5p_hdmi_get_hpd; +} + +/* MIXER */ +#if defined(CONFIG_ARCH_EXYNOS4) +static struct resource s5p_mixer_resources[] = { + [0] = { + .start = S5P_PA_MIXER, + .end = S5P_PA_MIXER + SZ_64K - 1, + .flags = IORESOURCE_MEM, + .name = "mxr" + }, + [1] = { + .start = S5P_PA_VP, + .end = S5P_PA_VP + SZ_64K - 1, + .flags = IORESOURCE_MEM, + .name = "vp" + }, + [2] = { + .start = IRQ_MIXER, + .end = IRQ_MIXER, + .flags = IORESOURCE_IRQ, + .name = "irq" + } +}; +#else +static struct resource s5p_mixer_resources[] = { + [0] = { + .start = S5P_PA_MIXER, + .end = S5P_PA_MIXER + SZ_64K - 1, + .flags = IORESOURCE_MEM, + .name = "mxr" + }, + [2] = { + .start = IRQ_MIXER, + .end = IRQ_MIXER, + .flags = IORESOURCE_IRQ, + .name = "irq" + } +}; +#endif + +struct platform_device s5p_device_mixer = { + .name = "s5p-mixer", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_mixer_resources), + .resource = s5p_mixer_resources, + .dev = { + .coherent_dma_mask = DMA_BIT_MASK(32), + .dma_mask = &s5p_device_mixer.dev.coherent_dma_mask, + } +}; +EXPORT_SYMBOL(s5p_device_mixer); + +#if defined(CONFIG_ARCH_EXYNOS4) +/* HDMI interface */ +static struct resource s5p_sdo_resources[] = { + [0] = { + .start = S5P_PA_SDO, + .end = S5P_PA_SDO + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SDO, + .end = IRQ_SDO, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device s5p_device_sdo = { + .name = "s5p-sdo", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_sdo_resources), + .resource = s5p_sdo_resources, + .dev = { + .coherent_dma_mask = DMA_BIT_MASK(32), + .dma_mask = &s5p_device_sdo.dev.coherent_dma_mask, + } +}; +EXPORT_SYMBOL(s5p_device_sdo); +#endif + +/* CEC */ +static struct resource s5p_cec_resources[] = { + [0] = { + .start = S5P_PA_HDMI_CEC, + .end = S5P_PA_HDMI_CEC + S5P_SZ_HDMI_CEC - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_CEC, + .end = IRQ_CEC, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s5p_device_cec = { + .name = "s5p-tvout-cec", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_cec_resources), + .resource = s5p_cec_resources, +}; +EXPORT_SYMBOL(s5p_device_cec); + + +void __init s5p_hdmi_cec_set_platdata(struct s5p_platform_cec *pd) +{ + struct s5p_platform_cec *npd; + + npd = kmemdup(pd, sizeof(struct s5p_platform_cec), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + else { + if (!npd->cfg_gpio) + npd->cfg_gpio = s5p_cec_cfg_gpio; + + s5p_device_cec.dev.platform_data = npd; + } +} diff --git a/arch/arm/plat-s5p/dev-tvout.c b/arch/arm/plat-s5p/dev-tvout.c new file mode 100644 index 0000000..dd057dd --- /dev/null +++ b/arch/arm/plat-s5p/dev-tvout.c @@ -0,0 +1,151 @@ +/* linux/arch/arm/plat-s5p/dev-tvout.c + * + * Copyright (c) 2010 Samsung Electronics + * + * Base S5P TVOUT resource and device definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <mach/map.h> +#include <plat/tvout.h> + +/* TVOUT interface */ +static struct resource s5p_tvout_resources[] = { + [0] = { + .start = S5P_PA_TVENC, + .end = S5P_PA_TVENC + S5P_SZ_TVENC - 1, + .flags = IORESOURCE_MEM, + .name = "s5p-sdo" + }, + [1] = { + .start = S5P_PA_VP, + .end = S5P_PA_VP + S5P_SZ_VP - 1, + .flags = IORESOURCE_MEM, + .name = "s5p-vp" + }, + [2] = { + .start = S5P_PA_MIXER, + .end = S5P_PA_MIXER + S5P_SZ_MIXER - 1, + .flags = IORESOURCE_MEM, + .name = "s5p-mixer" + }, + [3] = { + .start = S5P_PA_HDMI, + .end = S5P_PA_HDMI + S5P_SZ_HDMI - 1, + .flags = IORESOURCE_MEM, + .name = "s5p-hdmi" + }, + [4] = { + .start = S5P_I2C_HDMI_PHY, + .end = S5P_I2C_HDMI_PHY + S5P_I2C_HDMI_SZ_PHY - 1, + .flags = IORESOURCE_MEM, + .name = "s5p-i2c-hdmi-phy" + }, + [5] = { + .start = IRQ_MIXER, + .end = IRQ_MIXER, + .flags = IORESOURCE_IRQ, + .name = "s5p-mixer" + }, + [6] = { + .start = IRQ_HDMI, + .end = IRQ_HDMI, + .flags = IORESOURCE_IRQ, + .name = "s5p-hdmi" + }, + [7] = { + .start = IRQ_TVENC, + .end = IRQ_TVENC, + .flags = IORESOURCE_IRQ, + .name = "s5p-sdo" + }, +}; + +struct platform_device s5p_device_tvout = { + .name = "s5p-tvout", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_tvout_resources), + .resource = s5p_tvout_resources, +}; +EXPORT_SYMBOL(s5p_device_tvout); + +/* HPD */ +static struct resource s5p_hpd_resources[] = { + [0] = { + .start = IRQ_TVOUT_HPD, + .end = IRQ_TVOUT_HPD, + .flags = IORESOURCE_IRQ, + }, +}; +struct platform_device s5p_device_hpd = { + .name = "s5p-tvout-hpd", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_hpd_resources), + .resource = s5p_hpd_resources, +}; +EXPORT_SYMBOL(s5p_device_hpd); + +void __init s5p_hdmi_hpd_set_platdata(struct s5p_platform_hpd *pd) +{ + struct s5p_platform_hpd *npd; + + npd = kmemdup(pd, sizeof(struct s5p_platform_hpd), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + else { + if (!npd->int_src_ext_hpd) + npd->int_src_ext_hpd = s5p_int_src_ext_hpd; + if (!npd->int_src_hdmi_hpd) + npd->int_src_hdmi_hpd = s5p_int_src_hdmi_hpd; + if (!npd->read_gpio) + npd->read_gpio = s5p_hpd_read_gpio; + + s5p_device_hpd.dev.platform_data = npd; + } +} + +/* CEC */ +static struct resource s5p_cec_resources[] = { + [0] = { + .start = S5P_PA_HDMI_CEC, + .end = S5P_PA_HDMI_CEC + S5P_SZ_HDMI_CEC - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_CEC, + .end = IRQ_CEC, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s5p_device_cec = { + .name = "s5p-tvout-cec", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_cec_resources), + .resource = s5p_cec_resources, +}; +EXPORT_SYMBOL(s5p_device_cec); + + +void __init s5p_hdmi_cec_set_platdata(struct s5p_platform_cec *pd) +{ + struct s5p_platform_cec *npd; + + npd = kmemdup(pd, sizeof(struct s5p_platform_cec), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + else { + if (!npd->cfg_gpio) + npd->cfg_gpio = s5p_cec_cfg_gpio; + + s5p_device_cec.dev.platform_data = npd; + } +} diff --git a/arch/arm/plat-s5p/dev-usb-switch.c b/arch/arm/plat-s5p/dev-usb-switch.c new file mode 100644 index 0000000..889362c --- /dev/null +++ b/arch/arm/plat-s5p/dev-usb-switch.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co.Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include <linux/platform_device.h> +#include <mach/irqs.h> +#include <mach/map.h> +#include <mach/gpio.h> +#include <plat/devs.h> +#include <plat/usb-switch.h> + +/* USB Switch */ +static struct resource s5p_usbswitch_res[4]; + +struct platform_device s5p_device_usbswitch = { + .name = "exynos-usb-switch", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_usbswitch_res), + .resource = s5p_usbswitch_res, +}; + +void __init s5p_usbswitch_set_platdata(struct s5p_usbswitch_platdata *pd) +{ + struct s5p_usbswitch_platdata *npd; + + npd = s3c_set_platdata(pd, sizeof(struct s5p_usbswitch_platdata), + &s5p_device_usbswitch); + + s5p_usbswitch_res[0].start = gpio_to_irq(npd->gpio_host_detect); + s5p_usbswitch_res[0].end = gpio_to_irq(npd->gpio_host_detect); + s5p_usbswitch_res[0].flags = IORESOURCE_IRQ; + + s5p_usbswitch_res[1].start = gpio_to_irq(npd->gpio_device_detect); + s5p_usbswitch_res[1].end = gpio_to_irq(npd->gpio_device_detect); + s5p_usbswitch_res[1].flags = IORESOURCE_IRQ; + + s5p_usbswitch_res[2].start = gpio_to_irq(npd->gpio_drd_host_detect); + s5p_usbswitch_res[2].end = gpio_to_irq(npd->gpio_drd_host_detect); + s5p_usbswitch_res[2].flags = IORESOURCE_IRQ; + + s5p_usbswitch_res[3].start = gpio_to_irq(npd->gpio_drd_device_detect); + s5p_usbswitch_res[3].end = gpio_to_irq(npd->gpio_drd_device_detect); + s5p_usbswitch_res[3].flags = IORESOURCE_IRQ; +#ifdef CONFIG_USB_EHCI_S5P + npd->ehci_dev = &s5p_device_ehci.dev; +#endif +#ifdef CONFIG_USB_OHCI_S5P + npd->ohci_dev = &s5p_device_ohci.dev; +#endif +#ifdef CONFIG_USB_XHCI_EXYNOS + npd->xhci_dev = &exynos_device_xhci.dev; +#endif +#ifdef CONFIG_USB_S3C_OTGD + npd->s3c_udc_dev = &s3c_device_usbgadget.dev; +#endif +#ifdef CONFIG_USB_EXYNOS_SS_UDC + npd->exynos_udc_dev = &exynos_device_ss_udc.dev; +#endif +} diff --git a/arch/arm/plat-s5p/dev-usbgadget.c b/arch/arm/plat-s5p/dev-usbgadget.c new file mode 100644 index 0000000..3890ce3 --- /dev/null +++ b/arch/arm/plat-s5p/dev-usbgadget.c @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd. + * + * S3C series device definition for USB-GADGET + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/dma-mapping.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#if defined(CONFIG_USB_ANDROID) || defined(CONFIG_USB_G_ANDROID) +#include <linux/usb/android_composite.h> +#endif + +#include <mach/map.h> +#include <plat/devs.h> +#include <plat/usbgadget.h> +#include <plat/usb-phy.h> + +/* USB Device (Gadget)*/ +static struct resource s3c_usbgadget_resource[] = { + [0] = { + .start = S5P_PA_HSOTG, + .end = S5P_PA_HSOTG + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USB_HSOTG, + .end = IRQ_USB_HSOTG, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 s5p_device_usb_gadget_dmamask = 0xffffffffUL; +struct platform_device s3c_device_usbgadget = { + .name = "s3c-usbgadget", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_usbgadget_resource), + .resource = s3c_usbgadget_resource, + .dev = { + .dma_mask = &s5p_device_usb_gadget_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s5p_usbgadget_set_platdata(struct s5p_usbgadget_platdata *pd) +{ + struct s5p_usbgadget_platdata *npd; + + npd = s3c_set_platdata(pd, sizeof(struct s5p_usbgadget_platdata), + &s3c_device_usbgadget); + + if (!npd->phy_init) + npd->phy_init = s5p_usb_phy_init; + if (!npd->phy_exit) + npd->phy_exit = s5p_usb_phy_exit; +} + +#if defined(CONFIG_USB_ANDROID) || defined(CONFIG_USB_G_ANDROID) +/* default samsung vendor ID */ +#define SAMSUNG_VENDOR_ID 0x04e8 +/* dynamic composite using devguru driver */ +#define SAMSUNG_MTP_PRODUCT_ID 0x6860 /* mtp(0)+...*/ +#define SAMSUNG_UMS_PRODUCT_ID 0x685e /* ums(0)+...*/ +#define SAMSUNG_RNDIS_PRODUCT_ID 0x6864 /* RNDIS +...*/ +#define SAMSUNG_NCM_PRODUCT_ID 0x685D /* NCM + ...*/ +/* only mode using devguru driver */ +#define SAMSUNG_UMS_ONLY_PRODUCT_ID 0x685B /* UMS Only */ +#define SAMSUNG_MTP_ONLY_PRODUCT_ID 0x685C /* MTP Only */ +#define SAMSUNG_RNDIS_ONLY_PRODUCT_ID 0x6863 /* RNDIS only */ +#define SAMSUNG_ADB_ONLY_PRODUCT_ID SAMSUNG_MTP_ONLY_PRODUCT_ID + +#ifdef CONFIG_USB_ANDROID_MTP +#define SAMSUNG_PRODUCT_ID SAMSUNG_MTP_PRODUCT_ID +#else +#define SAMSUNG_PRODUCT_ID SAMSUNG_UMS_PRODUCT_ID +#endif + +#define MAX_USB_SERIAL_NUM 17 + +#ifdef CONFIG_USB_ANDROID_MASS_STORAGE +static char *usb_functions_ums[] = { + "usb_mass_storage", +}; +#endif + +#ifdef CONFIG_USB_ANDROID_RNDIS +static char *usb_functions_rndis[] = { + "rndis", +}; +#endif + +#ifdef CONFIG_USB_ANDROID_MTP +static char *usb_functions_mtp[] = { + "mtp", +}; +#endif + +#ifdef CONFIG_USB_ANDROID_ADB +static char *usb_functions_adb[] = { + "adb", +}; +#endif + +#if defined(CONFIG_USB_ANDROID_MASS_STORAGE) && defined(CONFIG_USB_ANDROID_ADB) +static char *usb_functions_ums_adb[] = { + "usb_mass_storage", + "adb", +}; +#endif + +#if defined(CONFIG_USB_ANDROID_MTP) && defined(CONFIG_USB_ANDROID_ADB) +static char *usb_functions_mtp_adb[] = { + "mtp", + "adb", +}; +#endif + +#if defined(CONFIG_USB_ANDROID_MASS_STORAGE) && defined(CONFIG_USB_ANDROID_ADB) && defined(CONFIG_USB_ANDROID_ACM) +static char *usb_functions_ums_adb_acm[] = { + "usb_mass_storage", + "adb", + "acm", +}; +#endif + +static char *usb_functions_all[] = { +#ifdef CONFIG_USB_ANDROID_RNDIS + "rndis", +#endif +#ifdef CONFIG_USB_ANDROID_MASS_STORAGE + "usb_mass_storage", +#endif +#ifdef CONFIG_USB_ANDROID_MTP + "mtp", +#endif +#ifdef CONFIG_USB_ANDROID_ADB + "adb", +#endif +#ifdef CONFIG_USB_ANDROID_ACM + "acm", +#endif +}; + +static struct android_usb_product usb_products[] = { +#ifdef CONFIG_USB_ANDROID_MASS_STORAGE + { + .product_id = SAMSUNG_UMS_ONLY_PRODUCT_ID, + .num_functions = ARRAY_SIZE(usb_functions_ums), + .functions = usb_functions_ums, + }, +#endif +#ifdef CONFIG_USB_ANDROID_RNDIS + { + .product_id = SAMSUNG_RNDIS_ONLY_PRODUCT_ID, + .num_functions = ARRAY_SIZE(usb_functions_rndis), + .functions = usb_functions_rndis, + }, +#endif +#ifdef CONFIG_USB_ANDROID_MTP + { + .product_id = SAMSUNG_MTP_ONLY_PRODUCT_ID, + .num_functions = ARRAY_SIZE(usb_functions_mtp), + .functions = usb_functions_mtp, + }, +#endif +#if defined(CONFIG_USB_ANDROID_MASS_STORAGE) && defined(CONFIG_USB_ANDROID_ADB) + { + .product_id = SAMSUNG_UMS_PRODUCT_ID, + .num_functions = ARRAY_SIZE(usb_functions_ums_adb), + .functions = usb_functions_ums_adb, + }, +#endif +#if defined(CONFIG_USB_ANDROID_MTP) && defined(CONFIG_USB_ANDROID_ADB) + { + .product_id = SAMSUNG_MTP_PRODUCT_ID, + .num_functions = ARRAY_SIZE(usb_functions_mtp_adb), + .functions = usb_functions_mtp_adb, + }, +#endif +#ifdef CONFIG_USB_ANDROID_ADB + { + .product_id = SAMSUNG_ADB_ONLY_PRODUCT_ID, + .num_functions = ARRAY_SIZE(usb_functions_adb), + .functions = usb_functions_adb, + }, +#endif +#if defined(CONFIG_USB_ANDROID_MASS_STORAGE) && defined(CONFIG_USB_ANDROID_ADB) && defined(CONFIG_USB_ANDROID_ACM) + { + .product_id = SAMSUNG_UMS_PRODUCT_ID, + .num_functions = ARRAY_SIZE(usb_functions_ums_adb_acm), + .functions = usb_functions_ums_adb_acm, + }, +#endif +}; + +static char device_serial[MAX_USB_SERIAL_NUM] = "0123456789ABCDEF"; + +/* standard android USB platform data */ +static struct android_usb_platform_data android_usb_pdata = { + .vendor_id = SAMSUNG_VENDOR_ID, + .product_id = SAMSUNG_PRODUCT_ID, + .manufacturer_name = "SAMSUNG", + .product_name = "S5P OTG-USB", + .serial_number = device_serial, + .num_products = ARRAY_SIZE(usb_products), + .products = usb_products, + .num_functions = ARRAY_SIZE(usb_functions_all), + .functions = usb_functions_all, +}; + +struct platform_device s3c_device_android_usb = { + .name = "android_usb", + .id = -1, + .dev = { + .platform_data = &android_usb_pdata, + }, +}; + +static struct usb_mass_storage_platform_data ums_pdata = { + .vendor = "SAMSUNG", + .product = "S5P UMS", + .release = 1, + .nluns = 1, +}; +struct platform_device s3c_device_usb_mass_storage = { + .name = "usb_mass_storage", + .id = -1, + .dev = { + .platform_data = &ums_pdata, + }, +}; + +#ifdef CONFIG_USB_ANDROID_RNDIS +static struct usb_ether_platform_data rndis_pdata = { +/* ethaddr is filled by board_serialno_setup */ + .vendorID = SAMSUNG_VENDOR_ID, + .vendorDescr = "SAMSUNG", +}; +struct platform_device s3c_device_rndis = { + .name = "rndis", + .id = -1, + .dev = { + .platform_data = &rndis_pdata, + }, +}; +#endif +#endif /* CONFIG_USB_ANDROID */ + diff --git a/arch/arm/plat-s5p/include/plat/ace-core.h b/arch/arm/plat-s5p/include/plat/ace-core.h new file mode 100644 index 0000000..7eb60b7 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/ace-core.h @@ -0,0 +1,26 @@ +/* linux/arch/arm/plat-s5p/include/plat/ace-core.h + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Samsung Advanced Crypto Engine core function + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_PLAT_ACE_CORE_H +#define __ASM_PLAT_ACE_CORE_H __FILE__ + +/* These functions are only for use with the core support code, such as + * the cpu specific initialisation code + */ + +/* re-define device name depending on support. */ +static inline void s5p_ace_setname(char *name) +{ + s5p_device_ace.name = name; +} + +#endif /* __ASM_PLAT_ACE_CORE_H */ diff --git a/arch/arm/plat-s5p/include/plat/bts.h b/arch/arm/plat-s5p/include/plat/bts.h new file mode 100644 index 0000000..a7cbc18 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/bts.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __EXYNOS_BTS_H_ +#define __EXYNOS_BTS_H_ + +#include <plat/pd.h> + +enum exynos_bts_id { + BTS_CPU, + BTS_DISP, + BTS_DISP10, + BTS_DISP11, + BTS_TV, + BTS_TV0, + BTS_TV1, + BTS_C2C, + BTS_JPEG, + BTS_MDMA1, + BTS_ROTATOR, + BTS_GSCL, + BTS_GSCL0, + BTS_GSCL1, + BTS_GSCL2, + BTS_GSCL3, + BTS_MFC, + BTS_MFC0, + BTS_MFC1, + BTS_G3D_ACP, + BTS_ISP0, + BTS_ISP1, + BTS_FIMC_ISP, + BTS_FIMC_FD, + BTS_FIMC_ODC, + BTS_FIMC_DIS0, + BTS_FIMC_DIS1, + BTS_3DNR, + BTS_SCALER_C, + BTS_SCALER_P +}; + +enum bts_priority { + BTS_LOW, + BTS_BE, + BTS_HARDTIME, +}; + +enum bts_fbm_group { + BTS_FBM_G0_L = (1<<1), + BTS_FBM_G0_R = (1<<2), + BTS_FBM_G1_L = (1<<3), + BTS_FBM_G1_R = (1<<4), + BTS_FBM_G2_L = (1<<5), + BTS_FBM_G2_R = (1<<6), +}; + +struct exynos_fbm_resource { + enum bts_fbm_group fbm_group; + enum bts_priority priority; + u32 base; +}; + +struct exynos_fbm_pdata { + struct exynos_fbm_resource *res; + int res_num; +}; + +struct exynos_bts_pdata { + enum exynos_bts_id id; + enum bts_priority def_priority; + enum exynos_pd_block pd_block; + char *clk_name; + struct exynos_fbm_pdata *fbm; + int res_num; +}; + +/* BTS functions */ +void exynos_bts_enable(enum exynos_pd_block pd_block); +void exynos_bts_set_priority(enum bts_priority prior); +#ifdef CONFIG_S5P_BTS +#define bts_enable(a) exynos_bts_enable(a); +#else +#define bts_enable(a) do {} while (0) +#endif +#endif /* __EXYNOS_BTS_H_ */ diff --git a/arch/arm/plat-s5p/include/plat/csis.h b/arch/arm/plat-s5p/include/plat/csis.h new file mode 100644 index 0000000..1cb1fae --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/csis.h @@ -0,0 +1,45 @@ +/* linux/arch/arm/plat-s5p/include/plat/csis.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Platform header file for MIPI-CSI2 driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_PLAT_CSIS_H +#define __ASM_PLAT_CSIS_H __FILE__ + +#define to_csis_plat(d) (to_platform_device(d)->dev.platform_data) + +struct platform_device; +struct clk; + +struct s3c_platform_csis { + char *srclk_name; + char *clk_name; + unsigned long clk_rate; + + void (*cfg_gpio)(void); + void (*cfg_phy_global)(int on); + int (*clk_on)(struct platform_device *pdev, struct clk **clk); + int (*clk_off)(struct platform_device *pdev, struct clk **clk); +}; +#ifdef CONFIG_ARCH_EXYNOS4 +extern void s3c_csis0_set_platdata(struct s3c_platform_csis *csis); +extern void s3c_csis1_set_platdata(struct s3c_platform_csis *csis); +extern void s3c_csis0_cfg_gpio(void); +extern void s3c_csis1_cfg_gpio(void); +extern void s3c_csis0_cfg_phy_global(int on); +extern void s3c_csis1_cfg_phy_global(int on); +#else +extern void s3c_csis_set_platdata(struct s3c_platform_csis *csis); +extern void s3c_csis_cfg_gpio(void); +extern void s3c_csis_cfg_phy_global(int on); +#endif +extern int s3c_csis_clk_on(struct platform_device *pdev, struct clk **clk); +extern int s3c_csis_clk_off(struct platform_device *pdev, struct clk **clk); +#endif /* __ASM_PLAT_CSIS_H */ diff --git a/arch/arm/plat-s5p/include/plat/dp.h b/arch/arm/plat-s5p/include/plat/dp.h new file mode 100644 index 0000000..0c4c97b --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/dp.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2011 Samsung Electronics Co., Ltd. + * + * Samsung S5P series DP device support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef PLAT_S5P_DP_H_ +#define PLAT_S5P_DP_H_ __FILE__ + +#include <video/s5p-dp.h> + +extern void s5p_dp_set_platdata(struct s5p_dp_platdata *pd); +extern void s5p_dp_phy_init(void); +extern void s5p_dp_phy_exit(void); + +#endif /* PLAT_S5P_DP_H_ */ diff --git a/arch/arm/plat-s5p/include/plat/dsim.h b/arch/arm/plat-s5p/include/plat/dsim.h new file mode 100644 index 0000000..bbfb52b --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/dsim.h @@ -0,0 +1,330 @@ +/* linux/arm/arch/plat-s5p/include/plat/dsim.h + * + * Platform data header for Samsung SoC MIPI-DSIM. + * + * Copyright (c) 2011 Samsung Electronics + * + * InKi Dae <inki.dae@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef _DSIM_H +#define _DSIM_H + +#include <linux/device.h> +#include <linux/fb.h> +#include <linux/notifier.h> + +#include <linux/regulator/consumer.h> + +#ifdef CONFIG_HAS_EARLYSUSPEND +#include <linux/earlysuspend.h> +#endif + +#define to_dsim_plat(d) (to_platform_device(d)->dev.platform_data) + +enum mipi_dsim_interface_type { + DSIM_COMMAND, + DSIM_VIDEO +}; + +enum mipi_dsim_virtual_ch_no { + DSIM_VIRTUAL_CH_0, + DSIM_VIRTUAL_CH_1, + DSIM_VIRTUAL_CH_2, + DSIM_VIRTUAL_CH_3 +}; + +enum mipi_dsim_burst_mode_type { + DSIM_NON_BURST_SYNC_EVENT, + DSIM_NON_BURST_SYNC_PULSE = 2, + DSIM_BURST = 1, + DSIM_NON_VIDEO_MODE = 4 +}; + +enum mipi_dsim_no_of_data_lane { + DSIM_DATA_LANE_1, + DSIM_DATA_LANE_2, + DSIM_DATA_LANE_3, + DSIM_DATA_LANE_4 +}; + +enum mipi_dsim_byte_clk_src { + DSIM_PLL_OUT_DIV8, + DSIM_EXT_CLK_DIV8, + DSIM_EXT_CLK_BYPASS +}; + +enum mipi_dsim_pixel_format { + DSIM_CMD_3BPP, + DSIM_CMD_8BPP, + DSIM_CMD_12BPP, + DSIM_CMD_16BPP, + DSIM_VID_16BPP_565, + DSIM_VID_18BPP_666PACKED, + DSIM_18BPP_666LOOSELYPACKED, + DSIM_24BPP_888 +}; + +/** + * struct mipi_dsim_config - interface for configuring mipi-dsi controller. + * + * @auto_flush: enable or disable Auto flush of MD FIFO using VSYNC pulse. + * @eot_disable: enable or disable EoT packet in HS mode. + * @auto_vertical_cnt: specifies auto vertical count mode. + * in Video mode, the vertical line transition uses line counter + * configured by VSA, VBP, and Vertical resolution. + * If this bit is set to '1', the line counter does not use VSA and VBP + * registers.(in command mode, this variable is ignored) + * @hse: set horizontal sync event mode. + * In VSYNC pulse and Vporch area, MIPI DSI master transfers only HSYNC + * start packet to MIPI DSI slave at MIPI DSI spec1.1r02. + * this bit transfers HSYNC end packet in VSYNC pulse and Vporch area + * (in mommand mode, this variable is ignored) + * @hfp: specifies HFP disable mode. + * if this variable is set, DSI master ignores HFP area in VIDEO mode. + * (in command mode, this variable is ignored) + * @hbp: specifies HBP disable mode. + * if this variable is set, DSI master ignores HBP area in VIDEO mode. + * (in command mode, this variable is ignored) + * @hsa: specifies HSA disable mode. + * if this variable is set, DSI master ignores HSA area in VIDEO mode. + * (in command mode, this variable is ignored) + * @e_interface: specifies interface to be used.(CPU or RGB interface) + * @e_virtual_ch: specifies virtual channel number that main or + * sub diaplsy uses. + * @e_pixel_format: specifies pixel stream format for main or sub display. + * @e_burst_mode: selects Burst mode in Video mode. + * in Non-burst mode, RGB data area is filled with RGB data and NULL + * packets, according to input bandwidth of RGB interface. + * In Burst mode, RGB data area is filled with RGB data only. + * @e_no_data_lane: specifies data lane count to be used by Master. + * @e_byte_clk: select byte clock source. (it must be DSIM_PLL_OUT_DIV8) + * DSIM_EXT_CLK_DIV8 and DSIM_EXT_CLK_BYPASSS are not supported. + * @pll_stable_time: specifies the PLL Timer for stability of the ganerated + * clock(System clock cycle base) + * if the timer value goes to 0x00000000, the clock stable bit of +status + * and interrupt register is set. + * @esc_clk: specifies escape clock frequency for getting the escape clock + * prescaler value. + * @stop_holding_cnt: specifies the interval value between transmitting + * read packet(or write "set_tear_on" command) and BTA request. + * after transmitting read packet or write "set_tear_on" command, + * BTA requests to D-PHY automatically. this counter value specifies + * the interval between them. + * @bta_timeout: specifies the timer for BTA. + * this register specifies time out from BTA request to change + * the direction with respect to Tx escape clock. + * @rx_timeout: specifies the timer for LP Rx mode timeout. + * this register specifies time out on how long RxValid deasserts, + * after RxLpdt asserts with respect to Tx escape clock. + * - RxValid specifies Rx data valid indicator. + * - RxLpdt specifies an indicator that D-PHY is under RxLpdt mode. + * - RxValid and RxLpdt specifies signal from D-PHY. + * @lcd_panel_info: pointer for lcd panel specific structure. + * this structure specifies width, height, timing and polarity and so +on. + * @mipi_ddi_pd: pointer to lcd panel platform data. + */ +struct mipi_dsim_config { + unsigned char auto_flush; + unsigned char eot_disable; + + unsigned char auto_vertical_cnt; + unsigned char hse; + unsigned char hfp; + unsigned char hbp; + unsigned char hsa; + + enum mipi_dsim_interface_type e_interface; + enum mipi_dsim_virtual_ch_no e_virtual_ch; + enum mipi_dsim_pixel_format e_pixel_format; + enum mipi_dsim_burst_mode_type e_burst_mode; + enum mipi_dsim_no_of_data_lane e_no_data_lane; + enum mipi_dsim_byte_clk_src e_byte_clk; + + unsigned char p; + unsigned short m; + unsigned char s; + + unsigned int pll_stable_time; + unsigned long esc_clk; + + unsigned short stop_holding_cnt; + unsigned char bta_timeout; + unsigned short rx_timeout; + + void *lcd_panel_info; + void *dsim_ddi_pd; +}; + +/* for RGB Interface */ +struct mipi_dsi_lcd_timing { + int left_margin; + int right_margin; + int upper_margin; + int lower_margin; + int hsync_len; + int vsync_len; +}; + +/* for CPU Interface */ +struct mipi_dsi_cpu_timing { + unsigned int cs_setup; + unsigned int wr_setup; + unsigned int wr_act; + unsigned int wr_hold; +}; + +struct mipi_dsi_lcd_size { + unsigned int width; + unsigned int height; +}; + +struct mipi_dsim_lcd_config { + enum mipi_dsim_interface_type e_interface; + unsigned int parameter[3]; + + /* lcd panel info */ + struct mipi_dsi_lcd_timing rgb_timing; + struct mipi_dsi_cpu_timing cpu_timing; + struct mipi_dsi_lcd_size lcd_size; + /* platform data for lcd panel based on MIPI-DSI. */ + void *mipi_ddi_pd; +}; + +/** + * struct mipi_dsim_device - global interface for mipi-dsi driver. + * + * @dev: driver model representation of the device. + * @clock: pointer to MIPI-DSI clock of clock framework. + * @irq: interrupt number to MIPI-DSI controller. + * @reg_base: base address to memory mapped SRF of MIPI-DSI controller. + * (virtual address) + * @pd: pointer to MIPI-DSI driver platform data. + * @dsim_info: infomation for configuring mipi-dsi controller. + * @master_ops: callbacks to mipi-dsi operations. + * @lcd_info: pointer to mipi_lcd_info structure. + * @state: specifies status of MIPI-DSI controller. + * the status could be RESET, INIT, STOP, HSCLKEN and ULPS. + * @data_lane: specifiec enabled data lane number. + * this variable would be set by driver according to e_no_data_lane + * automatically. + * @e_clk_src: select byte clock source. + * this variable would be set by driver according to e_byte_clock + * automatically. + * @hs_clk: HS clock rate. + * this variable would be set by driver automatically. + * @byte_clk: Byte clock rate. + * this variable would be set by driver automatically. + * @escape_clk: ESCAPE clock rate. + * this variable would be set by driver automatically. + * @freq_band: indicates Bitclk frequency band for D-PHY global timing. + * Serial Clock(=ByteClk X 8) FreqBand[3:0] + * ~ 99.99 MHz 0000 + * 100 ~ 119.99 MHz 0001 + * 120 ~ 159.99 MHz 0010 + * 160 ~ 199.99 MHz 0011 + * 200 ~ 239.99 MHz 0100 + * 140 ~ 319.99 MHz 0101 + * 320 ~ 389.99 MHz 0110 + * 390 ~ 449.99 MHz 0111 + * 450 ~ 509.99 MHz 1000 + * 510 ~ 559.99 MHz 1001 + * 560 ~ 639.99 MHz 1010 + * 640 ~ 689.99 MHz 1011 + * 690 ~ 769.99 MHz 1100 + * 770 ~ 869.99 MHz 1101 + * 870 ~ 949.99 MHz 1110 + * 950 ~ 1000 MHz 1111 + * this variable would be calculated by driver automatically. + */ +struct mipi_dsim_device { + struct device *dev; + struct resource *res; + struct clk *clock; + unsigned int irq; + void __iomem *reg_base; + + struct s5p_platform_mipi_dsim *pd; + struct mipi_dsim_config *dsim_config; + + unsigned int state; + unsigned int data_lane; + enum mipi_dsim_byte_clk_src e_clk_src; + unsigned long hs_clk; + unsigned long byte_clk; + unsigned long escape_clk; + unsigned char freq_band; + unsigned char id; + struct notifier_block fb_notif; + + struct mipi_dsim_lcd_driver *dsim_lcd_drv; +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; +#endif +}; + +/** + * struct s5p_platform_mipi_dsim - interface to platform data + * for mipi-dsi driver. + * + * @mipi_dsim_config: pointer of structure for configuring mipi-dsi controller. + * @dsim_lcd_info: pointer to structure for configuring + * mipi-dsi based lcd panel. + * @mipi_power: callback pointer for enabling or disabling mipi power. + * @part_reset: callback pointer for reseting mipi phy. + * @init_d_phy: callback pointer for enabing d_phy of dsi master. + * @get_fb_frame_done: callback pointer for getting frame done status of +the + * display controller(FIMD). + * @trigger: callback pointer for triggering display controller(FIMD) + * in case of CPU mode. + * @delay_for_stabilization: specifies stable time. + * this delay needs when writing data on SFR + * after mipi mode became LP mode. + */ +struct s5p_platform_mipi_dsim { + const char clk_name[16]; + + struct mipi_dsim_config *dsim_config; + struct mipi_dsim_lcd_config *dsim_lcd_config; + + unsigned int delay_for_stabilization; + + int (*mipi_power) (struct mipi_dsim_device *dsim, unsigned int + enable); + int (*part_reset) (struct mipi_dsim_device *dsim); + int (*init_d_phy) (struct mipi_dsim_device *dsim, unsigned int enable); + int (*get_fb_frame_done) (struct fb_info *info); + void (*trigger) (struct fb_info *info); +}; + +/** + * driver structure for mipi-dsi based lcd panel. + * + * this structure should be registered by lcd panel driver. + * mipi-dsi driver seeks lcd panel registered through name field + * and calls these callback functions in appropriate time. + */ + +struct mipi_dsim_lcd_driver { + int (*probe)(struct mipi_dsim_device *dsim); + int (*suspend)(struct mipi_dsim_device *dsim); + int (*displayon)(struct mipi_dsim_device *dsim); + int (*resume)(struct mipi_dsim_device *dsim); +}; + +/** + * register mipi_dsim_lcd_driver object defined by lcd panel driver + * to mipi-dsi driver. + */ +extern int s5p_dsim_part_reset(struct mipi_dsim_device *dsim); +extern int s5p_dsim_init_d_phy(struct mipi_dsim_device *dsim, + unsigned int enable); +extern void s5p_dsim_set_platdata(struct s5p_platform_mipi_dsim * pd); +#endif /* _DSIM_H */ diff --git a/arch/arm/plat-s5p/include/plat/ehci.h b/arch/arm/plat-s5p/include/plat/ehci.h index 6ae6810..0cdc0b5 100644 --- a/arch/arm/plat-s5p/include/plat/ehci.h +++ b/arch/arm/plat-s5p/include/plat/ehci.h @@ -14,8 +14,28 @@ struct s5p_ehci_platdata { int (*phy_init)(struct platform_device *pdev, int type); int (*phy_exit)(struct platform_device *pdev, int type); + int (*phy_suspend)(struct platform_device *pdev, int type); + int (*phy_resume)(struct platform_device *pdev, int type); +#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) ||\ + defined(CONFIG_CDMA_MODEM_MDM6600) +/* for SAMSUNG Modem*/ + void (*noti_host_states)(struct platform_device *pdev, int type); + int (*get_cp_active_state)(void); +#endif +}; + +struct s5p_ohci_platdata { + int (*phy_init)(struct platform_device *pdev, int type); + int (*phy_exit)(struct platform_device *pdev, int type); + int (*phy_suspend)(struct platform_device *pdev, int type); + int (*phy_resume)(struct platform_device *pdev, int type); }; extern void s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd); +extern void s5p_ohci_set_platdata(struct s5p_ohci_platdata *pd); +#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) ||\ + defined(CONFIG_CDMA_MODEM_MDM6600) +int s5p_ehci_port_control(struct platform_device *pdev, int port, int enable); +#endif #endif /* __PLAT_S5P_EHCI_H */ diff --git a/arch/arm/plat-s5p/include/plat/exynos4.h b/arch/arm/plat-s5p/include/plat/exynos4.h index 907caab..474a7c0 100644 --- a/arch/arm/plat-s5p/include/plat/exynos4.h +++ b/arch/arm/plat-s5p/include/plat/exynos4.h @@ -12,11 +12,13 @@ /* Common init code for EXYNOS4 related SoCs */ -extern void exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no); +struct s3c2410_uartcfg; + +extern void exynos_common_init_uarts(struct s3c2410_uartcfg *cfg, int no); extern void exynos4_register_clocks(void); extern void exynos4_setup_clocks(void); -#ifdef CONFIG_CPU_EXYNOS4210 +#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_CPU_EXYNOS4212) extern int exynos4_init(void); extern void exynos4_init_irq(void); @@ -24,7 +26,7 @@ extern void exynos4_map_io(void); extern void exynos4_init_clocks(int xtal); extern struct sys_timer exynos4_timer; -#define exynos4_init_uarts exynos4_common_init_uarts +#define exynos4_init_uarts exynos_common_init_uarts #else #define exynos4_init_clocks NULL @@ -32,3 +34,15 @@ extern struct sys_timer exynos4_timer; #define exynos4_map_io NULL #define exynos4_init NULL #endif + +#if defined(CONFIG_CPU_EXYNOS4210) +extern void exynos4210_register_clocks(void); +#else +#define exynos4210_register_clocks() do { } while(0) +#endif + +#if defined(CONFIG_CPU_EXYNOS4212) +extern void exynos4212_register_clocks(void); +#else +#define exynos4212_register_clocks() do { } while(0) +#endif diff --git a/arch/arm/plat-s5p/include/plat/exynos5.h b/arch/arm/plat-s5p/include/plat/exynos5.h new file mode 100644 index 0000000..bcc22ef --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/exynos5.h @@ -0,0 +1,36 @@ +/* linux/arch/arm/plat-s5p/include/plat/exynos5.h + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Header file for exynos5 cpu support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/* Common init code for EXYNOS5 related SoCs */ + +struct s3c2410_uartcfg; + +extern void exynos_common_init_uarts(struct s3c2410_uartcfg *cfg, int no); +extern void exynos5_register_clocks(void); +extern void exynos5_setup_clocks(void); + +#if defined(CONFIG_CPU_EXYNOS5210) || defined(CONFIG_CPU_EXYNOS5250) + +extern int exynos5_init(void); +extern void exynos5_init_irq(void); +extern void exynos5_map_io(void); +extern void exynos5_init_clocks(int xtal); +extern struct sys_timer exynos4_timer; + +#define exynos5_init_uarts exynos_common_init_uarts + +#else +#define exynos5_init_clocks NULL +#define exynos5_init_uarts NULL +#define exynos5_map_io NULL +#define exynos5_init NULL +#endif diff --git a/arch/arm/plat-s5p/include/plat/fb-s5p.h b/arch/arm/plat-s5p/include/plat/fb-s5p.h new file mode 100644 index 0000000..017a8b0 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/fb-s5p.h @@ -0,0 +1,97 @@ +/* linux/arch/arm/plat-s5p/include/plat/fb-s5p.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Core file for Samsung Display Controller (FIMD) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_PLAT_FB_S5P_H +#define __ASM_PLAT_FB_S5P_H __FILE__ + +#define FB_SWAP_WORD (1 << 24) +#define FB_SWAP_HWORD (1 << 16) +#define FB_SWAP_BYTE (1 << 8) +#define FB_SWAP_BIT (1 << 0) + +struct platform_device; +struct clk; + +#ifdef CONFIG_FB_S5P_MIPI_DSIM +/* enumerates display mode. */ +enum { + SINGLE_LCD_MODE = 1, + DUAL_LCD_MODE = 2, +}; + +/* enumerates interface mode. */ +enum { + FIMD_RGB_INTERFACE = 1, + FIMD_CPU_INTERFACE = 2, +}; +#endif + +struct s3c_platform_fb { + int hw_ver; + char clk_name[16]; + int nr_wins; + int nr_buffers[5]; + int default_win; + int swap; + void *lcd; +#ifdef CONFIG_FB_S5P_MIPI_DSIM + unsigned int sub_lcd_enabled; + unsigned int machine_is_cypress; + unsigned int machine_is_p1p2; + unsigned int mdnie_is_enabled; + unsigned int mipi_is_enabled; + unsigned int interface_mode; + + void *single_lcd; + void *dual_lcd; + + void (*set_display_path)(unsigned int mode); + int (*reset_lcd)(void); + + /* variables and interface for mDNIe */ + char mdnie_clk_name[20]; + void *mdnie_clk; + unsigned int mdnie_phy_base; + unsigned int ielcd_phy_base; + void __iomem *mdnie_mmio_base; + void __iomem *ielcd_mmio_base; + unsigned char mdnie_mode; + + void (*set_mdnie_clock)(void *mdnie_clk, unsigned char enable); + void (*init_mdnie)(unsigned int mdnie_base, + unsigned int hsize, unsigned int vsize); + void (*mdnie_set_mode)(unsigned int mdnie_base, unsigned char mode); + + void (*start_ielcd_logic)(unsigned int ielcd_base); + void (*init_ielcd)(unsigned int ielcd_base, void *l, void *c); +#endif + void (*cfg_gpio)(struct platform_device *dev); + int (*backlight_on)(struct platform_device *dev); + int (*backlight_off)(struct platform_device *dev); + int (*lcd_on)(struct platform_device *dev); + int (*lcd_off)(struct platform_device *dev); + int (*clk_on)(struct platform_device *pdev, struct clk **s3cfb_clk); + int (*clk_off)(struct platform_device *pdev, struct clk **clk); +}; + +extern void s3cfb_set_platdata(struct s3c_platform_fb *fimd); + +/* defined by architecture to configure gpio */ +extern void s3cfb_cfg_gpio(struct platform_device *pdev); +extern int s3cfb_backlight_on(struct platform_device *pdev); +extern int s3cfb_backlight_off(struct platform_device *pdev); +extern int s3cfb_lcd_on(struct platform_device *pdev); +extern int s3cfb_lcd_off(struct platform_device *pdev); +extern int s3cfb_clk_on(struct platform_device *pdev, struct clk **s3cfb_clk); +extern int s3cfb_clk_off(struct platform_device *pdev, struct clk **clk); +extern void s3cfb_get_clk_name(char *clk_name); +#endif /* __ASM_PLAT_FB_S5P_H */ diff --git a/arch/arm/plat-s5p/include/plat/fimc.h b/arch/arm/plat-s5p/include/plat/fimc.h new file mode 100644 index 0000000..037b70f --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/fimc.h @@ -0,0 +1,153 @@ +/* linux/arch/arm/plat-s5p/include/plat/fimc.h + * + * Copyright 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Platform header file for Samsung Camera Interface (FIMC) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ +#ifndef __ASM_PLAT_FIMC_H +#define __ASM_PLAT_FIMC_H __FILE__ + +#include <linux/videodev2.h> + +#define FIMC_SRC_MAX_W 4224 +#define FIMC_SRC_MAX_H 4224 +#define FLITE_MAX_NUM 2 + +struct platform_device; + +/* For exnternal camera device */ +enum fimc_cam_type { + CAM_TYPE_ITU = 0, + CAM_TYPE_MIPI = 1, +}; + +enum fimc_cam_format { + ITU_601_YCBCR422_8BIT = (1 << 31), + ITU_656_YCBCR422_8BIT = (0 << 31), + ITU_601_YCBCR422_16BIT = (1 << 29), + MIPI_CSI_YCBCR422_8BIT = 0x1e, + MIPI_CSI_RAW8 = 0x2a, + MIPI_CSI_RAW10 = 0x2b, + MIPI_CSI_RAW12 = 0x2c, + MIPI_USER_DEF_PACKET_1 = 0x30, /* User defined Byte-based packet 1 */ +}; + +enum fimc_cam_order422 { + CAM_ORDER422_8BIT_YCBYCR = (0 << 14), + CAM_ORDER422_8BIT_YCRYCB = (1 << 14), + CAM_ORDER422_8BIT_CBYCRY = (2 << 14), + CAM_ORDER422_8BIT_CRYCBY = (3 << 14), + CAM_ORDER422_16BIT_Y4CBCRCBCR = (0 << 14), + CAM_ORDER422_16BIT_Y4CRCBCRCB = (1 << 14), +}; + +enum fimc_cam_index { + CAMERA_PAR_A = 0, + CAMERA_PAR_B = 1, + CAMERA_CSI_C = 2, + CAMERA_CSI_D = 3, + CAMERA_WB = 4, + CAMERA_WB_B = 5, + CAMERA_PATTERN = 6, +}; + +enum flite_index { + FLITE_IDX_A = 0, + FLITE_IDX_B = 1, +}; + +/* struct s3c_platform_camera: abstraction for input camera */ +struct s3c_platform_camera { + /* + * ITU cam A,B: 0,1 + * CSI-2 cam C: 2 + */ + enum fimc_cam_index id; + + enum fimc_cam_type type; /* ITU or MIPI */ + enum fimc_cam_format fmt; /* input format */ + enum fimc_cam_order422 order422; /* YCBCR422 order for ITU */ + u32 pixelformat; /* default fourcc */ + + int i2c_busnum; + int (*get_i2c_busnum)(void); + struct i2c_board_info *info; + struct v4l2_subdev *sd; + + const char srclk_name[16]; /* source of mclk name */ + const char clk_name[16]; /* mclk name */ + const char* (*get_clk_name)(void); /* mclk name */ + u32 clk_rate; /* mclk ratio */ + struct clk *clk; /* mclk */ + int line_length; /* max length */ + int width; /* default resol */ + int height; /* default resol */ + struct v4l2_rect window; /* real cut region from source */ + + int mipi_lanes; /* MIPI data lanes */ + int mipi_settle; /* MIPI settle */ + int mipi_align; /* MIPI data align: 24/32 */ + + /* Polarity: 1 if inverted polarity used */ + int inv_pclk; + int inv_vsync; + int inv_href; + int inv_hsync; + + int initialized; + /* The cam needs reset before start streaming */ + int reset_camera; + + /* Board specific power pin control */ + int (*cam_power)(int onoff); + enum flite_index flite_id; + bool use_isp; + int sensor_index; +}; + +/* For camera interface driver */ +struct s3c_platform_fimc { + enum fimc_cam_index default_cam; /* index of default cam */ +#ifdef CONFIG_ARCH_EXYNOS4 + struct s3c_platform_camera *camera[7]; /* FIXME */ +#else + struct s3c_platform_camera *camera[5]; /* FIXME */ +#endif + int hw_ver; + bool use_cam; + + void (*cfg_gpio)(struct platform_device *pdev); + int (*clk_on)(struct platform_device *pdev, struct clk **clk); + int (*clk_off)(struct platform_device *pdev, struct clk **clk); +}; + +extern void s3c_fimc0_set_platdata(struct s3c_platform_fimc *fimc); +extern void s3c_fimc1_set_platdata(struct s3c_platform_fimc *fimc); +extern void s3c_fimc2_set_platdata(struct s3c_platform_fimc *fimc); +#ifdef CONFIG_ARCH_EXYNOS4 +extern void s3c_fimc3_set_platdata(struct s3c_platform_fimc *fimc); +#endif + +/* defined by architecture to configure gpio */ +extern void s3c_fimc0_cfg_gpio(struct platform_device *pdev); +extern void s3c_fimc1_cfg_gpio(struct platform_device *pdev); +extern void s3c_fimc2_cfg_gpio(struct platform_device *pdev); +#ifdef CONFIG_ARCH_EXYNOS4 +extern void s3c_fimc3_cfg_gpio(struct platform_device *pdev); +#endif +/* platform specific clock functions */ +extern int s3c_fimc_clk_on(struct platform_device *pdev, struct clk **clk); +extern int s3c_fimc_clk_off(struct platform_device *pdev, struct clk **clk); + +#ifdef CONFIG_DRM_EXYNOS_FIMD_WB +#include <linux/notifier.h> +extern int fimc_register_client(struct notifier_block *nb); +extern int fimc_unregister_client(struct notifier_block *nb); +#endif + +#endif /*__ASM_PLAT_FIMC_H */ diff --git a/arch/arm/plat-s5p/include/plat/fimg2d.h b/arch/arm/plat-s5p/include/plat/fimg2d.h new file mode 100644 index 0000000..2a2e622 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/fimg2d.h @@ -0,0 +1,26 @@ +/* linux/arch/arm/plat-s5p/include/plat/fimg2d.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Platform Data Structure for Samsung Graphics 2D Hardware + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_FIMG2D_H +#define __ASM_ARCH_FIMG2D_H __FILE__ + +struct fimg2d_platdata { + int hw_ver; + const char *parent_clkname; + const char *clkname; + const char *gate_clkname; + unsigned long clkrate; +}; + +extern void __init s5p_fimg2d_set_platdata(struct fimg2d_platdata *pd); + +#endif /* __ASM_ARCH_FIMG2D_H */ diff --git a/arch/arm/plat-s5p/include/plat/hdmi.h b/arch/arm/plat-s5p/include/plat/hdmi.h new file mode 100644 index 0000000..3dcd034 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/hdmi.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim <jy0922.shim@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundationr + */ + +#ifndef __PLAT_SAMSUNG_HDMI_H +#define __PLAT_SAMSUNG_HDMI_H + +/** + * Platform device data for Samsung hdmi + * + * @is_v13: use hdmi version 1.3 + * @cfg_hpd: configure the hpd pin, if enable, set to hpd special function 3, + * else set to external interrupt. + * @get_hpd: get level value of hpd pin + */ +struct s5p_hdmi_platdata { + bool is_v13; + void (*cfg_hpd)(bool enable); + int (*get_hpd)(void); +}; + +extern void s5p_hdmi_set_platdata(struct s5p_hdmi_platdata *pd); +#ifdef CONFIG_EXYNOS4_SETUP_HDMI +extern void s5p_hdmi_cfg_hpd(bool enable); +extern int s5p_hdmi_get_hpd(void); +#else +static inline void s5p_hdmi_cfg_hpd(bool enable) { } +static inline int s5p_hdmi_get_hpd(void) { return 0; } +#endif + +#endif /* __PLAT_SAMSUNG_HDMI_H */ diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h index ba9121c..8f3f616 100644 --- a/arch/arm/plat-s5p/include/plat/irqs.h +++ b/arch/arm/plat-s5p/include/plat/irqs.h @@ -101,7 +101,11 @@ S5P_GPIOINT_GROUP_COUNT chips, each with total number of S5P_GPIOINT_GROUP_SIZE pins/irqs. Each GPIOINT group can be assiged to any gpio chip with the s5p_register_gpio_interrupt() function */ +#ifdef CONFIG_MACH_MIDAS +#define S5P_GPIOINT_GROUP_COUNT 5 +#else #define S5P_GPIOINT_GROUP_COUNT 4 +#endif #define S5P_GPIOINT_GROUP_SIZE 8 #define S5P_GPIOINT_COUNT (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE) diff --git a/arch/arm/plat-s5p/include/plat/jpeg.h b/arch/arm/plat-s5p/include/plat/jpeg.h new file mode 100644 index 0000000..29784fb --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/jpeg.h @@ -0,0 +1,17 @@ +/* linux/arch/arm/plat-s5p/include/plat/jpeg.h + * + * Copyright 201i Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ +#ifndef __ASM_PLAT_JPEG_H +#define __ASM_PLAT_JPEG_H __FILE__ + +int __init exynos4_jpeg_setup_clock(struct device *dev, + unsigned long clk_rate); +int __init exynos5_jpeg_setup_clock(struct device *dev, + unsigned long clk_rate); +#endif /*__ASM_PLAT_JPEG_H */ diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h index d973d39..3e576956 100644 --- a/arch/arm/plat-s5p/include/plat/map-s5p.h +++ b/arch/arm/plat-s5p/include/plat/map-s5p.h @@ -20,8 +20,10 @@ #define S5P_VA_GPIO1 S5P_VA_GPIO #define S5P_VA_GPIO2 S3C_ADDR(0x02240000) #define S5P_VA_GPIO3 S3C_ADDR(0x02280000) +#define S5P_VA_GPIO4 S3C_ADDR(0x022C0000) #define S5P_VA_SYSRAM S3C_ADDR(0x02400000) +#define S5P_VA_SYSRAM_NS S3C_ADDR(0x02410000) #define S5P_VA_DMC0 S3C_ADDR(0x02440000) #define S5P_VA_DMC1 S3C_ADDR(0x02480000) #define S5P_VA_SROMC S3C_ADDR(0x024C0000) @@ -35,12 +37,34 @@ #define S5P_VA_COREPERI_BASE S3C_ADDR(0x02800000) #define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x)) #define S5P_VA_SCU S5P_VA_COREPERI(0x0) -#define S5P_VA_GIC_CPU S5P_VA_COREPERI(0x100) #define S5P_VA_TWD S5P_VA_COREPERI(0x600) -#define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000) + +#define S5P_VA_GIC_CPU S3C_ADDR(0x02810000) +#define S5P_VA_GIC_DIST S3C_ADDR(0x02820000) #define S3C_VA_USB_HSPHY S3C_ADDR(0x02900000) +#define S5P_VA_AUDSS S3C_ADDR(0x02910000) + +#define S5P_VA_PPMU_DMC0 S3C_ADDR(0x02930000) +#define S5P_VA_PPMU_DMC1 S3C_ADDR(0x02932000) +#define S5P_VA_PPMU_CPU S3C_ADDR(0x02934000) + +#define S5P_VA_GDL S3C_ADDR(0x02940000) +#define S5P_VA_GDR S3C_ADDR(0x02941000) + +#define S5P_VA_PPMU_DDR_C S3C_ADDR(0x02936000) +#define S5P_VA_PPMU_DDR_R1 S3C_ADDR(0x02938000) +#define S5P_VA_PPMU_DDR_L S3C_ADDR(0x0293a000) +#define S5P_VA_PPMU_RIGHT0_BUS S3C_ADDR(0x0293c000) + +#define S5P_VA_SS_PHY S3C_ADDR(0x02A00000) +#define S5P_VA_FIMCLITE0 S3C_ADDR(0x02A10000) +#define S5P_VA_FIMCLITE1 S3C_ADDR(0x02A20000) +#define S5P_VA_MIPICSI0 S3C_ADDR(0x02A30000) +#define S5P_VA_MIPICSI1 S3C_ADDR(0x02A40000) +#define S5P_VA_FIMCLITE2 S3C_ADDR(0x02A90000) + #define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000)) #define VA_VIC0 VA_VIC(0) #define VA_VIC1 VA_VIC(1) diff --git a/arch/arm/plat-s5p/include/plat/media.h b/arch/arm/plat-s5p/include/plat/media.h new file mode 100644 index 0000000..61e28bc --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/media.h @@ -0,0 +1,40 @@ +/* linux/arch/arm/plat-s5p/include/plat/media.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Samsung Media device descriptions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef _S5P_MEDIA_H +#define _S5P_MEDIA_H + +#include <linux/types.h> +#include <asm/setup.h> + +#ifdef CONFIG_CMA +#include <linux/cma.h> +void s5p_cma_region_reserve(struct cma_region *regions_normal, + struct cma_region *regions_secure, + size_t align_secure, const char *map); +#else + +struct s5p_media_device { + u32 id; + const char *name; + u32 bank; + size_t memsize; + dma_addr_t paddr; +}; + +extern struct meminfo meminfo; +extern dma_addr_t s5p_get_media_memory_bank(int dev_id, int bank); +extern size_t s5p_get_media_memsize_bank(int dev_id, int bank); +extern dma_addr_t s5p_get_media_membase_bank(int bank); +extern void s5p_reserve_mem(size_t boundary); +#endif /* CONFIG_CMA */ +#endif diff --git a/arch/arm/plat-s5p/include/plat/mipi_csis.h b/arch/arm/plat-s5p/include/plat/mipi_csis.h index 9bd254c..561a8c6 100644 --- a/arch/arm/plat-s5p/include/plat/mipi_csis.h +++ b/arch/arm/plat-s5p/include/plat/mipi_csis.h @@ -39,5 +39,7 @@ struct s5p_platform_mipi_csis { * false to disable D-PHY */ int s5p_csis_phy_enable(struct platform_device *pdev, bool on); +extern struct s5p_platform_mipi_csis s5p_mipi_csis0_default_data; +extern struct s5p_platform_mipi_csis s5p_mipi_csis1_default_data; #endif /* PLAT_S5P_MIPI_CSIS_H_ */ diff --git a/arch/arm/plat-s5p/include/plat/mipi_dsi.h b/arch/arm/plat-s5p/include/plat/mipi_dsi.h new file mode 100644 index 0000000..9fcde67 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/mipi_dsi.h @@ -0,0 +1,51 @@ +/* linux/arm/arch/mach-s5pc110/include/plat/mipi_dsi.h + * + * + * Copyright (c) 2011 Samsung Electronics + * InKi Dae <inki.dae <at> samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef _MIPI_DSI_H +#define _MIPI_DSI_H + +#if defined(CONFIG_LCD_MIPI_S6E8AB0) +extern struct mipi_dsim_lcd_driver s6e8ab0_mipi_lcd_driver; +#elif defined (CONFIG_LCD_MIPI_S6E63M0) +extern struct mipi_dsim_lcd_driver s6e63m0_mipi_lcd_driver; +#elif defined (CONFIG_LCD_MIPI_TC358764) +extern struct mipi_dsim_lcd_driver tc358764_mipi_lcd_driver; +#endif + +extern int s5p_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, + unsigned int data_id, unsigned int data0, unsigned int data1); + +enum mipi_ddi_interface { + RGB_IF = 0x4000, + I80_IF = 0x8000, + YUV_601 = 0x10000, + YUV_656 = 0x20000, + MIPI_VIDEO = 0x1000, + MIPI_COMMAND = 0x2000, +}; + +enum mipi_ddi_panel_select { + DDI_MAIN_LCD = 0, + DDI_SUB_LCD = 1, +}; + +enum mipi_ddi_model { + S6DR117 = 0, +}; + +enum mipi_ddi_parameter { + /* DSIM video interface parameter */ + DSI_VIRTUAL_CH_ID = 0, + DSI_FORMAT = 1, + DSI_VIDEO_MODE_SEL = 2, +}; + +#endif /* _MIPI_DSI_H */ diff --git a/arch/arm/plat-s5p/include/plat/mipi_dsim2.h b/arch/arm/plat-s5p/include/plat/mipi_dsim2.h new file mode 100644 index 0000000..3aaff61 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/mipi_dsim2.h @@ -0,0 +1,392 @@ +/* linux/arm/arch/plat-s5p/include/plat/mipi_dsim2.h + * + * Platform data header for Samsung SoC MIPI-DSIM. + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd + * + * InKi Dae <inki.dae@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef _MIPI_DSIM2_H +#define _MIPI_DSIM2_H + +#include <linux/device.h> +#include <linux/fb.h> + +#define PANEL_NAME_SIZE (32) + +/* + * enumurate display interface type. + * + * DSIM_COMMAND means cpu interface and rgb interface for DSIM_VIDEO. + * + * P.S. MIPI DSI Master has two display controller intefaces, RGB Interface + * for main display and CPU Interface(same as I80 Interface) for main + * and sub display. + */ +enum mipi_dsim_interface_type { + DSIM_COMMAND, + DSIM_VIDEO +}; + +enum mipi_dsim_virtual_ch_no { + DSIM_VIRTUAL_CH_0, + DSIM_VIRTUAL_CH_1, + DSIM_VIRTUAL_CH_2, + DSIM_VIRTUAL_CH_3 +}; + +enum mipi_dsim_burst_mode_type { + DSIM_NON_BURST_SYNC_EVENT, + DSIM_BURST_SYNC_EVENT, + DSIM_NON_BURST_SYNC_PULSE, + DSIM_BURST, + DSIM_NON_VIDEO_MODE +}; + +enum mipi_dsim_no_of_data_lane { + DSIM_DATA_LANE_1, + DSIM_DATA_LANE_2, + DSIM_DATA_LANE_3, + DSIM_DATA_LANE_4 +}; + +enum mipi_dsim_byte_clk_src { + DSIM_PLL_OUT_DIV8, + DSIM_EXT_CLK_DIV8, + DSIM_EXT_CLK_BYPASS +}; + +enum mipi_dsim_pixel_format { + DSIM_CMD_3BPP, + DSIM_CMD_8BPP, + DSIM_CMD_12BPP, + DSIM_CMD_16BPP, + DSIM_VID_16BPP_565, + DSIM_VID_18BPP_666PACKED, + DSIM_18BPP_666LOOSELYPACKED, + DSIM_24BPP_888 +}; + +/** + * struct mipi_dsim_config - interface for configuring mipi-dsi controller. + * + * @auto_flush: enable or disable Auto flush of MD FIFO using VSYNC pulse. + * @eot_disable: enable or disable EoT packet in HS mode. + * @auto_vertical_cnt: specifies auto vertical count mode. + * in Video mode, the vertical line transition uses line counter + * configured by VSA, VBP, and Vertical resolution. + * If this bit is set to '1', the line counter does not use VSA and VBP + * registers.(in command mode, this variable is ignored) + * @hse: set horizontal sync event mode. + * In VSYNC pulse and Vporch area, MIPI DSI master transfers only HSYNC + * start packet to MIPI DSI slave at MIPI DSI spec1.1r02. + * this bit transfers HSYNC end packet in VSYNC pulse and Vporch area + * (in mommand mode, this variable is ignored) + * @hfp: specifies HFP disable mode. + * if this variable is set, DSI master ignores HFP area in VIDEO mode. + * (in command mode, this variable is ignored) + * @hbp: specifies HBP disable mode. + * if this variable is set, DSI master ignores HBP area in VIDEO mode. + * (in command mode, this variable is ignored) + * @hsa: specifies HSA disable mode. + * if this variable is set, DSI master ignores HSA area in VIDEO mode. + * (in command mode, this variable is ignored) + * @cma_allow: specifies the number of horizontal lines, where command packet + * transmission is allowed after Stable VFP period. + * @e_interface: specifies interface to be used.(CPU or RGB interface) + * @e_virtual_ch: specifies virtual channel number that main or + * sub diaplsy uses. + * @e_pixel_format: specifies pixel stream format for main or sub display. + * @e_burst_mode: selects Burst mode in Video mode. + * in Non-burst mode, RGB data area is filled with RGB data and NULL + * packets, according to input bandwidth of RGB interface. + * In Burst mode, RGB data area is filled with RGB data only. + * @e_no_data_lane: specifies data lane count to be used by Master. + * @e_byte_clk: select byte clock source. (it must be DSIM_PLL_OUT_DIV8) + * DSIM_EXT_CLK_DIV8 and DSIM_EXT_CLK_BYPASSS are not supported. + * @pll_stable_time: specifies the PLL Timer for stability of the ganerated + * clock(System clock cycle base) + * if the timer value goes to 0x00000000, the clock stable bit of status + * and interrupt register is set. + * @esc_clk: specifies escape clock frequency for getting the escape clock + * prescaler value. + * @stop_holding_cnt: specifies the interval value between transmitting + * read packet(or write "set_tear_on" command) and BTA request. + * after transmitting read packet or write "set_tear_on" command, + * BTA requests to D-PHY automatically. this counter value specifies + * the interval between them. + * @bta_timeout: specifies the timer for BTA. + * this register specifies time out from BTA request to change + * the direction with respect to Tx escape clock. + * @rx_timeout: specifies the timer for LP Rx mode timeout. + * this register specifies time out on how long RxValid deasserts, + * after RxLpdt asserts with respect to Tx escape clock. + * - RxValid specifies Rx data valid indicator. + * - RxLpdt specifies an indicator that D-PHY is under RxLpdt mode. + * - RxValid and RxLpdt specifies signal from D-PHY. + */ +struct mipi_dsim_config { + unsigned char auto_flush; + unsigned char eot_disable; + + unsigned char auto_vertical_cnt; + unsigned char hse; + unsigned char hfp; + unsigned char hbp; + unsigned char hsa; + unsigned char cmd_allow; + + enum mipi_dsim_interface_type e_interface; + enum mipi_dsim_virtual_ch_no e_virtual_ch; + enum mipi_dsim_pixel_format e_pixel_format; + enum mipi_dsim_burst_mode_type e_burst_mode; + enum mipi_dsim_no_of_data_lane e_no_data_lane; + enum mipi_dsim_byte_clk_src e_byte_clk; + + /* + * =========================================== + * | P | M | S | MHz | + * ------------------------------------------- + * | 3 | 100 | 3 | 100 | + * | 3 | 100 | 2 | 200 | + * | 3 | 63 | 1 | 252 | + * | 4 | 100 | 1 | 300 | + * | 4 | 110 | 1 | 330 | + * | 12 | 350 | 1 | 350 | + * | 3 | 100 | 1 | 400 | + * | 4 | 150 | 1 | 450 | + * | 6 | 118 | 1 | 472 | + * | 3 | 120 | 1 | 480 | + * | 12 | 250 | 0 | 500 | + * | 4 | 100 | 0 | 600 | + * | 3 | 81 | 0 | 648 | + * | 3 | 88 | 0 | 704 | + * | 3 | 90 | 0 | 720 | + * | 3 | 100 | 0 | 800 | + * | 12 | 425 | 0 | 850 | + * | 4 | 150 | 0 | 900 | + * | 12 | 475 | 0 | 950 | + * | 6 | 250 | 0 | 1000 | + * ------------------------------------------- + */ + + /* + * pms could be calculated as the following. + * M * 24 / P * 2 ^ S = MHz + */ + unsigned char p; + unsigned short m; + unsigned char s; + + unsigned int pll_stable_time; + unsigned long esc_clk; + + unsigned short stop_holding_cnt; + unsigned char bta_timeout; + unsigned short rx_timeout; +}; + +/** + * struct mipi_dsim_device - global interface for mipi-dsi driver. + * + * @dev: driver model representation of the device. + * @id: unique device id. + * @clock: pointer to MIPI-DSI clock of clock framework. + * @irq: interrupt number to MIPI-DSI controller. + * @reg_base: base address to memory mapped SRF of MIPI-DSI controller. + * (virtual address) + * @lock: the mutex protecting this data structure. + * @dsim_info: infomation for configuring mipi-dsi controller. + * @master_ops: callbacks to mipi-dsi operations. + * @dsim_lcd_dev: pointer to activated ddi device. + * (it would be registered by mipi-dsi driver.) + * @dsim_lcd_drv: pointer to activated_ddi driver. + * (it would be registered by mipi-dsi driver.) + * @lcd_info: pointer to mipi_lcd_info structure. + * @early_blank_used_t: indicate whether mipi blank function is called + * or not by early fb blank envent and dpms operation of drm needs + * this flag. + * @state: specifies status of MIPI-DSI controller. + * the status could be RESET, INIT, STOP, HSCLKEN and ULPS. + * @data_lane: specifiec enabled data lane number. + * this variable would be set by driver according to e_no_data_lane + * automatically. + * @e_clk_src: select byte clock source. + * @pd: pointer to MIPI-DSI driver platform data. + * @reg_vdd10: 1.0V regulator for mipi. + * @reg_vdd18: 1.8V regulator for mipi. + * @suspended: indicate mipi-dsi driver is suspended or not. + * @enabled: power enable flag. + */ +struct mipi_dsim_device { + struct device *dev; + int id; + struct resource *res; + struct clk *clock; + unsigned int irq; + void __iomem *reg_base; + struct mutex lock; + + struct mipi_dsim_config *dsim_config; + struct mipi_dsim_master_ops *master_ops; + struct mipi_dsim_lcd_device *dsim_lcd_dev; + struct mipi_dsim_lcd_driver *dsim_lcd_drv; + + atomic_t early_blank_used_t; + unsigned int state; + unsigned int data_lane; + enum mipi_dsim_byte_clk_src e_clk_src; + + struct s5p_platform_mipi_dsim *pd; + + struct regulator *reg_vdd10; + struct regulator *reg_vdd18; + bool suspended; + bool enabled; +}; + +/** + * struct s5p_platform_mipi_dsim - interface to platform data + * for mipi-dsi driver. + * + * @lcd_panel_name: specifies lcd panel name registered to mipi-dsi driver. + * lcd panel driver searched would be actived. + * @dsim_config: pointer of structure for configuring mipi-dsi controller. + * @lcd_panel_info: pointer for lcd panel specific structure. + * this structure specifies width, height, timing and polarity and so on. + * @mipi_power: callback pointer for enabling or disabling mipi power. + * @enabled: flag to check mipi is turned on mipi already from bootloader. + * @phy_enable: pointer to a callback controlling D-PHY enable/reset + */ +struct s5p_platform_mipi_dsim { + char lcd_panel_name[PANEL_NAME_SIZE]; + + struct mipi_dsim_config *dsim_config; + void *lcd_panel_info; + + bool enabled; + int (*phy_enable)(struct platform_device *pdev, bool on); +}; +/** + * struct mipi_dsim_master_ops - callbacks to mipi-dsi operations. + * + * @cmd_write: transfer command to lcd panel at LP mode. + * @cmd_read: read command from rx register. + * @get_dsim_frame_done: get the status that all screen data have been + * transferred to mipi-dsi. + * @clear_dsim_frame_done: clear frame done status. + * @get_fb_frame_done: get frame done status of display controller. + * @trigger: trigger display controller. + * - this one would be used only in case of CPU mode. + * @set_early_blank_mode: set framebuffer blank mode. + * - this callback should be called prior to fb_blank() by a client driver + * only if needing. + * @set_blank_mode: set framebuffer blank mode. + * - this callback should be called after fb_blank() by a client driver + * only if needing. + */ + +struct mipi_dsim_master_ops { + int (*cmd_write)(struct mipi_dsim_device *dsim, unsigned int data_id, + unsigned int data0, unsigned int data1); + int (*cmd_read)(struct mipi_dsim_device *dsim, unsigned int data_id, + unsigned int data0, unsigned int req_size, u8 *rx_buf); + int (*get_dsim_frame_done)(struct mipi_dsim_device *dsim); + int (*clear_dsim_frame_done)(struct mipi_dsim_device *dsim); + + int (*get_fb_frame_done)(struct fb_info *info); + void (*trigger)(struct fb_info *info); + int (*set_early_blank_mode)(struct mipi_dsim_device *dsim, int power); + int (*set_blank_mode)(struct mipi_dsim_device *dsim, int power); + void (*set_pms)(struct mipi_dsim_device *dsim, unsigned int p, + unsigned int m, unsigned int s, unsigned int freq_band); +}; + +/** + * device structure for mipi-dsi based lcd panel. + * + * @name: name of the device to use with this device, or an + * alias for that name. + * @dev: driver model representation of the device. + * @id: id of device to be registered. + * @bus_id: bus id for identifing connected bus + * and this bus id should be same as id of mipi_dsim_device. + * @irq: irq number for signaling when framebuffer transfer of + * lcd panel module is completed. + * this irq would be used only for MIPI-DSI based CPU mode lcd panel. + * @master: pointer to mipi-dsi master device object. + * @platform_data: lcd panel specific platform data. + */ +struct mipi_dsim_lcd_device { + char *name; + struct device dev; + int id; + int bus_id; + int irq; + + struct mipi_dsim_device *master; + void *platform_data; +}; + +/** + * driver structure for mipi-dsi based lcd panel. + * + * this structure should be registered by lcd panel driver. + * mipi-dsi driver seeks lcd panel registered through name field + * and calls these callback functions in appropriate time. + * + * @name: name of the driver to use with this device, or an + * alias for that name. + * @id: id of driver to be registered. + * this id would be used for finding device object registered. + */ +struct mipi_dsim_lcd_driver { + char *name; + int id; + + int (*check_mtp)(struct mipi_dsim_lcd_device *dsim_dev); + void (*power_on)(struct mipi_dsim_lcd_device *dsim_dev, + unsigned int enable); + void (*set_sequence)(struct mipi_dsim_lcd_device *dsim_dev); + int (*probe)(struct mipi_dsim_lcd_device *dsim_dev); + void (*remove)(struct mipi_dsim_lcd_device *dsim_dev); + void (*shutdown)(struct mipi_dsim_lcd_device *dsim_dev); + int (*suspend)(struct mipi_dsim_lcd_device *dsim_dev); + int (*resume)(struct mipi_dsim_lcd_device *dsim_dev); +}; + +/** + * register mipi_dsim_lcd_driver object defined by lcd panel driver + * to mipi-dsi driver. + */ +int s5p_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver + *lcd_drv); + +/** + * register mipi_dsim_lcd_device to mipi-dsi master. + */ +int s5p_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device + *lcd_dev); + +/** + * s5p_dsim_phy_enable - global MIPI-DSI receiver D-PHY control + * @pdev: MIPI-DSIM platform device + * @on: true to enable D-PHY and deassert its reset + * false to disable D-PHY + */ +int s5p_dsim_phy_enable(struct platform_device *pdev, bool on); + +/* register a callback for mipi-dsi driver to drm based fimd driver. */ +extern int fimd_register_client(int (*client_notifier)(unsigned int val, + void *data), void *data); + +/* unregister the callback above from drm based fimd driver. */ +extern void fimd_unregister_client(int (*client_notifier)(unsigned int val, + void *data)); + +#endif /* _MIPI_DSIM2_H */ diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h index bf28fad..4b50b32 100644 --- a/arch/arm/plat-s5p/include/plat/pll.h +++ b/arch/arm/plat-s5p/include/plat/pll.h @@ -12,6 +12,59 @@ * published by the Free Software Foundation. */ +#define PLL35XX_MDIV_MASK (0x3FF) +#define PLL35XX_PDIV_MASK (0x3F) +#define PLL35XX_SDIV_MASK (0x7) +#define PLL35XX_MDIV_SHIFT (16) +#define PLL35XX_PDIV_SHIFT (8) +#define PLL35XX_SDIV_SHIFT (0) + +#include <asm/div64.h> + +static inline unsigned long s5p_get_pll35xx(unsigned long baseclk, u32 pll_con) +{ + u32 mdiv, pdiv, sdiv; + u64 fvco = baseclk; + + mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK; + pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK; + sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK; + + fvco *= mdiv; + do_div(fvco, (pdiv << sdiv)); + + return (unsigned long)fvco; +} + +#define PLL36XX_KDIV_MASK (0xFFFF) +#define PLL36XX_MDIV_MASK (0x1FF) +#define PLL36XX_PDIV_MASK (0x3F) +#define PLL36XX_SDIV_MASK (0x7) +#define PLL36XX_MDIV_SHIFT (16) +#define PLL36XX_PDIV_SHIFT (8) +#define PLL36XX_SDIV_SHIFT (0) + +static inline unsigned long s5p_get_pll36xx(unsigned long baseclk, + u32 pll_con0, u32 pll_con1) +{ + unsigned long result; + u32 mdiv, pdiv, sdiv, kdiv; + u64 tmp; + + mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK; + pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK; + sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK; + kdiv = pll_con1 & PLL36XX_KDIV_MASK; + + tmp = baseclk; + + tmp *= (mdiv << 16) + kdiv; + do_div(tmp, (pdiv << sdiv)); + result = tmp >> 16; + + return result; +} + #define PLL45XX_MDIV_MASK (0x3FF) #define PLL45XX_PDIV_MASK (0x3F) #define PLL45XX_SDIV_MASK (0x7) @@ -19,8 +72,6 @@ #define PLL45XX_PDIV_SHIFT (8) #define PLL45XX_SDIV_SHIFT (0) -#include <asm/div64.h> - enum pll45xx_type_t { pll_4500, pll_4502, @@ -72,7 +123,6 @@ static inline unsigned long s5p_get_pll46xx(unsigned long baseclk, mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK; pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK; sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK; - kdiv = pll_con1 & PLL46XX_KDIV_MASK; if (pll_type == pll_4650c) kdiv = pll_con1 & PLL4650C_KDIV_MASK; diff --git a/arch/arm/plat-s5p/include/plat/regs-csis.h b/arch/arm/plat-s5p/include/plat/regs-csis.h new file mode 100644 index 0000000..da80917 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/regs-csis.h @@ -0,0 +1,124 @@ +/* linux/arch/arm/plat-s5p/include/plat/regs-csis.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Register definition file for MIPI-CSI2 Driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_PLAT_REGS_CSIS_H +#define __ASM_PLAT_REGS_CSIS_H __FILE__ + +/* + * Registers +*/ +#define S3C_CSIS_CONTROL (0x00) +#define S3C_CSIS_DPHYCTRL (0x04) +#define S3C_CSIS_CONFIG (0x08) +#define S3C_CSIS_DPHYSTS (0x0c) +#define S3C_CSIS_INTMSK (0x10) +#define S3C_CSIS_INTSRC (0x14) +#define S3C_CSIS_RESOL (0x2c) +#define S3C_CSIS_PKTDATA_ODD (0x2000) +#define S3C_CSIS_PKTDATA_EVEN (0x3000) + + + +/* + * Bit Definitions +*/ +/* Control Register */ +#define S3C_CSIS_CONTROL_DPDN_DEFAULT (0 << 31) +#define S3C_CSIS_CONTROL_DPDN_SWAP (1 << 31) +#define S3C_CSIS_CONTROL_ALIGN_32BIT (1 << 20) +#define S3C_CSIS_CONTROL_ALIGN_24BIT (0 << 20) +#define S3C_CSIS_CONTROL_ALIGN_MASK (1 << 20) +#define S3C_CSIS_CONTROL_UPDATE_SHADOW (1 << 16) +#define S3C_CSIS_CONTROL_WCLK_PCLK (0 << 8) +#define S3C_CSIS_CONTROL_WCLK_EXTCLK (1 << 8) +#define S3C_CSIS_CONTROL_WCLK_MASK (1 << 8) +#define S3C_CSIS_CONTROL_RESET (1 << 4) +#define S3C_CSIS_CONTROL_DISABLE (0 << 0) +#define S3C_CSIS_CONTROL_ENABLE (1 << 0) + +/* D-PHY Control Register */ +#define S3C_CSIS_DPHYCTRL_HS_SETTLE_MASK (0x1f << 27) +#define S3C_CSIS_DPHYCTRL_HS_SETTLE_SHIFT (27) +#define S3C_CSIS_DPHYCTRL_ENABLE (0x1f << 0) + +/* Configuration Register */ +#define S3C_CSIS_CONFIG_FORMAT_SHIFT (2) +#define S3C_CSIS_CONFIG_FORMAT_MASK (0x3f << 2) +#define S3C_CSIS_CONFIG_NR_LANE_1 (0 << 0) +#define S3C_CSIS_CONFIG_NR_LANE_2 (1 << 0) +#define S3C_CSIS_CONFIG_NR_LANE_3 (1 << 1) +#define S3C_CSIS_CONFIG_NR_LANE_4 (0x3 << 0) +#define S3C_CSIS_CONFIG_NR_LANE_MASK (1 << 0) + +/* D-PHY Status Register */ +#define S3C_CSIS_DPHYSTS_STOPSTATE_LANE1 (1 << 5) +#define S3C_CSIS_DPHYSTS_STOPSTATE_LANE0 (1 << 4) +#define S3C_CSIS_DPHYSTS_STOPSTATE_CLOCK (1 << 0) + +/* Interrupt Mask Register */ +#define S3C_CSIS_INTMSK_EVEN_BEFORE_DISABLE (0 << 31) +#define S3C_CSIS_INTMSK_EVEN_BEFORE_ENABLE (1 << 31) +#define S3C_CSIS_INTMSK_EVEN_AFTER_DISABLE (0 << 30) +#define S3C_CSIS_INTMSK_EVEN_AFTER_ENABLE (1 << 30) +#define S3C_CSIS_INTMSK_ODD_BEFORE_DISABLE (0 << 29) +#define S3C_CSIS_INTMSK_ODD_BEFORE_ENABLE (1 << 29) +#define S3C_CSIS_INTMSK_ODD_AFTER_DISABLE (0 << 28) +#define S3C_CSIS_INTMSK_ODD_AFTER_ENABLE (1 << 28) +#define S3C_CSIS_INTMSK_ERR_SOT_HS_DISABLE (0 << 12) +#define S3C_CSIS_INTMSK_ERR_SOT_HS_ENABLE (1 << 12) + +#define S3C_CSIS_INTMSK_ERR_LOST_FS_DISABLE (0 << 5) +#define S3C_CSIS_INTMSK_ERR_LOST_FS_ENABLE (1 << 5) + +#define S3C_CSIS_INTMSK_ERR_LOST_FE_DISABLE (0 << 4) +#define S3C_CSIS_INTMSK_ERR_LOST_FE_ENABLE (1 << 4) +#define S3C_CSIS_INTMSK_ERR_OVER_DISABLE (0 << 3) +#define S3C_CSIS_INTMSK_ERR_OVER_ENABLE (1 << 3) + +#define S3C_CSIS_INTMSK_ERR_ECC_DISABLE (0 << 2) +#define S3C_CSIS_INTMSK_ERR_ECC_ENABLE (1 << 2) +#define S3C_CSIS_INTMSK_ERR_CRC_DISABLE (0 << 1) +#define S3C_CSIS_INTMSK_ERR_CRC_ENABLE (1 << 1) +#define S3C_CSIS_INTMSK_ERR_ID_DISABLE (0 << 0) +#define S3C_CSIS_INTMSK_ERR_ID_ENABLE (1 << 0) + +/* Interrupt Source Register */ +#define S3C_CSIS_INTSRC_EVEN_BEFORE (1 << 31) +#define S3C_CSIS_INTSRC_EVEN_AFTER (1 << 30) +#define S3C_CSIS_INTSRC_ODD_BEFORE (1 << 29) +#define S3C_CSIS_INTSRC_ODD_AFTER (1 << 28) + +#define S3C_CSIS_INTSRC_ERR_SOT_HS (0xF << 12) +#define S3C_CSIS_INTSRC_ERR_LOST_FS (1 << 5) +#define S3C_CSIS_INTSRC_ERR_LOST_FE (1 << 4) +#define S3C_CSIS_INTSRC_ERR_OVER (1 << 3) +#define S3C_CSIS_INTSRC_ERR_ECC (1 << 2) +#define S3C_CSIS_INTSRC_ERR_CRC (1 << 1) +#define S3C_CSIS_INTSRC_ERR_ID (1 << 0) +#define S3C_CSIS_INTSRC_ERR (S3C_CSIS_INTSRC_ERR_SOT_HS | \ + S3C_CSIS_INTSRC_ERR_LOST_FS | \ + S3C_CSIS_INTSRC_ERR_LOST_FE | \ + S3C_CSIS_INTSRC_ERR_OVER | \ + S3C_CSIS_INTSRC_ERR_ECC | \ + S3C_CSIS_INTSRC_ERR_CRC | \ + S3C_CSIS_INTSRC_ERR_ID) + +#define S3C_CSIS_INTSRC_NON_IMAGE_DATA (S3C_CSIS_INTSRC_EVEN_BEFORE | \ + S3C_CSIS_INTSRC_EVEN_AFTER | \ + S3C_CSIS_INTSRC_ODD_BEFORE | \ + S3C_CSIS_INTSRC_ODD_AFTER) + +/* Resolution Register */ +#define S3C_CSIS_RESOL_HOR_SHIFT (16) +#define S3C_CSIS_RESOL_VER_SHIFT (0) + +#endif /* __ASM_PLAT_REGS_CSIS_H */ diff --git a/arch/arm/plat-s5p/include/plat/regs-dsim.h b/arch/arm/plat-s5p/include/plat/regs-dsim.h new file mode 100644 index 0000000..f4d1eed --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/regs-dsim.h @@ -0,0 +1,237 @@ +/* linux/arch/arm/plat-s5p/include/plat/regs-dsim.h + * + * Register definition file for Samsung MIPI-DSIM driver + * + * InKi Dae <inki.dae@samsung.com>, Copyright (c) 2009 Samsung Electronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef _REGS_DSIM_H +#define _REGS_DSIM_H + +#define S5P_DSIM_STATUS (0x0) /* Status register */ +#define S5P_DSIM_SWRST (0x4) /* Software reset register */ +#define S5P_DSIM_CLKCTRL (0x8) /* Clock control register */ +#define S5P_DSIM_TIMEOUT (0xc) /* Time out register */ +#define S5P_DSIM_CONFIG (0x10) /* Configuration register */ +#define S5P_DSIM_ESCMODE (0x14) /* Escape mode register */ +#define S5P_DSIM_MDRESOL (0x18) /* Main display image resolution register */ +#define S5P_DSIM_MVPORCH (0x1c) /* Main display Vporch register */ +#define S5P_DSIM_MHPORCH (0x20) /* Main display Hporch register */ +#define S5P_DSIM_MSYNC (0x24) /* Main display sync area register */ +#define S5P_DSIM_SDRESOL (0x28) /* Sub display image resolution register */ +#define S5P_DSIM_INTSRC (0x2c) /* Interrupt source register */ +#define S5P_DSIM_INTMSK (0x30) /* Interrupt mask register */ +#define S5P_DSIM_PKTHDR (0x34) /* Packet Header FIFO register */ +#define S5P_DSIM_PAYLOAD (0x38) /* Payload FIFO register */ +#define S5P_DSIM_RXFIFO (0x3c) /* Read FIFO register */ +#define S5P_DSIM_FIFOTHLD (0x40) /* FIFO threshold level register */ +#define S5P_DSIM_FIFOCTRL (0x44) /* FIFO status and control register */ +#define S5P_DSIM_MEMACCHR (0x48) /* FIFO memory AC characteristic register */ +#define S5P_DSIM_PLLCTRL (0x4c) /* PLL control register */ +#define S5P_DSIM_PLLTMR (0x50) /* PLL timer register */ +#define S5P_DSIM_PHYACCHR (0x54) /* D-PHY AC characteristic register */ +#define S5P_DSIM_PHYACCHR1 (0x58) /* D-PHY AC characteristic register 1 */ + +/* DSIM_SWRST */ +#define DSIM_FUNCRST (1 << 16) +#define DSIM_SWRST (1 << 0) + +/* S5P_DSIM_TIMEOUT */ +#define DSIM_LPDR_TOUT_SHIFT (0) +#define DSIM_BTA_TOUT_SHIFT (16) +#define DSIM_LPDR_TOUT(x) (((x) & 0xffff) << DSIM_LPDR_TOUT_SHIFT) +#define DSIM_BTA_TOUT(x) (((x) & 0xff) << DSIM_BTA_TOUT_SHIFT) + +/* S5P_DSIM_CLKCTRL */ +#define DSIM_ESC_PRESCALER_SHIFT (0) +#define DSIM_LANE_ESC_CLKEN_SHIFT (19) +#define DSIM_BYTE_CLKEN_SHIFT (24) +#define DSIM_BYTE_CLK_SRC_SHIFT (25) +#define DSIM_PLL_BYPASS_SHIFT (27) +#define DSIM_ESC_CLKEN_SHIFT (28) +#define DSIM_TX_REQUEST_HSCLK_SHIFT (31) +#define DSIM_ESC_PRESCALER(x) (((x) & 0xffff) << DSIM_ESC_PRESCALER_SHIFT) +#define DSIM_LANE_ESC_CLKEN(x) (((x) & 0x1f) << DSIM_LANE_ESC_CLKEN_SHIFT) +#define DSIM_BYTE_CLK_ENABLE (1 << DSIM_BYTE_CLKEN_SHIFT) +#define DSIM_BYTE_CLK_DISABLE (0 << DSIM_BYTE_CLKEN_SHIFT) +#define DSIM_BYTE_CLKSRC(x) (((x) & 0x3) << DSIM_BYTE_CLK_SRC_SHIFT) +#define DSIM_PLL_BYPASS_PLL (0 << DSIM_PLL_BYPASS_SHIFT) +#define DSIM_PLL_BYPASS_EXTERNAL (1 << DSIM_PLL_BYPASS_SHIFT) +#define DSIM_ESC_CLKEN_ENABLE (1 << DSIM_ESC_CLKEN_SHIFT) +#define DSIM_ESC_CLKEN_DISABLE (0 << DSIM_ESC_CLKEN_SHIFT) + +/* S5P_DSIM_CONFIG */ +#define DSIM_LANE_EN_SHIFT (0) +#define DSIM_NUM_OF_DATALANE_SHIFT (5) +#define DSIM_SUB_PIX_FORMAT_SHIFT (8) +#define DSIM_MAIN_PIX_FORMAT_SHIFT (12) +#define DSIM_SUB_VC_SHIFT (16) +#define DSIM_MAIN_VC_SHIFT (18) +#define DSIM_HSA_MODE_SHIFT (20) +#define DSIM_HBP_MODE_SHIFT (21) +#define DSIM_HFP_MODE_SHIFT (22) +#define DSIM_HSE_MODE_SHIFT (23) +#define DSIM_AUTO_MODE_SHIFT (24) +#define DSIM_VIDEO_MODE_SHIFT (25) +#define DSIM_BURST_MODE_SHIFT (26) +#define DSIM_SYNC_INFORM_SHIFT (27) +#define DSIM_EOT_R03_SHIFT (28) +#define DSIM_LANE_ENx(x) ((1) << x) +#define DSIM_NUM_OF_DATA_LANE(x) ((x) << 5) /* in case of Gemunus, it should be 0x1. */ +#define DSIM_SUB_PIX_FORMAT_3BPP (0 << 8) /* command mode only */ +#define DSIM_SUB_PIX_FORMAT_8BPP (1 << 8) /* command mode only */ +#define DSIM_SUB_PIX_FORMAT_12BPP (2 << 8) /* command mode only */ +#define DSIM_SUB_PIX_FORMAT_16BPP (3 << 8) /* command mode only */ +#define DSIM_SUB_PIX_FORMAT_16BPP_RGB (4 << 8) /* video mode only */ +#define DSIM_SUB_PIX_FORMAT_18BPP_PRGB (5 << 8) /* video mode only */ +#define DSIM_SUB_PIX_FORMAT_18BPP_LRGB (6 << 8) /* common */ +#define DSIM_SUB_PIX_FORMAT_24BPP_RGB (7 << 8) /* common */ +#define DSIM_MAIN_PIX_FORMAT_3BPP (0 << 12) /* command mode only */ +#define DSIM_MAIN_PIX_FORMAT_8BPP (1 << 12) /* command mode only */ +#define DSIM_MAIN_PIX_FORMAT_12BPP (2 << 12) /* command mode only */ +#define DSIM_MAIN_PIX_FORMAT_16BPP (3 << 12) /* command mode only */ +#define DSIM_MAIN_PIX_FORMAT_16BPP_RGB (4 << 12) /* video mode only */ +#define DSIM_MAIN_PIX_FORMAT_18BPP_PRGB (5 << 12) /* video mode only */ +#define DSIM_MAIN_PIX_FORMAT_18BPP_LRGB (6 << 12) /* common */ +#define DSIM_MAIN_PIX_FORMAT_24BPP_RGB (7 << 12) /* common */ +#define DSIM_SUB_VC(x) (((x) & 0x3) << 16) /* Virtual channel number for sub display */ +#define DSIM_MAIN_VC(x) (((x) & 0x3) << 18) /* Virtual channel number for main display */ +#define DSIM_HSA_MODE_ENABLE (1 << 20) +#define DSIM_HSA_MODE_DISABLE (0 << 20) +#define DSIM_HBP_MODE_ENABLE (1 << 21) +#define DSIM_HBP_MODE_DISABLE (0 << 21) +#define DSIM_HFP_MODE_ENABLE (1 << 22) +#define DSIM_HFP_MODE_DISABLE (0 << 22) +#define DSIM_HSE_MODE_ENABLE (1 << 23) +#define DSIM_HSE_MODE_DISABLE (0 << 23) +#define DSIM_AUTO_MODE (1 << 24) +#define DSIM_CONFIGURATION_MODE (0 << 24) +#define DSIM_VIDEO_MODE (1 << 25) +#define DSIM_COMMAND_MODE (0 << 25) +#define DSIM_BURST_MODE (1 << 26) +#define DSIM_NON_BURST_MODE (0 << 26) +#define DSIM_SYNC_INFORM_PULSE (1 << 27) +#define DSIM_SYNC_INFORM_EVENT (0 << 27) +#define DSIM_EOT_R03_ENABLE (0 << 28) /* enable EoT packet generation for V1.01r11 */ +#define DSIM_EOT_R03_DISABLE (1 << 28) /* disable EoT packet generation for V1.01r03 */ + +/* S5P_DSIM_ESCMODE */ +#define DSIM_STOP_STATE_CNT_SHIFT (21) +#define DSIM_STOP_STATE_CNT(x) (((x) & 0x3ff) << DSIM_STOP_STATE_CNT_SHIFT) +#define DSIM_FORCE_STOP_STATE_SHIFT (20) +#define DSIM_FORCE_BTA_SHIFT (16) +#define DSIM_CMD_LPDT_HS_MODE (0 << 7) +#define DSIM_CMD_LPDT_LP_MODE (1 << 7) +#define DSIM_TX_LPDT_HS_MODE (0 << 6) +#define DSIM_TX_LPDT_LP_MODE (1 << 6) +#define DSIM_TX_TRIGGER_RST_SHIFT (4) +#define DSIM_TX_UIPS_DAT_SHIFT (3) +#define DSIM_TX_UIPS_EXIT_SHIFT (2) +#define DSIM_TX_UIPS_CLK_SHIFT (1) +#define DSIM_TX_UIPS_CLK_EXIT_SHIFT (0) + +/* S5P_DSIM_MDRESOL */ +#define DSIM_MAIN_STAND_BY (1 << 31) +#define DSIM_MAIN_NOT_READY (0 << 31) +#define DSIM_MAIN_VRESOL(x) (((x) & 0x7ff) << 16) +#define DSIM_MAIN_HRESOL(x) (((x) & 0X7ff) << 0) + +/* S5P_DSIM_MVPORCH */ +#define DSIM_CMD_ALLOW_SHIFT (28) +#define DSIM_STABLE_VFP_SHIFT (16) +#define DSIM_MAIN_VBP_SHIFT (0) +#define DSIM_CMD_ALLOW_MASK (0xf << DSIM_CMD_ALLOW_SHIFT) +#define DSIM_STABLE_VFP_MASK (0x7ff << DSIM_STABLE_VFP_SHIFT) +#define DSIM_MAIN_VBP_MASK (0x7ff << DSIM_MAIN_VBP_SHIFT) +#define DSIM_CMD_ALLOW(x) (((x) & 0xf) << DSIM_CMD_ALLOW_SHIFT) +#define DSIM_STABLE_VFP(x) (((x) & 0x7ff) << DSIM_STABLE_VFP_SHIFT) +#define DSIM_MAIN_VBP(x) (((x) & 0x7ff) << DSIM_MAIN_VBP_SHIFT) + +/* S5P_DSIM_MHPORCH */ +#define DSIM_MAIN_HFP_SHIFT (16) +#define DSIM_MAIN_HBP_SHIFT (0) +#define DSIM_MAIN_HFP_MASK ((0xffff) << DSIM_MAIN_HFP_SHIFT) +#define DSIM_MAIN_HBP_MASK ((0xffff) << DSIM_MAIN_HBP_SHIFT) +#define DSIM_MAIN_HFP(x) (((x) & 0xffff) << DSIM_MAIN_HFP_SHIFT) +#define DSIM_MAIN_HBP(x) (((x) & 0xffff) << DSIM_MAIN_HBP_SHIFT) + +/* S5P_DSIM_MSYNC */ +#define DSIM_MAIN_VSA_SHIFT (22) +#define DSIM_MAIN_HSA_SHIFT (0) +#define DSIM_MAIN_VSA_MASK ((0x3ff) << DSIM_MAIN_VSA_SHIFT) +#define DSIM_MAIN_HSA_MASK ((0xffff) << DSIM_MAIN_HSA_SHIFT) +#define DSIM_MAIN_VSA(x) (((x) & 0x3ff) << DSIM_MAIN_VSA_SHIFT) +#define DSIM_MAIN_HSA(x) (((x) & 0xffff) << DSIM_MAIN_HSA_SHIFT) + +/* S5P_DSIM_SDRESOL */ +#define DSIM_SUB_STANDY_SHIFT (31) +#define DSIM_SUB_VRESOL_SHIFT (16) +#define DSIM_SUB_HRESOL_SHIFT (0) +#define DSIM_SUB_STANDY_MASK ((0x1) << DSIM_SUB_STANDY_SHIFT) +#define DSIM_SUB_VRESOL_MASK ((0x7ff) << DSIM_SUB_VRESOL_SHIFT) +#define DSIM_SUB_HRESOL_MASK ((0x7ff) << DSIM_SUB_HRESOL_SHIFT) +#define DSIM_SUB_STANDY (1 << DSIM_SUB_STANDY_SHIFT) +#define DSIM_SUB_NOT_READY (0 << DSIM_SUB_STANDY_SHIFT) +#define DSIM_SUB_VRESOL(x) (((x) & 0x7ff) << DSIM_SUB_VRESOL_SHIFT) +#define DSIM_SUB_HRESOL(x) (((x) & 0x7ff) << DSIM_SUB_HRESOL_SHIFT) + +/* S5P_DSIM_PKTHDR */ +#define DSIM_PACKET_HEADER_DI(x) (((x) & 0xff) << 0) +#define DSIM_PACKET_HEADER_DAT0(x) (((x) & 0xff) << 8) /* Word count lower byte for long packet */ +#define DSIM_PACKET_HEADER_DAT1(x) (((x) & 0xff) << 16) /* Word count upper byte for long packet */ + +/* S5P_DSIM_FIFOCTRL */ +#define DSIM_RX_FIFO (1 << 4) +#define DSIM_TX_SFR_FIFO (1 << 3) +#define DSIM_I80_FIFO (1 << 2) +#define DSIM_SUB_DISP_FIFO (1 << 1) +#define DSIM_MAIN_DISP_FIFO (1 << 0) + +/* S5P_DSIM_PHYACCHR */ +#define DSIM_AFC_CTL(x) (((x) & 0x7) << 5) +#define DSIM_AFC_ENABLE (1 << 14) +#define DSIM_AFC_DISABLE (0 << 14) + +/* S5P_DSIM_PLLCTRL */ +#define DSIM_PMS_SHIFT (1) +#define DSIM_PLL_EN_SHIFT (23) +#define DSIM_FREQ_BAND_SHIFT (24) +#define DSIM_PMS(x) (((x) & 0x7ffff) << DSIM_PMS_SHIFT) +#define DSIM_FREQ_BAND(x) (((x) & 0xf) << DSIM_FREQ_BAND_SHIFT) + +typedef enum { + PllStable = 1 << 31, + SwRstRelease = 1 << 30, + SFRFifoEmpty = 1 << 29, + BusTrunOVer = 1 << 25, + FrameDone = 1 << 24, + LpdrTout = 1 << 21, + TaTout = 1 << 20, + RxDatDone = 1 << 18, + RxTE = 1 << 17, + ErrRxEcc = 1 << 15, + ErrRxCRC = 1 << 14, + ErrEsc3 = 1 << 13, + ErrEsc2 = 1 << 12, + ErrEsc1 = 1 << 11, + ErrEsc0 = 1 << 10, + ErrSync3 = 1 << 9, + ErrSync2 = 1 << 8, + ErrSync1 = 1 << 7, + ErrSync0 = 1 << 6, + ErrControl3 = 1 << 5, + ErrControl2 = 1 << 4, + ErrControl1 = 1 << 3, + ErrControl0 = 1 << 2, + ErrContentLP0 = 1 << 1, + ErrContentLP1 = 1 << 0, + + AllDsimIntr = 0xffffffff, + ErrDsimIntr = 0xffff, +} DSIM_INTSRC; + +#endif /* _REGS_DSIM_H */ diff --git a/arch/arm/plat-s5p/include/plat/regs-dsim2.h b/arch/arm/plat-s5p/include/plat/regs-dsim2.h new file mode 100644 index 0000000..95a49e1 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/regs-dsim2.h @@ -0,0 +1,155 @@ +/* linux/arch/arm/plat-s5p/include/plat/regs-dsim.h + * + * Register definition file for Samsung MIPI-DSIM driver + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd + * + * InKi Dae <inki.dae@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef _REGS_DSIM_H +#define _REGS_DSIM_H + +#define S5P_DSIM_STATUS (0x0) /* Status register */ +#define S5P_DSIM_SWRST (0x4) /* Software reset register */ +#define S5P_DSIM_CLKCTRL (0x8) /* Clock control register */ +#define S5P_DSIM_TIMEOUT (0xc) /* Time out register */ +#define S5P_DSIM_CONFIG (0x10) /* Configuration register */ +#define S5P_DSIM_ESCMODE (0x14) /* Escape mode register */ + +/* Main display image resolution register */ +#define S5P_DSIM_MDRESOL (0x18) +#define S5P_DSIM_MVPORCH (0x1c) /* Main display Vporch register */ +#define S5P_DSIM_MHPORCH (0x20) /* Main display Hporch register */ +#define S5P_DSIM_MSYNC (0x24) /* Main display sync area register */ + +/* Sub display image resolution register */ +#define S5P_DSIM_SDRESOL (0x28) +#define S5P_DSIM_INTSRC (0x2c) /* Interrupt source register */ +#define S5P_DSIM_INTMSK (0x30) /* Interrupt mask register */ +#define S5P_DSIM_PKTHDR (0x34) /* Packet Header FIFO register */ +#define S5P_DSIM_PAYLOAD (0x38) /* Payload FIFO register */ +#define S5P_DSIM_RXFIFO (0x3c) /* Read FIFO register */ +#define S5P_DSIM_FIFOTHLD (0x40) /* FIFO threshold level register */ +#define S5P_DSIM_FIFOCTRL (0x44) /* FIFO status and control register */ + +/* FIFO memory AC characteristic register */ +#define S5P_DSIM_PLLCTRL (0x4c) /* PLL control register */ +#define S5P_DSIM_PLLTMR (0x50) /* PLL timer register */ +#define S5P_DSIM_PHYACCHR (0x54) /* D-PHY AC characteristic register */ +#define S5P_DSIM_PHYACCHR1 (0x58) /* D-PHY AC characteristic register1 */ + +/* DSIM_STATUS */ +#define DSIM_STOP_STATE_DAT(x) (((x) & 0xf) << 0) +#define DSIM_STOP_STATE_CLK (1 << 8) +#define DSIM_TX_READY_HS_CLK (1 << 10) + +/* DSIM_SWRST */ +#define DSIM_FUNCRST (1 << 16) +#define DSIM_SWRST (1 << 0) + +/* S5P_DSIM_TIMEOUT */ +#define DSIM_LPDR_TOUT_SHIFT (0) +#define DSIM_BTA_TOUT_SHIFT (16) + +/* S5P_DSIM_CLKCTRL */ +#define DSIM_LANE_ESC_CLKEN_SHIFT (19) +#define DSIM_BYTE_CLKEN_SHIFT (24) +#define DSIM_BYTE_CLK_SRC_SHIFT (25) +#define DSIM_PLL_BYPASS_SHIFT (27) +#define DSIM_ESC_CLKEN_SHIFT (28) +#define DSIM_TX_REQUEST_HSCLK_SHIFT (31) +#define DSIM_LANE_ESC_CLKEN(x) (((x) & 0x1f) << \ + DSIM_LANE_ESC_CLKEN_SHIFT) +#define DSIM_BYTE_CLK_ENABLE (1 << DSIM_BYTE_CLKEN_SHIFT) +#define DSIM_BYTE_CLK_DISABLE (0 << DSIM_BYTE_CLKEN_SHIFT) +#define DSIM_PLL_BYPASS_EXTERNAL (1 << DSIM_PLL_BYPASS_SHIFT) +#define DSIM_ESC_CLKEN_ENABLE (1 << DSIM_ESC_CLKEN_SHIFT) +#define DSIM_ESC_CLKEN_DISABLE (0 << DSIM_ESC_CLKEN_SHIFT) + +/* S5P_DSIM_CONFIG */ +#define DSIM_NUM_OF_DATALANE_SHIFT (5) +#define DSIM_HSA_MODE_SHIFT (20) +#define DSIM_HBP_MODE_SHIFT (21) +#define DSIM_HFP_MODE_SHIFT (22) +#define DSIM_HSE_MODE_SHIFT (23) +#define DSIM_AUTO_MODE_SHIFT (24) +#define DSIM_LANE_ENx(x) (((x) & 0x1f) << 0) + +#define DSIM_NUM_OF_DATA_LANE(x) ((x) << DSIM_NUM_OF_DATALANE_SHIFT) + +/* S5P_DSIM_ESCMODE */ +#define DSIM_TX_LPDT_SHIFT (6) +#define DSIM_CMD_LPDT_SHIFT (7) +#define DSIM_TX_LPDT_LP (1 << DSIM_TX_LPDT_SHIFT) +#define DSIM_CMD_LPDT_LP (1 << DSIM_CMD_LPDT_SHIFT) +#define DSIM_STOP_STATE_CNT_SHIFT (21) +#define DSIM_FORCE_STOP_STATE_SHIFT (20) + +/* S5P_DSIM_MDRESOL */ +#define DSIM_MAIN_STAND_BY (1 << 31) +#define DSIM_MAIN_VRESOL(x) (((x) & 0x7ff) << 16) +#define DSIM_MAIN_HRESOL(x) (((x) & 0X7ff) << 0) + +/* S5P_DSIM_MVPORCH */ +#define DSIM_CMD_ALLOW_SHIFT (28) +#define DSIM_STABLE_VFP_SHIFT (16) +#define DSIM_MAIN_VBP_SHIFT (0) +#define DSIM_CMD_ALLOW_MASK (0xf << DSIM_CMD_ALLOW_SHIFT) +#define DSIM_STABLE_VFP_MASK (0x7ff << DSIM_STABLE_VFP_SHIFT) +#define DSIM_MAIN_VBP_MASK (0x7ff << DSIM_MAIN_VBP_SHIFT) + +/* S5P_DSIM_MHPORCH */ +#define DSIM_MAIN_HFP_SHIFT (16) +#define DSIM_MAIN_HBP_SHIFT (0) +#define DSIM_MAIN_HFP_MASK ((0xffff) << DSIM_MAIN_HFP_SHIFT) +#define DSIM_MAIN_HBP_MASK ((0xffff) << DSIM_MAIN_HBP_SHIFT) + +/* S5P_DSIM_MSYNC */ +#define DSIM_MAIN_VSA_SHIFT (22) +#define DSIM_MAIN_HSA_SHIFT (0) +#define DSIM_MAIN_VSA_MASK ((0x3ff) << DSIM_MAIN_VSA_SHIFT) +#define DSIM_MAIN_HSA_MASK ((0xffff) << DSIM_MAIN_HSA_SHIFT) + +/* S5P_DSIM_SDRESOL */ +#define DSIM_SUB_STANDY_SHIFT (31) +#define DSIM_SUB_VRESOL_SHIFT (16) +#define DSIM_SUB_HRESOL_SHIFT (0) +#define DSIM_SUB_STANDY_MASK ((0x1) << DSIM_SUB_STANDY_SHIFT) +#define DSIM_SUB_VRESOL_MASK ((0x7ff) << DSIM_SUB_VRESOL_SHIFT) +#define DSIM_SUB_HRESOL_MASK ((0x7ff) << DSIM_SUB_HRESOL_SHIFT) + +/* S5P_DSIM_INTSRC */ +#define INTSRC_PLL_STABLE (1 << 31) +#define INTSRC_SW_RST_RELEASE (1 << 30) +#define INTSRC_SFR_FIFO_EMPTY (1 << 29) +#define INTSRC_FRAME_DONE (1 << 24) +#define INTSRC_RX_DATA_DONE (1 << 18) + +/* S5P_DSIM_INTMSK */ +#define INTMSK_FIFO_EMPTY (1 << 29) +#define INTMSK_BTA (1 << 25) +#define INTMSK_FRAME_DONE (1 << 24) +#define INTMSK_RX_TIMEOUT (1 << 21) +#define INTMSK_BTA_TIMEOUT (1 << 20) +#define INTMSK_RX_DONE (1 << 18) +#define INTMSK_RX_TE (1 << 17) +#define INTMSK_RX_ACK (1 << 16) +#define INTMSK_RX_ECC_ERR (1 << 15) +#define INTMSK_RX_CRC_ERR (1 << 14) + +/* S5P_DSIM_FIFOCTRL */ +#define SFR_HEADER_EMPTY (1 << 22) + +/* S5P_DSIM_PHYACCHR */ +#define DSIM_AFC_CTL(x) (((x) & 0x7) << 5) + +/* S5P_DSIM_PLLCTRL */ +#define DSIM_PLL_EN_SHIFT (23) +#define DSIM_FREQ_BAND_SHIFT (24) + +#endif /* _REGS_DSIM_H */ diff --git a/arch/arm/plat-s5p/include/plat/regs-fb-s5p.h b/arch/arm/plat-s5p/include/plat/regs-fb-s5p.h new file mode 100644 index 0000000..b616f2c --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/regs-fb-s5p.h @@ -0,0 +1,415 @@ +/* linux/arch/arm/plat-s5p/include/plat/regs-fb-s5p.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Register definition file for Samsung Display Controller (FIMD) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_PLAT_REGS_FB_S5P_H +#define __ASM_PLAT_REGS_FB_S5P_H __FILE__ + +#define S3C_WINCON(x) (0x0020 + (x * 0x04)) +#define S3C_VIDOSD_A(x) (0x0040 + (x * 0x10)) +#define S3C_VIDOSD_B(x) (0x0044 + (x * 0x10)) +#define S3C_VIDOSD_C(x) (0x0048 + (x * 0x10)) +#define S3C_VIDOSD_D(x) (0x004C + (x * 0x10)) +#define S3C_VIDADDR_START0(x) (0x00A0 + (x * 0x08)) +#define S3C_VIDADDR_START1(x) (0x00A4 + (x * 0x08)) +#define S3C_VIDADDR_END0(x) (0x00D0 + (x * 0x08)) +#define S3C_VIDADDR_END1(x) (0x00D4 + (x * 0x08)) +#define S3C_VIDADDR_SIZE(x) (0x0100 + (x * 0x04)) +#define S3C_KEYCON(x) (0x0140 + ((x - 1) * 0x08)) +#define S3C_KEYVAL(x) (0x0144 + ((x - 1) * 0x08)) +#define S3C_WINMAP(x) (0x0180 + (x * 0x04)) + +/* + * Register Map +*/ +#define S3C_VIDCON0 (0x0000) /* Video control 0 */ +#define S3C_VIDCON1 (0x0004) /* Video control 1 */ +#define S3C_VIDCON2 (0x0008) /* Video control 2 */ +#define S3C_PRTCON (0x000C) /* Protect control */ + +#define S3C_VIDTCON0 (0x0010) /* Video time control 0 */ +#define S3C_VIDTCON1 (0x0014) /* Video time control 1 */ +#define S3C_VIDTCON2 (0x0018) /* Video time control 2 */ + +#define S3C_WINCON0 (0x0020) /* Window control 0 */ +#define S3C_WINCON1 (0x0024) /* Window control 1 */ +#define S3C_WINCON2 (0x0028) /* Window control 2 */ +#define S3C_WINCON3 (0x002C) /* Window control 3 */ +#define S3C_WINCON4 (0x0030) /* Window control 4 */ + +#define S3C_WINSHMAP (0x0034) /* Window Shadow control */ + +#define S3C_VIDOSD0A (0x0040) /* Video Window 0 position control */ +#define S3C_VIDOSD0B (0x0044) /* Video Window 0 position control1 */ +#define S3C_VIDOSD0C (0x0048) /* Video Window 0 position control */ + +#define S3C_VIDOSD1A (0x0050) /* Video Window 1 position control */ +#define S3C_VIDOSD1B (0x0054) /* Video Window 1 position control */ +#define S3C_VIDOSD1C (0x0058) /* Video Window 1 position control */ +#define S3C_VIDOSD1D (0x005C) /* Video Window 1 position control */ + +#define S3C_VIDOSD2A (0x0060) /* Video Window 2 position control */ +#define S3C_VIDOSD2B (0x0064) /* Video Window 2 position control */ +#define S3C_VIDOSD2C (0x0068) /* Video Window 2 position control */ +#define S3C_VIDOSD2D (0x006C) /* Video Window 2 position control */ + +#define S3C_VIDOSD3A (0x0070) /* Video Window 3 position control */ +#define S3C_VIDOSD3B (0x0074) /* Video Window 3 position control */ +#define S3C_VIDOSD3C (0x0078) /* Video Window 3 position control */ + +#define S3C_VIDOSD4A (0x0080) /* Video Window 4 position control */ +#define S3C_VIDOSD4B (0x0084) /* Video Window 4 position control */ +#define S3C_VIDOSD4C (0x0088) /* Video Window 4 position control */ + +#define S3C_VIDW00ADD0B0 (0x00A0) /* Window 0 buffer start address, buffer 0 */ +#define S3C_VIDW00ADD0B1 (0x00A4) /* Window 0 buffer start address, buffer 1 */ +#define S3C_VIDW01ADD0B0 (0x00A8) /* Window 1 buffer start address, buffer 0 */ +#define S3C_VIDW01ADD0B1 (0x00AC) /* Window 1 buffer start address, buffer 1 */ +#define S3C_VIDW02ADD0 (0x00B0) /* Window 2 buffer start address, buffer 0 */ +#define S3C_VIDW03ADD0 (0x00B8) /* Window 3 buffer start address, buffer 0 */ +#define S3C_VIDW04ADD0 (0x00C0) /* Window 4 buffer start address, buffer 0 */ +#define S3C_VIDW00ADD1B0 (0x00D0) /* Window 0 buffer end address, buffer 0 */ +#define S3C_VIDW00ADD1B1 (0x00D4) /* Window 0 buffer end address, buffer 1 */ +#define S3C_VIDW01ADD1B0 (0x00D8) /* Window 1 buffer end address, buffer 0 */ +#define S3C_VIDW01ADD1B1 (0x00DC) /* Window 1 buffer end address, buffer 1 */ +#define S3C_VIDW02ADD1 (0x00E0) /* Window 2 buffer end address */ +#define S3C_VIDW03ADD1 (0x00E8) /* Window 3 buffer end address */ +#define S3C_VIDW04ADD1 (0x00F0) /* Window 4 buffer end address */ +#define S3C_VIDW00ADD2 (0x0100) /* Window 0 buffer size */ +#define S3C_VIDW01ADD2 (0x0104) /* Window 1 buffer size */ +#define S3C_VIDW02ADD2 (0x0108) /* Window 2 buffer size */ +#define S3C_VIDW03ADD2 (0x010C) /* Window 3 buffer size */ +#define S3C_VIDW04ADD2 (0x0110) /* Window 4 buffer size */ + +#define S3C_VP1TCON0 (0x0118) /* VP1 interface timing control 0 */ +#define S3C_VP1TCON1 (0x011C) /* VP1 interface timing control 1 */ + +#define S3C_VIDINTCON0 (0x0130) /* Indicate the Video interrupt control */ +#define S3C_VIDINTCON1 (0x0134) /* Video Interrupt Pending */ + +#define S3C_W1KEYCON0 (0x0140) /* Color key control */ +#define S3C_W1KEYCON1 (0x0144) /* Color key value (transparent value) */ +#define S3C_W2KEYCON0 (0x0148) /* Color key control */ +#define S3C_W2KEYCON1 (0x014C) /* Color key value (transparent value) */ +#define S3C_W3KEYCON0 (0x0150) /* Color key control */ +#define S3C_W3KEYCON1 (0x0154) /* Color key value (transparent value) */ +#define S3C_W4KEYCON0 (0x0158) /* Color key control */ +#define S3C_W4KEYCON1 (0x015C) /* Color key value (transparent value) */ + +#define S3C_W1KEYALPHA (0x0160) /* Color key alpha value */ +#define S3C_W2KEYALPHA (0x0164) /* Color key alpha value */ +#define S3C_W3KEYALPHA (0x0168) /* Color key alpha value */ +#define S3C_W4KEYALPHA (0x016C) /* Color key alpha value */ + +#define S3C_DITHMODE (0x0170) /* Dithering mode */ + +#define S3C_WIN0MAP (0x0180) /* Window color control */ +#define S3C_WIN1MAP (0x0184) /* Window color control */ +#define S3C_WIN2MAP (0x0188) /* Window color control */ +#define S3C_WIN3MAP (0x018C) /* Window color control */ +#define S3C_WIN4MAP (0x0190) /* Window color control */ + +#define S3C_WPALCON_H (0x019C) /* Window Palette control */ +#define S3C_WPALCON_L (0x01A0) /* Window Palette control */ +#define S3C_TRIGCON (0x01A4) /* I80 / RGB Trigger Control Regiter */ +#define S3C_I80IFCONA0 (0x01B0) /* I80 Interface control 0 for Main LDI */ +#define S3C_I80IFCONA1 (0x01B4) /* I80 Interface control 0 for Sub LDI */ +#define S3C_I80IFCONB0 (0x01B8) /* I80 Interface control 1 for Main LDI */ +#define S3C_I80IFCONB1 (0x01BC) /* I80 Interface control 1 for Sub LDI */ +#define S3C_LDI_CMDCON0 (0x01D0) /* I80 Interface LDI Command Control 0 */ +#define S3C_LDI_CMDCON1 (0x01D4) /* I80 Interface LDI Command Control 1 */ +#define S3C_SIFCCON0 (0x01E0) /* LCD i80 System Interface Command Control 0 */ +#define S3C_SIFCCON1 (0x01E4) /* LCD i80 System Interface Command Control 1 */ +#define S3C_SIFCCON2 (0x01E8) /* LCD i80 System Interface Command Control 2 */ + +#define S3C_VIDW0ALPHA0 (0x0200) /* Window 0 alpha value 0 */ +#define S3C_VIDW0ALPHA1 (0x0204) /* Window 0 alpha value 1 */ +#define S3C_VIDW1ALPHA0 (0x0208) /* Window 1 alpha value 0 */ +#define S3C_VIDW1ALPHA1 (0x020C) /* Window 1 alpha value 1 */ +#define S3C_VIDW2ALPHA0 (0x0210) /* Window 2 alpha value 0 */ +#define S3C_VIDW2ALPHA1 (0x0214) /* Window 2 alpha value 1 */ +#define S3C_VIDW3ALPHA0 (0x0218) /* Window 3 alpha value 0 */ +#define S3C_VIDW3ALPHA1 (0x021C) /* Window 3 alpha value 1 */ +#define S3C_VIDW4ALPHA0 (0x0220) /* Window 4 alpha value 0 */ +#define S3C_VIDW4ALPHA1 (0x0224) /* Window 4 alpha value 1 */ + +#define S3C_BLENDEQ1 (0x0244) /* Window 1 blending equation control */ +#define S3C_BLENDEQ2 (0x0248) /* Window 2 blending equation control */ +#define S3C_BLENDEQ3 (0x024C) /* Window 3 blending equation control */ +#define S3C_BLENDEQ4 (0x0250) /* Window 4 blending equation control */ +#define S3C_BLENDCON (0x0260) /* Blending control */ +#define S3C_SHD_WIN_BASE (0x4000) /* Shadow Window control reg Base */ +/* + * Bit Definitions +*/ + +/* VIDCON0 */ +#define S3C_VIDCON0_DSI_DISABLE (0 << 30) +#define S3C_VIDCON0_DSI_ENABLE (1 << 30) +#define S3C_VIDCON0_SCAN_PROGRESSIVE (0 << 29) +#define S3C_VIDCON0_SCAN_INTERLACE (1 << 29) +#define S3C_VIDCON0_SCAN_MASK (1 << 29) +#define S3C_VIDCON0_VIDOUT_RGB (0 << 26) +#define S3C_VIDCON0_VIDOUT_ITU (1 << 26) +#define S3C_VIDCON0_VIDOUT_I80LDI0 (2 << 26) +#define S3C_VIDCON0_VIDOUT_I80LDI1 (3 << 26) +#define S3C_VIDCON0_VIDOUT_WB_RGB (4 << 26) +#define S3C_VIDCON0_VIDOUT_WB_I80LDI0 (6 << 26) +#define S3C_VIDCON0_VIDOUT_WB_I80LDI1 (7 << 26) +#define S3C_VIDCON0_VIDOUT_MASK (7 << 26) +#define S3C_VIDCON0_PNRMODE_RGB_P (0 << 17) +#define S3C_VIDCON0_PNRMODE_BGR_P (1 << 17) +#define S3C_VIDCON0_PNRMODE_RGB_S (2 << 17) +#define S3C_VIDCON0_PNRMODE_BGR_S (3 << 17) +#define S3C_VIDCON0_PNRMODE_MASK (3 << 17) +#define S3C_VIDCON0_PNRMODE_SHIFT (17) +#define S3C_VIDCON0_CLKVALUP_ALWAYS (0 << 16) +#define S3C_VIDCON0_CLKVALUP_START_FRAME (1 << 16) +#define S3C_VIDCON0_CLKVALUP_MASK (1 << 16) +#define S3C_VIDCON0_CLKVAL_F(x) (((x) & 0xff) << 6) +#define S3C_VIDCON0_VCLKEN_NORMAL (0 << 5) +#define S3C_VIDCON0_VCLKEN_FREERUN (1 << 5) +#define S3C_VIDCON0_VCLKEN_MASK (1 << 5) +#define S3C_VIDCON0_CLKDIR_DIRECTED (0 << 4) +#define S3C_VIDCON0_CLKDIR_DIVIDED (1 << 4) +#define S3C_VIDCON0_CLKDIR_MASK (1 << 4) +#define S3C_VIDCON0_CLKSEL_HCLK (0 << 2) +#define S3C_VIDCON0_CLKSEL_SCLK (1 << 2) +#define S3C_VIDCON0_CLKSEL_MASK (1 << 2) +#define S3C_VIDCON0_ENVID_ENABLE (1 << 1) +#define S3C_VIDCON0_ENVID_DISABLE (0 << 1) +#define S3C_VIDCON0_ENVID_F_ENABLE (1 << 0) +#define S3C_VIDCON0_ENVID_F_DISABLE (0 << 0) + +/* VIDCON1 */ +#define S3C_VIDCON1_FIXVCLK_VCLK_HOLD (0 << 9) +#define S3C_VIDCON1_FIXVCLK_VCLK_RUN (1 << 9) +#define S3C_VIDCON1_FIXVCLK_VCLK_RUN_VDEN_DIS (3 << 9) +#define S3C_VIDCON1_FIXVCLK_MASK (3 << 9) +#define S3C_VIDCON1_IVCLK_FALLING_EDGE (0 << 7) +#define S3C_VIDCON1_IVCLK_RISING_EDGE (1 << 7) +#define S3C_VIDCON1_IHSYNC_NORMAL (0 << 6) +#define S3C_VIDCON1_IHSYNC_INVERT (1 << 6) +#define S3C_VIDCON1_IVSYNC_NORMAL (0 << 5) +#define S3C_VIDCON1_IVSYNC_INVERT (1 << 5) +#define S3C_VIDCON1_IVDEN_NORMAL (0 << 4) +#define S3C_VIDCON1_IVDEN_INVERT (1 << 4) +#define S3C_VIDCON1_VSTATUS_VSYNC (0 << 13) +#define S3C_VIDCON1_VSTATUS_BACK (1 << 13) +#define S3C_VIDCON1_VSTATUS_ACTIVE (2 << 13) +#define S3C_VIDCON1_VSTATUS_FRONT (3 << 13) +#define S3C_VIDCON1_VSTATUS_MASK (3 << 13) + + +/* VIDCON2 */ +#define S3C_VIDCON2_EN601_DISABLE (0 << 23) +#define S3C_VIDCON2_EN601_ENABLE (1 << 23) +#define S3C_VIDCON2_EN601_MASK (1 << 23) +#define S3C_VIDCON2_WB_DISABLE (0 << 15) +#define S3C_VIDCON2_WB_ENABLE (1 << 15) +#define S3C_VIDCON2_WB_MASK (1 << 15) +#define S3C_VIDCON2_TVFORMATSEL_HW (0 << 14) +#define S3C_VIDCON2_TVFORMATSEL_SW (1 << 14) +#define S3C_VIDCON2_TVFORMATSEL_MASK (1 << 14) +#define S3C_VIDCON2_TVFORMATSEL_YUV422 (1 << 12) +#define S3C_VIDCON2_TVFORMATSEL_YUV444 (2 << 12) +#define S3C_VIDCON2_TVFORMATSEL_YUV_MASK (3 << 12) +#define S3C_VIDCON2_ORGYUV_YCBCR (0 << 8) +#define S3C_VIDCON2_ORGYUV_CBCRY (1 << 8) +#define S3C_VIDCON2_ORGYUV_MASK (1 << 8) +#define S3C_VIDCON2_YUVORD_CBCR (0 << 7) +#define S3C_VIDCON2_YUVORD_CRCB (1 << 7) +#define S3C_VIDCON2_YUVORD_MASK (1 << 7) + +/* PRTCON */ +#define S3C_PRTCON_UPDATABLE (0 << 11) +#define S3C_PRTCON_PROTECT (1 << 11) + +/* VIDTCON0 */ +#define S3C_VIDTCON0_VBPDE(x) (((x) & 0xff) << 24) +#define S3C_VIDTCON0_VBPD(x) (((x) & 0xff) << 16) +#define S3C_VIDTCON0_VFPD(x) (((x) & 0xff) << 8) +#define S3C_VIDTCON0_VSPW(x) (((x) & 0xff) << 0) + +/* VIDTCON1 */ +#define S3C_VIDTCON1_VFPDE(x) (((x) & 0xff) << 24) +#define S3C_VIDTCON1_HBPD(x) (((x) & 0xff) << 16) +#define S3C_VIDTCON1_HFPD(x) (((x) & 0xff) << 8) +#define S3C_VIDTCON1_HSPW(x) (((x) & 0xff) << 0) + +/* VIDTCON2 */ +#define S3C_VIDTCON2_LINEVAL(x) (((x) & 0x7ff) << 11) +#define S3C_VIDTCON2_HOZVAL(x) (((x) & 0x7ff) << 0) + +/* Window 0~4 Control - WINCONx */ +#define S3C_WINCON_DATAPATH_DMA (0 << 22) +#define S3C_WINCON_DATAPATH_LOCAL (1 << 22) +#define S3C_WINCON_DATAPATH_MASK (1 << 22) +#define S3C_WINCON_BUFSEL_0 (0 << 20) +#define S3C_WINCON_BUFSEL_1 (1 << 20) +#define S3C_WINCON_BUFSEL_MASK (1 << 20) +#define S3C_WINCON_BUFSEL_SHIFT (20) +#define S3C_WINCON_BUFAUTO_DISABLE (0 << 19) +#define S3C_WINCON_BUFAUTO_ENABLE (1 << 19) +#define S3C_WINCON_BUFAUTO_MASK (1 << 19) +#define S3C_WINCON_BITSWP_DISABLE (0 << 18) +#define S3C_WINCON_BITSWP_ENABLE (1 << 18) +#define S3C_WINCON_BITSWP_SHIFT (18) +#define S3C_WINCON_BYTESWP_DISABLE (0 << 17) +#define S3C_WINCON_BYTESWP_ENABLE (1 << 17) +#define S3C_WINCON_BYTESWP_SHIFT (17) +#define S3C_WINCON_HAWSWP_DISABLE (0 << 16) +#define S3C_WINCON_HAWSWP_ENABLE (1 << 16) +#define S3C_WINCON_HAWSWP_SHIFT (16) +#define S3C_WINCON_WSWP_DISABLE (0 << 15) +#define S3C_WINCON_WSWP_ENABLE (1 << 15) +#define S3C_WINCON_WSWP_SHIFT (15) +#define S3C_WINCON_INRGB_RGB (0 << 13) +#define S3C_WINCON_INRGB_YUV (1 << 13) +#define S3C_WINCON_INRGB_MASK (1 << 13) +#define S3C_WINCON_BURSTLEN_16WORD (0 << 9) +#define S3C_WINCON_BURSTLEN_8WORD (1 << 9) +#define S3C_WINCON_BURSTLEN_4WORD (2 << 9) +#define S3C_WINCON_BURSTLEN_MASK (3 << 9) +#define S3C_WINCON_ALPHA_MULTI_DISABLE (0 << 7) +#define S3C_WINCON_ALPHA_MULTI_ENABLE (1 << 7) +#define S3C_WINCON_BLD_PLANE (0 << 6) +#define S3C_WINCON_BLD_PIXEL (1 << 6) +#define S3C_WINCON_BLD_MASK (1 << 6) +#define S3C_WINCON_BPPMODE_1BPP (0 << 2) +#define S3C_WINCON_BPPMODE_2BPP (1 << 2) +#define S3C_WINCON_BPPMODE_4BPP (2 << 2) +#define S3C_WINCON_BPPMODE_8BPP_PAL (3 << 2) +#define S3C_WINCON_BPPMODE_8BPP (4 << 2) +#define S3C_WINCON_BPPMODE_16BPP_565 (5 << 2) +#define S3C_WINCON_BPPMODE_16BPP_A555 (6 << 2) +#define S3C_WINCON_BPPMODE_18BPP_666 (8 << 2) +#define S3C_WINCON_BPPMODE_18BPP_A665 (9 << 2) +#define S3C_WINCON_BPPMODE_24BPP_888 (0xb << 2) +#define S3C_WINCON_BPPMODE_24BPP_A887 (0xc << 2) +#define S3C_WINCON_BPPMODE_32BPP (0xd << 2) +#define S3C_WINCON_BPPMODE_16BPP_A444 (0xe << 2) +#define S3C_WINCON_BPPMODE_15BPP_555 (0xf << 2) +#define S3C_WINCON_BPPMODE_MASK (0xf << 2) +#define S3C_WINCON_BPPMODE_SHIFT (2) +#define S3C_WINCON_ALPHA0_SEL (0 << 1) +#define S3C_WINCON_ALPHA1_SEL (1 << 1) +#define S3C_WINCON_ALPHA_SEL_MASK (1 << 1) +#define S3C_WINCON_ENWIN_DISABLE (0 << 0) +#define S3C_WINCON_ENWIN_ENABLE (1 << 0) + +/* WINCON1 special */ +#define S3C_WINCON1_VP_DISABLE (0 << 24) +#define S3C_WINCON1_VP_ENABLE (1 << 24) +#define S3C_WINCON1_LOCALSEL_FIMC1 (0 << 23) +#define S3C_WINCON1_LOCALSEL_VP (1 << 23) +#define S3C_WINCON1_LOCALSEL_MASK (1 << 23) + +/* WINSHMAP */ +#define S3C_WINSHMAP_PROTECT(x) (((x) & 0x1f) << 10) +#define S3C_WINSHMAP_CH_ENABLE(x) (1 << (x)) +#define S3C_WINSHMAP_CH_DISABLE(x) (1 << (x)) +#define S3C_WINSHMAP_LOCAL_ENABLE(x) (0x20 << (x)) +#define S3C_WINSHMAP_LOCAL_DISABLE(x) (0x20 << (x)) + + +/* VIDOSDxA, VIDOSDxB */ +#define S3C_VIDOSD_LEFT_X(x) (((x) & 0x7ff) << 11) +#define S3C_VIDOSD_TOP_Y(x) (((x) & 0x7ff) << 0) +#define S3C_VIDOSD_RIGHT_X(x) (((x) & 0x7ff) << 11) +#define S3C_VIDOSD_BOTTOM_Y(x) (((x) & 0x7ff) << 0) + +/* VIDOSD0C, VIDOSDxD */ +#define S3C_VIDOSD_SIZE(x) (((x) & 0xffffff) << 0) + +/* VIDOSDxC (1~4) */ +#define S3C_VIDOSD_ALPHA0_R(x) (((x) & 0xf) << 20) +#define S3C_VIDOSD_ALPHA0_G(x) (((x) & 0xf) << 16) +#define S3C_VIDOSD_ALPHA0_B(x) (((x) & 0xf) << 12) +#define S3C_VIDOSD_ALPHA1_R(x) (((x) & 0xf) << 8) +#define S3C_VIDOSD_ALPHA1_G(x) (((x) & 0xf) << 4) +#define S3C_VIDOSD_ALPHA1_B(x) (((x) & 0xf) << 0) +#define S3C_VIDOSD_ALPHA0_SHIFT (12) +#define S3C_VIDOSD_ALPHA1_SHIFT (0) + +/* Start Address */ +#define S3C_VIDADDR_START_VBANK(x) (((x) & 0xff) << 24) +#define S3C_VIDADDR_START_VBASEU(x) (((x) & 0xffffff) << 0) + +/* End Address */ +#define S3C_VIDADDR_END_VBASEL(x) (((x) & 0xffffff) << 0) + +/* Buffer Size */ +#define S3C_VIDADDR_OFFSIZE(x) (((x) & 0x1fff) << 13) +#define S3C_VIDADDR_PAGEWIDTH(x) (((x) & 0x1fff) << 0) + +/* WIN Color Map */ +#define S3C_WINMAP_COLOR(x) ((x) & 0xffffff) + +/* VIDINTCON0 */ +#define S3C_VIDINTCON0_SYSMAINCON_DISABLE (0 << 19) +#define S3C_VIDINTCON0_SYSMAINCON_ENABLE (1 << 19) +#define S3C_VIDINTCON0_SYSSUBCON_DISABLE (0 << 18) +#define S3C_VIDINTCON0_SYSSUBCON_ENABLE (1 << 18) +#define S3C_VIDINTCON0_SYSIFDONE_DISABLE (0 << 17) +#define S3C_VIDINTCON0_SYSIFDONE_ENABLE (1 << 17) +#define S3C_VIDINTCON0_FRAMESEL0_BACK (0 << 15) +#define S3C_VIDINTCON0_FRAMESEL0_VSYNC (1 << 15) +#define S3C_VIDINTCON0_FRAMESEL0_ACTIVE (2 << 15) +#define S3C_VIDINTCON0_FRAMESEL0_FRONT (3 << 15) +#define S3C_VIDINTCON0_FRAMESEL0_MASK (3 << 15) +#define S3C_VIDINTCON0_FRAMESEL1_NONE (0 << 13) +#define S3C_VIDINTCON0_FRAMESEL1_BACK (1 << 13) +#define S3C_VIDINTCON0_FRAMESEL1_VSYNC (2 << 13) +#define S3C_VIDINTCON0_FRAMESEL1_FRONT (3 << 13) +#define S3C_VIDINTCON0_INTFRMEN_DISABLE (0 << 12) +#define S3C_VIDINTCON0_INTFRMEN_ENABLE (1 << 12) +#define S3C_VIDINTCON0_FIFOSEL_WIN4 (1 << 11) +#define S3C_VIDINTCON0_FIFOSEL_WIN3 (1 << 10) +#define S3C_VIDINTCON0_FIFOSEL_WIN2 (1 << 9) +#define S3C_VIDINTCON0_FIFOSEL_WIN1 (1 << 6) +#define S3C_VIDINTCON0_FIFOSEL_WIN0 (1 << 5) +#define S3C_VIDINTCON0_FIFOSEL_ALL (0x73 << 5) +#define S3C_VIDINTCON0_FIFOSEL_MASK (0x73 << 5) +#define S3C_VIDINTCON0_FIFOLEVEL_25 (0 << 2) +#define S3C_VIDINTCON0_FIFOLEVEL_50 (1 << 2) +#define S3C_VIDINTCON0_FIFOLEVEL_75 (2 << 2) +#define S3C_VIDINTCON0_FIFOLEVEL_EMPTY (3 << 2) +#define S3C_VIDINTCON0_FIFOLEVEL_FULL (4 << 2) +#define S3C_VIDINTCON0_FIFOLEVEL_MASK (7 << 2) +#define S3C_VIDINTCON0_INTFIFO_DISABLE (0 << 1) +#define S3C_VIDINTCON0_INTFIFO_ENABLE (1 << 1) +#define S3C_VIDINTCON0_INT_DISABLE (0 << 0) +#define S3C_VIDINTCON0_INT_ENABLE (1 << 0) +#define S3C_VIDINTCON0_INT_MASK (1 << 0) + +/* VIDINTCON1 */ +#define S3C_VIDINTCON1_INTVPPEND (1 << 5) +#define S3C_VIDINTCON1_INTI80PEND (1 << 2) +#define S3C_VIDINTCON1_INTFRMPEND (1 << 1) +#define S3C_VIDINTCON1_INTFIFOPEND (1 << 0) + +/* WINMAP */ +#define S3C_WINMAP_ENABLE (1 << 24) + +/* WxKEYCON0 (1~4) */ +#define S3C_KEYCON0_KEYBLEN_DISABLE (0 << 26) +#define S3C_KEYCON0_KEYBLEN_ENABLE (1 << 26) +#define S3C_KEYCON0_KEY_DISABLE (0 << 25) +#define S3C_KEYCON0_KEY_ENABLE (1 << 25) +#define S3C_KEYCON0_DIRCON_MATCH_FG (0 << 24) +#define S3C_KEYCON0_DIRCON_MATCH_BG (1 << 24) +#define S3C_KEYCON0_COMPKEY(x) (((x) & 0xffffff) << 0) + +/* WxKEYCON1 (1~4) */ +#define S3C_KEYCON1_COLVAL(x) (((x) & 0xffffff) << 0) + +#endif /* __ASM_PLAT_REGS_FB_S5P_H */ diff --git a/arch/arm/plat-s5p/include/plat/regs-fimc.h b/arch/arm/plat-s5p/include/plat/regs-fimc.h new file mode 100644 index 0000000..883d37d --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/regs-fimc.h @@ -0,0 +1,510 @@ +/* linux/arch/arm/plat-s5p/include/plat/regs-fimc.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Register definition file for Samsung Camera Interface (FIMC) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_PLAT_REGS_FIMC_H +#define __ASM_PLAT_REGS_FIMC_H __FILE__ + +/* + * Register part +*/ +#define S3C_CISRCFMT (0x00) /* Input source format */ +#define S3C_CIWDOFST (0x04) /* Window offset */ +#define S3C_CIGCTRL (0x08) /* Global control */ +#define S3C_CIWDOFST2 (0x14) /* Window offset 2 */ +#define S3C_CIOYSA1 (0x18) /* Y 1st frame start address for output DMA */ +#define S3C_CIOYSA2 (0x1c) /* Y 2nd frame start address for output DMA */ +#define S3C_CIOYSA3 (0x20) /* Y 3rd frame start address for output DMA */ +#define S3C_CIOYSA4 (0x24) /* Y 4th frame start address for output DMA */ +#define S3C_CIOCBSA1 (0x28) /* Cb 1st frame start address for output DMA */ +#define S3C_CIOCBSA2 (0x2c) /* Cb 2nd frame start address for output DMA */ +#define S3C_CIOCBSA3 (0x30) /* Cb 3rd frame start address for output DMA */ +#define S3C_CIOCBSA4 (0x34) /* Cb 4th frame start address for output DMA */ +#define S3C_CIOCRSA1 (0x38) /* Cr 1st frame start address for output DMA */ +#define S3C_CIOCRSA2 (0x3c) /* Cr 2nd frame start address for output DMA */ +#define S3C_CIOCRSA3 (0x40) /* Cr 3rd frame start address for output DMA */ +#define S3C_CIOCRSA4 (0x44) /* Cr 4th frame start address for output DMA */ +#define S3C_CITRGFMT (0x48) /* Target image format */ +#define S3C_CIOCTRL (0x4c) /* Output DMA control */ +#define S3C_CISCPRERATIO (0x50) /* Pre-scaler control 1 */ +#define S3C_CISCPREDST (0x54) /* Pre-scaler control 2 */ +#define S3C_CISCCTRL (0x58) /* Main scaler control */ +#define S3C_CITAREA (0x5c) /* Target area */ +#define S3C_CISTATUS (0x64) /* Status */ +#define S3C_CISTATUS2 (0x68) /* Status2 */ +#define S3C_CIIMGCPT (0xc0) /* Image capture enable command */ +#define S3C_CICPTSEQ (0xc4) /* Capture sequence */ +#define S3C_CIIMGEFF (0xd0) /* Image effects */ +#define S3C_CIIYSA0 (0xd4) /* Y frame start address for input DMA */ +#define S3C_CIICBSA0 (0xd8) /* Cb frame start address for input DMA */ +#define S3C_CIICRSA0 (0xdc) /* Cr frame start address for input DMA */ +#define S3C_CIILINESKIP_Y (0xec) /* Input DMA Y Line Skip */ +#define S3C_CIILINESKIP_CB (0xf0) /* Input DMA Cb Line Skip */ +#define S3C_CIILINESKIP_CR (0xf4) /* Input DMA Cr Line Skip */ +#define S3C_CIREAL_ISIZE (0xf8) /* Real input DMA image size */ +#define S3C_MSCTRL (0xfc) /* Input DMA control */ +#define S3C_CIOYOFF (0x168) /* Output DMA Y offset */ +#define S3C_CIOCBOFF (0x16c) /* Output DMA CB offset */ +#define S3C_CIOCROFF (0x170) /* Output DMA CR offset */ +#define S3C_CIIYOFF (0x174) /* Input DMA Y offset */ +#define S3C_CIICBOFF (0x178) /* Input DMA CB offset */ +#define S3C_CIICROFF (0x17c) /* Input DMA CR offset */ +#define S3C_ORGISIZE (0x180) /* Input DMA original image size */ +#define S3C_ORGOSIZE (0x184) /* Output DMA original image size */ +#define S3C_CIEXTEN (0x188) /* Real output DMA image size */ +#define S3C_CIDMAPARAM (0x18c) /* DMA parameter */ +#define S3C_CSIIMGFMT (0x194) /* MIPI CSI image format */ +#define S3C_MISC_FIMC (0x198) /* FIMC Clock Source Select */ + +/* Add for FIMC v5.1 */ +#define S3C_CIFCNTSEQ (0x1fc) /* Output Frame Buffer Sequence */ +#define S3C_CIOYSA5 (0x200) /* Y 5th frame start address for output DMA */ +#define S3C_CIOYSA6 (0x204) /* Y 6th frame start address for output DMA */ +#define S3C_CIOYSA7 (0x208) /* Y 7th frame start address for output DMA */ +#define S3C_CIOYSA8 (0x20c) /* Y 8th frame start address for output DMA */ +#define S3C_CIOYSA9 (0x210) /* Y 9th frame start address for output DMA */ +#define S3C_CIOYSA10 (0x214) /* Y 10th frame start address for output DMA */ +#define S3C_CIOYSA11 (0x218) /* Y 11th frame start address for output DMA */ +#define S3C_CIOYSA12 (0x21c) /* Y 12th frame start address for output DMA */ +#define S3C_CIOYSA13 (0x220) /* Y 13th frame start address for output DMA */ +#define S3C_CIOYSA14 (0x224) /* Y 14th frame start address for output DMA */ +#define S3C_CIOYSA15 (0x228) /* Y 15th frame start address for output DMA */ +#define S3C_CIOYSA16 (0x22c) /* Y 16th frame start address for output DMA */ +#define S3C_CIOYSA17 (0x230) /* Y 17th frame start address for output DMA */ +#define S3C_CIOYSA18 (0x234) /* Y 18th frame start address for output DMA */ +#define S3C_CIOYSA19 (0x238) /* Y 19th frame start address for output DMA */ +#define S3C_CIOYSA20 (0x23c) /* Y 20th frame start address for output DMA */ +#define S3C_CIOYSA21 (0x240) /* Y 21th frame start address for output DMA */ +#define S3C_CIOYSA22 (0x244) /* Y 22th frame start address for output DMA */ +#define S3C_CIOYSA23 (0x248) /* Y 23th frame start address for output DMA */ +#define S3C_CIOYSA24 (0x24c) /* Y 24th frame start address for output DMA */ +#define S3C_CIOYSA25 (0x250) /* Y 25th frame start address for output DMA */ +#define S3C_CIOYSA26 (0x254) /* Y 26th frame start address for output DMA */ +#define S3C_CIOYSA27 (0x258) /* Y 27th frame start address for output DMA */ +#define S3C_CIOYSA28 (0x25c) /* Y 28th frame start address for output DMA */ +#define S3C_CIOYSA29 (0x260) /* Y 29th frame start address for output DMA */ +#define S3C_CIOYSA30 (0x264) /* Y 30th frame start address for output DMA */ +#define S3C_CIOYSA31 (0x268) /* Y 31th frame start address for output DMA */ +#define S3C_CIOYSA32 (0x26c) /* Y 32th frame start address for output DMA */ + +#define S3C_CIOCBSA5 (0x270) /* CB 5th frame start address for output DMA */ +#define S3C_CIOCBSA6 (0x274) /* CB 6th frame start address for output DMA */ +#define S3C_CIOCBSA7 (0x278) /* CB 7th frame start address for output DMA */ +#define S3C_CIOCBSA8 (0x27c) /* CB 8th frame start address for output DMA */ +#define S3C_CIOCBSA9 (0x280) /* CB 9th frame start address for output DMA */ +#define S3C_CIOCBSA10 (0x284) /* CB 10th frame start address for output DMA */ +#define S3C_CIOCBSA11 (0x288) /* CB 11th frame start address for output DMA */ +#define S3C_CIOCBSA12 (0x28c) /* CB 12th frame start address for output DMA */ +#define S3C_CIOCBSA13 (0x290) /* CB 13th frame start address for output DMA */ +#define S3C_CIOCBSA14 (0x294) /* CB 14th frame start address for output DMA */ +#define S3C_CIOCBSA15 (0x298) /* CB 15th frame start address for output DMA */ +#define S3C_CIOCBSA16 (0x29c) /* CB 16th frame start address for output DMA */ +#define S3C_CIOCBSA17 (0x2a0) /* CB 17th frame start address for output DMA */ +#define S3C_CIOCBSA18 (0x2a4) /* CB 18th frame start address for output DMA */ +#define S3C_CIOCBSA19 (0x2a8) /* CB 19th frame start address for output DMA */ +#define S3C_CIOCBSA20 (0x2ac) /* CB 20th frame start address for output DMA */ +#define S3C_CIOCBSA21 (0x2b0) /* CB 21th frame start address for output DMA */ +#define S3C_CIOCBSA22 (0x2b4) /* CB 22th frame start address for output DMA */ +#define S3C_CIOCBSA23 (0x2b8) /* CB 23th frame start address for output DMA */ +#define S3C_CIOCBSA24 (0x2bc) /* CB 24th frame start address for output DMA */ +#define S3C_CIOCBSA25 (0x2c0) /* CB 25th frame start address for output DMA */ +#define S3C_CIOCBSA26 (0x2c4) /* CB 26th frame start address for output DMA */ +#define S3C_CIOCBSA27 (0x2c8) /* CB 27th frame start address for output DMA */ +#define S3C_CIOCBSA28 (0x2cc) /* CB 28th frame start address for output DMA */ +#define S3C_CIOCBSA29 (0x2d0) /* CB 29th frame start address for output DMA */ +#define S3C_CIOCBSA30 (0x2d4) /* CB 30th frame start address for output DMA */ +#define S3C_CIOCBSA31 (0x2d8) /* CB 31th frame start address for output DMA */ +#define S3C_CIOCBSA32 (0x2dc) /* CB 32th frame start address for output DMA */ + +#define S3C_CIOCRSA5 (0x2e0) /* CR 5th frame start address for output DMA */ +#define S3C_CIOCRSA6 (0x2e4) /* CR 6th frame start address for output DMA */ +#define S3C_CIOCRSA7 (0x2e8) /* CR 7th frame start address for output DMA */ +#define S3C_CIOCRSA8 (0x2ec) /* CR 8th frame start address for output DMA */ +#define S3C_CIOCRSA9 (0x2f0) /* CR 9th frame start address for output DMA */ +#define S3C_CIOCRSA10 (0x2f4) /* CR 10th frame start address for output DMA */ +#define S3C_CIOCRSA11 (0x2f8) /* CR 11th frame start address for output DMA */ +#define S3C_CIOCRSA12 (0x2fc) /* CR 12th frame start address for output DMA */ +#define S3C_CIOCRSA13 (0x300) /* CR 13th frame start address for output DMA */ +#define S3C_CIOCRSA14 (0x304) /* CR 14th frame start address for output DMA */ +#define S3C_CIOCRSA15 (0x308) /* CR 15th frame start address for output DMA */ +#define S3C_CIOCRSA16 (0x30c) /* CR 16th frame start address for output DMA */ +#define S3C_CIOCRSA17 (0x310) /* CR 17th frame start address for output DMA */ +#define S3C_CIOCRSA18 (0x314) /* CR 18th frame start address for output DMA */ +#define S3C_CIOCRSA19 (0x318) /* CR 19th frame start address for output DMA */ +#define S3C_CIOCRSA20 (0x31c) /* CR 20th frame start address for output DMA */ +#define S3C_CIOCRSA21 (0x320) /* CR 21th frame start address for output DMA */ +#define S3C_CIOCRSA22 (0x324) /* CR 22th frame start address for output DMA */ +#define S3C_CIOCRSA23 (0x328) /* CR 23th frame start address for output DMA */ +#define S3C_CIOCRSA24 (0x32c) /* CR 24th frame start address for output DMA */ +#define S3C_CIOCRSA25 (0x330) /* CR 25th frame start address for output DMA */ +#define S3C_CIOCRSA26 (0x334) /* CR 26th frame start address for output DMA */ +#define S3C_CIOCRSA27 (0x338) /* CR 27th frame start address for output DMA */ +#define S3C_CIOCRSA28 (0x33c) /* CR 28th frame start address for output DMA */ +#define S3C_CIOCRSA29 (0x340) /* CR 29th frame start address for output DMA */ +#define S3C_CIOCRSA30 (0x344) /* CR 30th frame start address for output DMA */ +#define S3C_CIOCRSA31 (0x348) /* CR 31th frame start address for output DMA */ +#define S3C_CIOCRSA32 (0x34c) /* CR 32th frame start address for output DMA */ +/* + * Macro part +*/ +/* frame start address 1 ~ 4, 5 ~ 32 */ +#define DEF_PP 4 /* Number of Default PingPong Memory */ +#define S3C_CIOYSA(__x) \ + (((__x) < DEF_PP) ? \ + (S3C_CIOYSA1 + (__x) * 4) : (S3C_CIOYSA5 + ((__x) - DEF_PP) * 4)) +#define S3C_CIOCBSA(__x) \ + (((__x) < DEF_PP) ? \ + (S3C_CIOCBSA1 + (__x) * 4) : (S3C_CIOCBSA5 + ((__x) - DEF_PP) * 4)) +#define S3C_CIOCRSA(__x) \ + (((__x) < DEF_PP) ? \ + (S3C_CIOCRSA1 + (__x) * 4) : (S3C_CIOCRSA5 + ((__x) - DEF_PP) * 4)) + +#define S3C_CISRCFMT_SOURCEHSIZE(x) ((x) << 16) +#define S3C_CISRCFMT_SOURCEVSIZE(x) ((x) << 0) + +#define S3C_CIWDOFST_WINHOROFST(x) ((x) << 16) +#define S3C_CIWDOFST_WINVEROFST(x) ((x) << 0) + +#define S3C_CIWDOFST2_WINHOROFST2(x) ((x) << 16) +#define S3C_CIWDOFST2_WINVEROFST2(x) ((x) << 0) + +#define S3C_CITRGFMT_TARGETHSIZE(x) (((x) & 0x1fff) << 16) +#define S3C_CITRGFMT_TARGETVSIZE(x) (((x) & 0x1fff) << 0) + +#define S3C_CISCPRERATIO_SHFACTOR(x) ((x) << 28) +#define S3C_CISCPRERATIO_PREHORRATIO(x) ((x) << 16) +#define S3C_CISCPRERATIO_PREVERRATIO(x) ((x) << 0) + +#define S3C_CISCPREDST_PREDSTWIDTH(x) ((x) << 16) +#define S3C_CISCPREDST_PREDSTHEIGHT(x) ((x) << 0) + +#define S3C_CISCCTRL_MAINHORRATIO(x) ((x) << 16) +#define S3C_CISCCTRL_MAINVERRATIO(x) ((x) << 0) + +#define S3C_CITAREA_TARGET_AREA(x) ((x) << 0) + +#define S3C_CISTATUS_GET_FRAME_COUNT(x) (((x) >> 26) & 0x3) +#define S3C_CISTATUS_GET_FRAME_END(x) (((x) >> 17) & 0x1) +#define S3C_CISTATUS_GET_LAST_CAPTURE_END(x) (((x) >> 16) & 0x1) +#define S3C_CISTATUS_GET_LCD_STATUS(x) (((x) >> 9) & 0x1) +#define S3C_CISTATUS_GET_ENVID_STATUS(x) (((x) >> 8) & 0x1) + +#define S3C_CISTATUS2_GET_FRAMECOUNT_BEFORE(x) (((x) >> 7) & 0x3f) +#define S3C_CISTATUS2_GET_FRAMECOUNT_PRESENT(x) ((x) & 0x3f) + +#define S3C_CIIMGEFF_FIN(x) ((x & 0x7) << 26) +#define S3C_CIIMGEFF_PAT_CB(x) ((x) << 13) +#define S3C_CIIMGEFF_PAT_CR(x) ((x) << 0) + +#define S3C_CIILINESKIP(x) (((x) & 0xf) << 24) + +#define S3C_CIREAL_ISIZE_HEIGHT(x) ((x) << 16) +#define S3C_CIREAL_ISIZE_WIDTH(x) ((x) << 0) + +#define S3C_MSCTRL_SUCCESSIVE_COUNT(x) ((x) << 24) +#define S3C_MSCTRL_GET_INDMA_STATUS(x) ((x) & 0x1) + +#define S3C_CIOYOFF_VERTICAL(x) ((x) << 16) +#define S3C_CIOYOFF_HORIZONTAL(x) ((x) << 0) + +#define S3C_CIOCBOFF_VERTICAL(x) ((x) << 16) +#define S3C_CIOCBOFF_HORIZONTAL(x) ((x) << 0) + +#define S3C_CIOCROFF_VERTICAL(x) ((x) << 16) +#define S3C_CIOCROFF_HORIZONTAL(x) ((x) << 0) + +#define S3C_CIIYOFF_VERTICAL(x) ((x) << 16) +#define S3C_CIIYOFF_HORIZONTAL(x) ((x) << 0) + +#define S3C_CIICBOFF_VERTICAL(x) ((x) << 16) +#define S3C_CIICBOFF_HORIZONTAL(x) ((x) << 0) + +#define S3C_CIICROFF_VERTICAL(x) ((x) << 16) +#define S3C_CIICROFF_HORIZONTAL(x) ((x) << 0) + +#define S3C_ORGISIZE_VERTICAL(x) ((x) << 16) +#define S3C_ORGISIZE_HORIZONTAL(x) ((x) << 0) + +#define S3C_ORGOSIZE_VERTICAL(x) ((x) << 16) +#define S3C_ORGOSIZE_HORIZONTAL(x) ((x) << 0) + +#define S3C_CIEXTEN_TARGETH_EXT(x) ((((x) & 0x2000) >> 13) << 26) +#define S3C_CIEXTEN_TARGETV_EXT(x) ((((x) & 0x2000) >> 13) << 24) +#define S3C_CIEXTEN_MAINHORRATIO_EXT(x) (((x) & 0x3F) << 10) +#define S3C_CIEXTEN_MAINVERRATIO_EXT(x) ((x) & 0x3F) + +/* + * Bit definition part +*/ +/* Source format register */ +#define S3C_CISRCFMT_ITU601_8BIT (1 << 31) +#define S3C_CISRCFMT_ITU656_8BIT (0 << 31) +#define S3C_CISRCFMT_ITU601_16BIT (1 << 29) +#define S3C_CISRCFMT_ORDER422_YCBYCR (0 << 14) +#define S3C_CISRCFMT_ORDER422_YCRYCB (1 << 14) +#define S3C_CISRCFMT_ORDER422_CBYCRY (2 << 14) +#define S3C_CISRCFMT_ORDER422_CRYCBY (3 << 14) +#define S3C_CISRCFMT_ORDER422_Y4CBCRCBCR (0 << 14) /* ITU601 16bit only */ +#define S3C_CISRCFMT_ORDER422_Y4CRCBCRCB (1 << 14) /* ITU601 16bit only */ + +/* Window offset register */ +#define S3C_CIWDOFST_WINOFSEN (1 << 31) +#define S3C_CIWDOFST_CLROVFIY (1 << 30) +#define S3C_CIWDOFST_CLROVRLB (1 << 29) +#define S3C_CIWDOFST_WINHOROFST_MASK (0x7ff << 16) +#define S3C_CIWDOFST_CLROVFICB (1 << 15) +#define S3C_CIWDOFST_CLROVFICR (1 << 14) +#define S3C_CIWDOFST_WINVEROFST_MASK (0xfff << 0) + +/* Global control register */ +#define S3C_CIGCTRL_SWRST (1 << 31) +#define S3C_CIGCTRL_CAMRST_A (1 << 30) +#define S3C_CIGCTRL_SELCAM_ITU_B (0 << 29) +#define S3C_CIGCTRL_SELCAM_ITU_A (1 << 29) +#define S3C_CIGCTRL_SELCAM_ITU_MASK (1 << 29) +#define S3C_CIGCTRL_TESTPATTERN_NORMAL (0 << 27) +#define S3C_CIGCTRL_TESTPATTERN_COLOR_BAR (1 << 27) +#define S3C_CIGCTRL_TESTPATTERN_HOR_INC (2 << 27) +#define S3C_CIGCTRL_TESTPATTERN_VER_INC (3 << 27) +#define S3C_CIGCTRL_TESTPATTERN_MASK (3 << 27) +#define S3C_CIGCTRL_TESTPATTERN_SHIFT (27) +#define S3C_CIGCTRL_INVPOLPCLK (1 << 26) +#define S3C_CIGCTRL_INVPOLVSYNC (1 << 25) +#define S3C_CIGCTRL_INVPOLHREF (1 << 24) +#define S3C_CIGCTRL_IRQ_OVFEN (1 << 22) +#define S3C_CIGCTRL_HREF_MASK (1 << 21) +#define S3C_CIGCTRL_IRQ_EDGE (0 << 20) +#define S3C_CIGCTRL_IRQ_LEVEL (1 << 20) +#define S3C_CIGCTRL_IRQ_CLR (1 << 19) +#define S3C_CIGCTRL_IRQ_END_DISABLE (1 << 18) +#define S3C_CIGCTRL_IRQ_DISABLE (0 << 16) +#define S3C_CIGCTRL_IRQ_ENABLE (1 << 16) +#define S3C_CIGCTRL_SHADOW_DISABLE (1 << 12) +#define S3C_CIGCTRL_CAM_JPEG (1 << 8) +#define S3C_CIGCTRL_SELCAM_MIPI_B (0 << 7) +#define S3C_CIGCTRL_SELCAM_MIPI_A (1 << 7) +#define S3C_CIGCTRL_SELCAM_MIPI_MASK (1 << 7) +#define S3C_CIGCTRL_SELWB_CAMIF_CAMERA (0 << 6) +#define S3C_CIGCTRL_SELWB_CAMIF_WRITEBACK (1 << 6) +#define S3C_CIGCTRL_SELWRITEBACK_MASK (1 << 10) +#define S3C_CIGCTRL_SELWRITEBACK_A (1 << 10) +#define S3C_CIGCTRL_SELWRITEBACK_B (0 << 10) +#define S3C_CIGCTRL_SELWB_CAMIF_MASK (1 << 6) +#define S3C_CIGCTRL_CSC_ITU601 (0 << 5) +#define S3C_CIGCTRL_CSC_ITU709 (1 << 5) +#define S3C_CIGCTRL_CSC_MASK (1 << 5) +#define S3C_CIGCTRL_INVPOLHSYNC (1 << 4) +#define S3C_CIGCTRL_SELCAM_FIMC_ITU (0 << 3) +#define S3C_CIGCTRL_SELCAM_FIMC_MIPI (1 << 3) +#define S3C_CIGCTRL_SELCAM_FIMC_MASK (1 << 3) +#define S3C_CIGCTRL_PROGRESSIVE (0 << 0) +#define S3C_CIGCTRL_INTERLACE (1 << 0) + +/* Window offset2 register */ +#define S3C_CIWDOFST_WINHOROFST2_MASK (0xfff << 16) +#define S3C_CIWDOFST_WINVEROFST2_MASK (0xfff << 16) + +/* Target format register */ +#define S3C_CITRGFMT_INROT90_CLOCKWISE (1 << 31) +#define S3C_CITRGFMT_OUTFORMAT_YCBCR420 (0 << 29) +#define S3C_CITRGFMT_OUTFORMAT_YCBCR422 (1 << 29) +#define S3C_CITRGFMT_OUTFORMAT_YCBCR422_1PLANE (2 << 29) +#define S3C_CITRGFMT_OUTFORMAT_RGB (3 << 29) +#define S3C_CITRGFMT_OUTFORMAT_MASK (3 << 29) +#define S3C_CITRGFMT_FLIP_SHIFT (14) +#define S3C_CITRGFMT_FLIP_NORMAL (0 << 14) +#define S3C_CITRGFMT_FLIP_X_MIRROR (1 << 14) +#define S3C_CITRGFMT_FLIP_Y_MIRROR (2 << 14) +#define S3C_CITRGFMT_FLIP_180 (3 << 14) +#define S3C_CITRGFMT_FLIP_MASK (3 << 14) +#define S3C_CITRGFMT_OUTROT90_CLOCKWISE (1 << 13) +#define S3C_CITRGFMT_TARGETV_MASK (0x1fff << 0) +#define S3C_CITRGFMT_TARGETH_MASK (0x1fff << 16) + +/* Output DMA control register */ +#define S3C_CIOCTRL_WEAVE_OUT (1 << 31) +#define S3C_CIOCTRL_WEAVE_MASK (1 << 31) +#define S3C_CIOCTRL_LASTENDEN (1 << 30) +#define S3C_CIOCTRL_ORDER2P_LSB_CBCR (0 << 24) +#define S3C_CIOCTRL_ORDER2P_LSB_CRCB (1 << 24) +#define S3C_CIOCTRL_ORDER2P_MSB_CRCB (2 << 24) +#define S3C_CIOCTRL_ORDER2P_MSB_CBCR (3 << 24) +#define S3C_CIOCTRL_ORDER2P_SHIFT (24) +#define S3C_CIOCTRL_ORDER2P_MASK (3 << 24) +#define S3C_CIOCTRL_YCBCR_3PLANE (0 << 3) +#define S3C_CIOCTRL_YCBCR_2PLANE (1 << 3) +#define S3C_CIOCTRL_YCBCR_PLANE_MASK (1 << 3) +#define S3C_CIOCTRL_LASTIRQ_ENABLE (1 << 2) +#define S3C_CIOCTRL_ORDER422_YCBYCR (0 << 0) +#define S3C_CIOCTRL_ORDER422_YCRYCB (1 << 0) +#define S3C_CIOCTRL_ORDER422_CBYCRY (2 << 0) +#define S3C_CIOCTRL_ORDER422_CRYCBY (3 << 0) +#define S3C_CIOCTRL_ORDER422_MASK (3 << 0) + +/* Main scaler control register */ +#define S3C_CISCCTRL_SCALERBYPASS (1 << 31) +#define S3C_CISCCTRL_SCALEUP_H (1 << 30) +#define S3C_CISCCTRL_SCALEUP_V (1 << 29) +#define S3C_CISCCTRL_CSCR2Y_NARROW (0 << 28) +#define S3C_CISCCTRL_CSCR2Y_WIDE (1 << 28) +#define S3C_CISCCTRL_CSCY2R_NARROW (0 << 27) +#define S3C_CISCCTRL_CSCY2R_WIDE (1 << 27) +#define S3C_CISCCTRL_LCDPATHEN_FIFO (1 << 26) +#define S3C_CISCCTRL_PROGRESSIVE (0 << 25) +#define S3C_CISCCTRL_INTERLACE (1 << 25) +#define S3C_CISCCTRL_SCAN_MASK (1 << 25) +#define S3C_CISCCTRL_SCALERSTART (1 << 15) +#define S3C_CISCCTRL_INRGB_FMT_RGB565 (0 << 13) +#define S3C_CISCCTRL_INRGB_FMT_RGB666 (1 << 13) +#define S3C_CISCCTRL_INRGB_FMT_RGB888 (2 << 13) +#define S3C_CISCCTRL_INRGB_FMT_RGB_MASK (3 << 13) +#define S3C_CISCCTRL_OUTRGB_FMT_RGB565 (0 << 11) +#define S3C_CISCCTRL_OUTRGB_FMT_RGB666 (1 << 11) +#define S3C_CISCCTRL_OUTRGB_FMT_RGB888 (2 << 11) +#define S3C_CISCCTRL_OUTRGB_FMT_RGB_MASK (3 << 11) +#define S3C_CISCCTRL_EXTRGB_NORMAL (0 << 10) +#define S3C_CISCCTRL_EXTRGB_EXTENSION (1 << 10) +#define S3C_CISCCTRL_ONE2ONE (1 << 9) +#define S3C_CISCCTRL_MAIN_V_RATIO_MASK (0x1ff << 0) +#define S3C_CISCCTRL_MAIN_H_RATIO_MASK (0x1ff << 16) + +/* Status register */ +#define S3C_CISTATUS_OVFIY (1 << 31) +#define S3C_CISTATUS_OVFICB (1 << 30) +#define S3C_CISTATUS_OVFICR (1 << 29) +#define S3C_CISTATUS_VSYNC (1 << 28) +#define S3C_CISTATUS_SCALERSTART (1 << 26) +#define S3C_CISTATUS_WINOFSTEN (1 << 25) +#define S3C_CISTATUS_IMGCPTEN (1 << 22) +#define S3C_CISTATUS_IMGCPTENSC (1 << 21) +#define S3C_CISTATUS_VSYNC_A (1 << 20) +#define S3C_CISTATUS_VSYNC_B (1 << 19) +#define S3C_CISTATUS_OVRLB (1 << 18) +#define S3C_CISTATUS_FRAMEEND (1 << 17) +#define S3C_CISTATUS_LASTCAPTUREEND (1 << 16) +#define S3C_CISTATUS_VVALID_A (1 << 15) +#define S3C_CISTATUS_VVALID_B (1 << 14) + +/* Image capture enable register */ +#define S3C_CIIMGCPT_IMGCPTEN (1 << 31) +#define S3C_CIIMGCPT_IMGCPTEN_SC (1 << 30) +#define S3C_CIIMGCPT_CPT_FREN_ENABLE (1 << 25) +#define S3C_CIIMGCPT_CPT_FRMOD_EN (0 << 18) +#define S3C_CIIMGCPT_CPT_FRMOD_CNT (1 << 18) + +/* Image effects register */ +#define S3C_CIIMGEFF_IE_DISABLE (0 << 30) +#define S3C_CIIMGEFF_IE_ENABLE (1 << 30) +#define S3C_CIIMGEFF_IE_SC_BEFORE (0 << 29) +#define S3C_CIIMGEFF_IE_SC_AFTER (1 << 29) +#define S3C_CIIMGEFF_FIN_BYPASS (0 << 26) +#define S3C_CIIMGEFF_FIN_ARBITRARY (1 << 26) +#define S3C_CIIMGEFF_FIN_NEGATIVE (2 << 26) +#define S3C_CIIMGEFF_FIN_ARTFREEZE (3 << 26) +#define S3C_CIIMGEFF_FIN_EMBOSSING (4 << 26) +#define S3C_CIIMGEFF_FIN_SILHOUETTE (5 << 26) +#define S3C_CIIMGEFF_FIN_MASK (7 << 26) +#define S3C_CIIMGEFF_PAT_CBCR_MASK ((0xff < 13) | (0xff < 0)) + +/* Real input DMA size register */ +#define S3C_CIREAL_ISIZE_AUTOLOAD_ENABLE (1 << 31) +#define S3C_CIREAL_ISIZE_ADDR_CH_DISABLE (1 << 30) +#define S3C_CIREAL_ISIZE_HEIGHT_MASK (0x3FFF << 16) +#define S3C_CIREAL_ISIZE_WIDTH_MASK (0x3FFF << 0) + +/* Input DMA control register */ +#define S3C_MSCTRL_FIELD_MASK (1 << 31) +#define S3C_MSCTRL_FIELD_WEAVE (1 << 31) +#define S3C_MSCTRL_FIELD_NORMAL (0 << 31) +#define S3C_MSCTRL_BURST_CNT (24) +#define S3C_MSCTRL_BURST_CNT_MASK (0xf << 24) +#define S3C_MSCTRL_ORDER2P_LSB_CBCR (0 << 16) +#define S3C_MSCTRL_ORDER2P_LSB_CRCB (1 << 16) +#define S3C_MSCTRL_ORDER2P_MSB_CRCB (2 << 16) +#define S3C_MSCTRL_ORDER2P_MSB_CBCR (3 << 16) +#define S3C_MSCTRL_ORDER2P_SHIFT (16) +#define S3C_MSCTRL_ORDER2P_SHIFT_MASK (0x3 << 16) +#define S3C_MSCTRL_C_INT_IN_3PLANE (0 << 15) +#define S3C_MSCTRL_C_INT_IN_2PLANE (1 << 15) +#define S3C_MSCTRL_FLIP_SHIFT (13) +#define S3C_MSCTRL_FLIP_NORMAL (0 << 13) +#define S3C_MSCTRL_FLIP_X_MIRROR (1 << 13) +#define S3C_MSCTRL_FLIP_Y_MIRROR (2 << 13) +#define S3C_MSCTRL_FLIP_180 (3 << 13) +#define S3C_MSCTRL_FLIP_MASK (3 << 13) +#define S3C_MSCTRL_ORDER422_CRYCBY (0 << 4) +#define S3C_MSCTRL_ORDER422_YCRYCB (1 << 4) +#define S3C_MSCTRL_ORDER422_CBYCRY (2 << 4) +#define S3C_MSCTRL_ORDER422_YCBYCR (3 << 4) +#define S3C_MSCTRL_INPUT_EXTCAM (0 << 3) +#define S3C_MSCTRL_INPUT_MEMORY (1 << 3) +#define S3C_MSCTRL_INPUT_MASK (1 << 3) +#define S3C_MSCTRL_INFORMAT_YCBCR420 (0 << 1) +#define S3C_MSCTRL_INFORMAT_YCBCR422 (1 << 1) +#define S3C_MSCTRL_INFORMAT_YCBCR422_1PLANE (2 << 1) +#define S3C_MSCTRL_INFORMAT_RGB (3 << 1) +#define S3C_MSCTRL_ENVID (1 << 0) + +/* DMA parameter register */ +#define S3C_CIDMAPARAM_R_MODE_LINEAR (0 << 29) +#define S3C_CIDMAPARAM_R_MODE_CONFTILE (1 << 29) +#define S3C_CIDMAPARAM_R_MODE_16X16 (2 << 29) +#define S3C_CIDMAPARAM_R_MODE_64X32 (3 << 29) +#define S3C_CIDMAPARAM_R_MODE_MASK (3 << 29) +#define S3C_CIDMAPARAM_R_TILE_HSIZE_64 (0 << 24) +#define S3C_CIDMAPARAM_R_TILE_HSIZE_128 (1 << 24) +#define S3C_CIDMAPARAM_R_TILE_HSIZE_256 (2 << 24) +#define S3C_CIDMAPARAM_R_TILE_HSIZE_512 (3 << 24) +#define S3C_CIDMAPARAM_R_TILE_HSIZE_1024 (4 << 24) +#define S3C_CIDMAPARAM_R_TILE_HSIZE_2048 (5 << 24) +#define S3C_CIDMAPARAM_R_TILE_HSIZE_4096 (6 << 24) +#define S3C_CIDMAPARAM_R_TILE_VSIZE_1 (0 << 20) +#define S3C_CIDMAPARAM_R_TILE_VSIZE_2 (1 << 20) +#define S3C_CIDMAPARAM_R_TILE_VSIZE_4 (2 << 20) +#define S3C_CIDMAPARAM_R_TILE_VSIZE_8 (3 << 20) +#define S3C_CIDMAPARAM_R_TILE_VSIZE_16 (4 << 20) +#define S3C_CIDMAPARAM_R_TILE_VSIZE_32 (5 << 20) +#define S3C_CIDMAPARAM_W_MODE_LINEAR (0 << 13) +#define S3C_CIDMAPARAM_W_MODE_CONFTILE (1 << 13) +#define S3C_CIDMAPARAM_W_MODE_16X16 (2 << 13) +#define S3C_CIDMAPARAM_W_MODE_64X32 (3 << 13) +#define S3C_CIDMAPARAM_W_MODE_MASK (3 << 13) +#define S3C_CIDMAPARAM_W_TILE_HSIZE_64 (0 << 8) +#define S3C_CIDMAPARAM_W_TILE_HSIZE_128 (1 << 8) +#define S3C_CIDMAPARAM_W_TILE_HSIZE_256 (2 << 8) +#define S3C_CIDMAPARAM_W_TILE_HSIZE_512 (3 << 8) +#define S3C_CIDMAPARAM_W_TILE_HSIZE_1024 (4 << 8) +#define S3C_CIDMAPARAM_W_TILE_HSIZE_2048 (5 << 8) +#define S3C_CIDMAPARAM_W_TILE_HSIZE_4096 (6 << 8) +#define S3C_CIDMAPARAM_W_TILE_VSIZE_1 (0 << 4) +#define S3C_CIDMAPARAM_W_TILE_VSIZE_2 (1 << 4) +#define S3C_CIDMAPARAM_W_TILE_VSIZE_4 (2 << 4) +#define S3C_CIDMAPARAM_W_TILE_VSIZE_8 (3 << 4) +#define S3C_CIDMAPARAM_W_TILE_VSIZE_16 (4 << 4) +#define S3C_CIDMAPARAM_W_TILE_VSIZE_32 (5 << 4) + +/* Gathering Extension register */ +#define S3C_CIEXTEN_TARGETH_EXT_MASK (1 << 26) +#define S3C_CIEXTEN_TARGETV_EXT_MASK (1 << 24) +#define S3C_CIEXTEN_MAINHORRATIO_EXT_MASK (0x3F << 10) +#define S3C_CIEXTEN_MAINVERRATIO_EXT_MASK (0x3F) +#define S3C_CIEXTEN_YUV444_OUT (1 << 22) + +/* FIMC Clock Source Select register */ +#define S3C_CLKSRC_HCLK (0 << 1) +#define S3C_CLKSRC_HCLK_MASK (1 << 1) +#define S3C_CLKSRC_SCLK (1 << 1) + +/* SYSREG for FIMC writeback */ +#define SYSREG_CAMERA_BLK (S3C_VA_SYS + 0x0218) +#define SYSREG_ISP_BLK (S3C_VA_SYS + 0x020c) + +#endif /* __ASM_PLAT_REGS_FIMC_H */ diff --git a/arch/arm/plat-s5p/include/plat/regs-ipc.h b/arch/arm/plat-s5p/include/plat/regs-ipc.h new file mode 100644 index 0000000..ea439c8 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/regs-ipc.h @@ -0,0 +1,143 @@ +/* linux/arch/arm/plat-s5p/include/plat/regs-ipc.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Register definition file for IPC driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_PLAT_REGS_IPC_H +#define __ASM_PLAT_REGS_IPC_H __FILE__ + +#define IPC_2D_ENABLE 0x10000 +#define IPC_HOR_SCALING_ENABLE 0x8000 + +/* + * Registers +*/ +#define S3C_IPC_ENABLE (0x00) +#define S3C_IPC_SRESET (0x04) +#define S3C_IPC_SHADOW_UPDATE (0x08) +#define S3C_IPC_FIELD_ID (0x0c) +#define S3C_IPC_MODE (0x10) +#define S3C_IPC_PEL_RATE_CTRL (0x1C) +#define S3C_IPC_ENDIAN_MODE (0x3C) +#define S3C_IPC_SRC_WIDTH (0x4C) +#define S3C_IPC_SRC_HEIGHT (0x50) +#define S3C_IPC_DST_WIDTH (0x5C) +#define S3C_IPC_DST_HEIGHT (0x60) +#define S3C_IPC_H_RATIO (0x64) +#define S3C_IPC_V_RATIO (0x68) + +#define S3C_IPC_POLY8_Y0_LL (0x6C) +#define S3C_IPC_POLY8_Y0_LH (0x70) +#define S3C_IPC_POLY8_Y0_HL (0x74) +#define S3C_IPC_POLY8_Y0_HH (0x78) +#define S3C_IPC_POLY8_Y1_LL (0x7C) +#define S3C_IPC_POLY8_Y1_LH (0x80) +#define S3C_IPC_POLY8_Y1_HL (0x84) +#define S3C_IPC_POLY8_Y1_HH (0x88) +#define S3C_IPC_POLY8_Y2_LL (0x8C) +#define S3C_IPC_POLY8_Y2_LH (0x90) +#define S3C_IPC_POLY8_Y2_HL (0x94) +#define S3C_IPC_POLY8_Y2_HH (0x98) +#define S3C_IPC_POLY8_Y3_LL (0x9C) +#define S3C_IPC_POLY8_Y3_LH (0xA0) +#define S3C_IPC_POLY8_Y3_HL (0xA4) +#define S3C_IPC_POLY8_Y3_HH (0xA8) +#define S3C_IPC_POLY4_Y0_LL (0xEC) +#define S3C_IPC_POLY4_Y0_LH (0xF0) +#define S3C_IPC_POLY4_Y0_HL (0xF4) +#define S3C_IPC_POLY4_Y0_HH (0xF8) +#define S3C_IPC_POLY4_Y1_LL (0xFC) +#define S3C_IPC_POLY4_Y1_LH (0x100) +#define S3C_IPC_POLY4_Y1_HL (0x104) +#define S3C_IPC_POLY4_Y1_HH (0x108) +#define S3C_IPC_POLY4_Y2_LL (0x10C) +#define S3C_IPC_POLY4_Y2_LH (0x110) +#define S3C_IPC_POLY4_Y2_HL (0x114) +#define S3C_IPC_POLY4_Y2_HH (0x118) +#define S3C_IPC_POLY4_Y3_LL (0x11C) +#define S3C_IPC_POLY4_Y3_LH (0x120) +#define S3C_IPC_POLY4_Y3_HL (0x124) +#define S3C_IPC_POLY4_Y3_HH (0x128) +#define S3C_IPC_POLY4_C0_LL (0x12C) +#define S3C_IPC_POLY4_C0_LH (0x130) +#define S3C_IPC_POLY4_C0_HL (0x134) +#define S3C_IPC_POLY4_C0_HH (0x138) +#define S3C_IPC_POLY4_C1_LL (0x13C) +#define S3C_IPC_POLY4_C1_LH (0x140) +#define S3C_IPC_POLY4_C1_HL (0x144) +#define S3C_IPC_POLY4_C1_HH (0x148) +#define S3C_IPC_BYPASS (0x200) +#define S3C_IPC_PP_SATURATION (0x20C) +#define S3C_IPC_PP_SHARPNESS (0x210) +#define S3C_IPC_PP_LINE_EQ0 (0x218) +#define S3C_IPC_PP_LINE_EQ1 (0x21C) +#define S3C_IPC_PP_LINE_EQ2 (0x220) +#define S3C_IPC_PP_LINE_EQ3 (0x224) +#define S3C_IPC_PP_LINE_EQ4 (0x228) +#define S3C_IPC_PP_LINE_EQ5 (0x22C) +#define S3C_IPC_PP_LINE_EQ6 (0x230) +#define S3C_IPC_PP_LINE_EQ7 (0x234) +#define S3C_IPC_PP_BRIGHT_OFFSET (0x238) +#define S3C_IPC_VERSION_INFO (0x3FC) + +/* + * Bit Definitions +*/ +/* ENABLE/DISABLE CONTROL */ +#define S3C_IPC_ON (1 << 0) +#define S3C_IPC_OFF (0 << 0) + +/* SOFTWARE RESET */ +#define S3C_IPC_SRESET_ENABLE (1 << 0) +#define S3C_IPC_SRESET_MASK (1 << 0) + +/* SHADOW UPDATE ENABLE CONTROL */ +#define S3C_IPC_SHADOW_UPDATE_ENABLE (1 << 0) +#define S3C_IPC_SHADOW_UPDATE_DISABLE (0 << 0) + +/* OPERATION MODE CONTROL */ +#define S3C_IPC_2D_ENABLE (1 << 0) +#define S3C_IPC_2D_DISABLE (0 << 0) +#define S3C_IPC_2D_MASK (1 << 1) + +/* VERTICAL SCALER PIXEL RATE CONTROL */ +#define S3C_IPC_PEL_RATE_SET (0 << 0) + +/* HORIZONTAL ZOOM RATIO */ +#define S3C_IPC_H_RATIO_MASK (0x7fff << 0) +#define S3C_IPC_V_RATIO_MASK (0x7fff << 0) + +/* POST PROCESSING IMAGE BYPASS MODE CONTROL */ +#define S3C_IPC_PP_BYPASS_ENABLE (0 << 0) +#define S3C_IPC_PP_BYPASS_DISABLE (1 << 0) +#define S3C_IPC_PP_BYPASS_MASK (1 << 0) + +/* BRIGHTNESS AND CONTRAST CONTROL */ +#define S3C_IPC_PP_LINE_CONTRAST_MASK (0xff << 0) +#define S3C_IPC_PP_LINE_BRIGTHNESS_MASK (0xffff << 8) + +/* + * Macro part +*/ +#define S3C_IPC_FIELD_ID_SELECTION(x) ((x) << 6) +#define S3C_IPC_FIELD_ID_AUTO_TOGGLING(x) ((x) << 2) +#define S3C_IPC_2D_CTRL(x) ((x) << 1) +#define S3C_IPC_SRC_WIDTH_SET(x) ((x) & 0x7ff << 0) +#define S3C_IPC_SRC_HEIGHT_SET(x) ((x) & 0x3ff << 0) +#define S3C_IPC_DST_WIDTH_SET(x) ((x) & 0x7ff << 0) +#define S3C_IPC_DST_HEIGHT_SET(x) ((x) & 0x3ff << 0) +#define S3C_IPC_PP_SATURATION_SET(x) ((x) & 0xff << 0) +#define S3C_IPC_PP_TH_HNOISE_SET(x) ((x) & 0xff << 8) +#define S3C_IPC_PP_SHARPNESS_SET(x) ((x) & 0x3 << 8) +#define S3C_IPC_PP_BRIGHT_OFFSET_SET(x) ((x) & 0x1ff << 8) +#define S3C_IPC_PP_LINE_CONTRAST(x) (((x) & S3C_IPC_PP_LINE_CONTRAST_MASK) << 0) +#define S3C_IPC_PP_LINE_BRIGHT(x) (((x) & S3C_IPC_PP_LINE_BRIGTHNESS_MASK) << 8) + +#endif /* __ASM_PLAT_REGS_IPC_H */ diff --git a/arch/arm/plat-s5p/include/plat/regs-mipidsim.h b/arch/arm/plat-s5p/include/plat/regs-mipidsim.h new file mode 100644 index 0000000..43b69cf --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/regs-mipidsim.h @@ -0,0 +1,149 @@ +/* linux/arch/arm/plat-s5p/include/plat/regs-mipidsim.h + * + * Register definition file for Samsung MIPI-DSIM driver + * + * Copyright (c) 2011 Samsung Electronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef _REGS_MIPIDSIM_H +#define _REGS_MIPIDSIM_H + +#define S5P_DSIM_STATUS (0x0) /* Status register */ +#define S5P_DSIM_SWRST (0x4) /* Software reset register */ +#define S5P_DSIM_CLKCTRL (0x8) /* Clock control register */ +#define S5P_DSIM_TIMEOUT (0xc) /* Time out register */ +#define S5P_DSIM_CONFIG (0x10) /* Configuration register */ +#define S5P_DSIM_ESCMODE (0x14) /* Escape mode register */ + +/* Main display image resolution register */ +#define S5P_DSIM_MDRESOL (0x18) +#define S5P_DSIM_MVPORCH (0x1c) /* Main display Vporch register */ +#define S5P_DSIM_MHPORCH (0x20) /* Main display Hporch register */ +#define S5P_DSIM_MSYNC (0x24) /* Main display sync area register +*/ + +/* Sub display image resolution register */ +#define S5P_DSIM_SDRESOL (0x28) +#define S5P_DSIM_INTSRC (0x2c) /* Interrupt source +register */ +#define S5P_DSIM_INTMSK (0x30) /* Interrupt mask register +*/ +#define S5P_DSIM_PKTHDR (0x34) /* Packet Header FIFO +register */ +#define S5P_DSIM_PAYLOAD (0x38) /* Payload FIFO register */ +#define S5P_DSIM_RXFIFO (0x3c) /* Read FIFO register */ +#define S5P_DSIM_FIFOTHLD (0x40) /* FIFO threshold level register */ +#define S5P_DSIM_FIFOCTRL (0x44) /* FIFO status and control register +*/ + +/* FIFO memory AC characteristic register */ +#define S5P_DSIM_PLLCTRL (0x4c) /* PLL control register */ +#define S5P_DSIM_PLLTMR (0x50) /* PLL timer register */ +#define S5P_DSIM_PHYACCHR (0x54) /* D-PHY AC characteristic register +*/ +#define S5P_DSIM_PHYACCHR1 (0x58) /* D-PHY AC characteristic +register1 */ + +/* DSIM_STATUS */ +#define DSIM_STOP_STATE_DAT(x) (((x) & 0xf) << 0) +#define DSIM_STOP_STATE_CLK (1 << 8) +#define DSIM_TX_READY_HS_CLK (1 << 10) + +/* DSIM_SWRST */ +#define DSIM_FUNCRST (1 << 16) +#define DSIM_SWRST (1 << 0) + +/* S5P_DSIM_TIMEOUT */ +#define DSIM_LPDR_TOUT_SHIFT (0) +#define DSIM_BTA_TOUT_SHIFT (16) + +/* S5P_DSIM_CLKCTRL */ +#define DSIM_LANE_ESC_CLKEN_SHIFT (19) +#define DSIM_BYTE_CLKEN_SHIFT (24) +#define DSIM_BYTE_CLK_SRC_SHIFT (25) +#define DSIM_PLL_BYPASS_SHIFT (27) +#define DSIM_ESC_CLKEN_SHIFT (28) +#define DSIM_TX_REQUEST_HSCLK_SHIFT (31) +#define DSIM_LANE_ESC_CLKEN(x) (((x) & 0x1f) << \ + DSIM_LANE_ESC_CLKEN_SHIFT) +#define DSIM_BYTE_CLK_ENABLE (1 << DSIM_BYTE_CLKEN_SHIFT) +#define DSIM_BYTE_CLK_DISABLE (0 << DSIM_BYTE_CLKEN_SHIFT) +#define DSIM_PLL_BYPASS_EXTERNAL (1 << DSIM_PLL_BYPASS_SHIFT) +#define DSIM_ESC_CLKEN_ENABLE (1 << DSIM_ESC_CLKEN_SHIFT) +#define DSIM_ESC_CLKEN_DISABLE (0 << DSIM_ESC_CLKEN_SHIFT) + +/* S5P_DSIM_CONFIG */ +#define DSIM_NUM_OF_DATALANE_SHIFT (5) +#define DSIM_HSA_MODE_SHIFT (20) +#define DSIM_HBP_MODE_SHIFT (21) +#define DSIM_HFP_MODE_SHIFT (22) +#define DSIM_HSE_MODE_SHIFT (23) +#define DSIM_AUTO_MODE_SHIFT (24) +#define DSIM_LANE_ENx(x) (((x) & 0x1f) << 0) + +#define DSIM_NUM_OF_DATA_LANE(x) ((x) << DSIM_NUM_OF_DATALANE_SHIFT) + +/* S5P_DSIM_ESCMODE */ +#define DSIM_TX_LPDT_SHIFT (6) +#define DSIM_CMD_LPDT_SHIFT (7) +#define DSIM_TX_LPDT_LP (1 << DSIM_TX_LPDT_SHIFT) +#define DSIM_CMD_LPDT_LP (1 << DSIM_CMD_LPDT_SHIFT) +#define DSIM_STOP_STATE_CNT_SHIFT (21) +#define DSIM_FORCE_STOP_STATE_SHIFT (20) + +/* S5P_DSIM_MDRESOL */ +#define DSIM_MAIN_STAND_BY (1 << 31) +#define DSIM_MAIN_VRESOL(x) (((x) & 0x7ff) << 16) +#define DSIM_MAIN_HRESOL(x) (((x) & 0X7ff) << 0) + +/* S5P_DSIM_MVPORCH */ +#define DSIM_CMD_ALLOW_SHIFT (28) +#define DSIM_STABLE_VFP_SHIFT (16) +#define DSIM_MAIN_VBP_SHIFT (0) +#define DSIM_CMD_ALLOW_MASK (0xf << DSIM_CMD_ALLOW_SHIFT) +#define DSIM_STABLE_VFP_MASK (0x7ff << DSIM_STABLE_VFP_SHIFT) +#define DSIM_MAIN_VBP_MASK (0x7ff << DSIM_MAIN_VBP_SHIFT) + +/* S5P_DSIM_MHPORCH */ +#define DSIM_MAIN_HFP_SHIFT (16) +#define DSIM_MAIN_HBP_SHIFT (0) +#define DSIM_MAIN_HFP_MASK ((0xffff) << DSIM_MAIN_HFP_SHIFT) +#define DSIM_MAIN_HBP_MASK ((0xffff) << DSIM_MAIN_HBP_SHIFT) + +/* S5P_DSIM_MSYNC */ +#define DSIM_MAIN_VSA_SHIFT (22) +#define DSIM_MAIN_HSA_SHIFT (0) +#define DSIM_MAIN_VSA_MASK ((0x3ff) << DSIM_MAIN_VSA_SHIFT) +#define DSIM_MAIN_HSA_MASK ((0xffff) << DSIM_MAIN_HSA_SHIFT) + +/* S5P_DSIM_SDRESOL */ +#define DSIM_SUB_STANDY_SHIFT (31) +#define DSIM_SUB_VRESOL_SHIFT (16) +#define DSIM_SUB_HRESOL_SHIFT (0) +#define DSIM_SUB_STANDY_MASK ((0x1) << DSIM_SUB_STANDY_SHIFT) +#define DSIM_SUB_VRESOL_MASK ((0x7ff) << DSIM_SUB_VRESOL_SHIFT) +#define DSIM_SUB_HRESOL_MASK ((0x7ff) << DSIM_SUB_HRESOL_SHIFT) + +/* S5P_DSIM_INTSRC */ +#define INTSRC_FRAME_DONE (1 << 24) +#define INTSRC_PLL_STABLE (1 << 31) +#define INTSRC_SFR_FIFO_EMPTY (1 << 29) + +/* S5P_DSIM_INTMSK */ +#define INTMSK_FRAME_DONE (1 << 24) + +/* S5P_DSIM_FIFOCTRL */ +#define SFR_HEADER_EMPTY (1 << 22) + +/* S5P_DSIM_PHYACCHR */ +#define DSIM_AFC_CTL(x) (((x) & 0x7) << 5) + +/* S5P_DSIM_PLLCTRL */ +#define DSIM_PLL_EN_SHIFT (23) +#define DSIM_FREQ_BAND_SHIFT (24) + +#endif /* _REGS_MIPIDSIM_H */ diff --git a/arch/arm/plat-s5p/include/plat/regs_jpeg.h b/arch/arm/plat-s5p/include/plat/regs_jpeg.h new file mode 100644 index 0000000..cd9bb2f --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/regs_jpeg.h @@ -0,0 +1,144 @@ +/* linux/arch/arm/plat-s5p/include/plat/regs-jpeg.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Register definition file for Samsung JPEG Encoder/Decoder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARM_REGS_S5P_JPEG_H +#define __ASM_ARM_REGS_S5P_JPEG_H + +/* JPEG Registers part */ + +/* JPEG Codec Control Registers */ +#define S5P_JPEG_MOD_REG 0x00 +#define S5P_JPEG_OPR_REG 0x04 +#define S5P_JPEG_QTBL_REG 0x08 +#define S5P_JPEG_HTBL_REG 0x0c +#define S5P_JPEG_DRI_U_REG 0x10 +#define S5P_JPEG_DRI_L_REG 0x14 +#define S5P_JPEG_Y_U_REG 0x18 +#define S5P_JPEG_Y_L_REG 0x1c +#define S5P_JPEG_X_U_REG 0x20 +#define S5P_JPEG_X_L_REG 0x24 +#define S5P_JPEG_CNT_U_REG 0x28 +#define S5P_JPEG_CNT_M_REG 0x2c +#define S5P_JPEG_CNT_L_REG 0x30 +#define S5P_JPEG_INTSE_REG 0x34 +#define S5P_JPEG_INTST_REG 0x38 + +#define S5P_JPEG_COM_REG 0x4c + +/* raw image data address */ +#define S5P_JPEG_IMGADR_REG 0x50 + +#define S5P_JPEG_JPGADR_REG 0x58 +#define S5P_JPEG_COEF1_REG 0x5c +#define S5P_JPEG_COEF2_REG 0x60 +#define S5P_JPEG_COEF3_REG 0x64 + +#define S5P_JPEG_CMOD_REG 0x68 +#define S5P_JPEG_CLKCON_REG 0x6c + +#define S5P_JPEG_JSTART_REG 0x70 +#define S5P_JPEG_JRSTART_REG 0x74 +#define S5P_JPEG_SW_RESET_REG 0x78 + +#define S5P_JPEG_TIMER_SE_REG 0x7c +#define S5P_JPEG_TIMER_ST_REG 0x80 +#define S5P_JPEG_COMSTAT_REG 0x84 +#define S5P_JPEG_OUTFORM_REG 0x88 +#define S5P_JPEG_VERSION_REG 0x8c + +#define S5P_JPEG_ENC_STREAM_INTSE_REG 0x98 +#define S5P_JPEG_ENC_STREAM_INTST_REG 0x9c + +#define S5P_JPEG_QTBL0_REG 0x400 +#define S5P_JPEG_QTBL1_REG 0x500 +#define S5P_JPEG_QTBL2_REG 0x600 +#define S5P_JPEG_QTBL3_REG 0x700 + +#define S5P_JPEG_HDCTBL0_REG 0x800 +#define S5P_JPEG_HDCTBLG0_REG 0x840 +#define S5P_JPEG_HACTBL0_REG 0x880 +#define S5P_JPEG_HACTBLG0_REG 0x8c0 +#define S5P_JPEG_HDCTBL1_REG 0xc00 +#define S5P_JPEG_HDCTBLG1_REG 0xc40 +#define S5P_JPEG_HACTBL1_REG 0xc80 +#define S5P_JPEG_HACTBLG1_REG 0xcc0 + +/***************************************************************/ +/* Bit definition part */ +/***************************************************************/ + +/* JPEG Mode Register bit */ +#define S5P_JPEG_MOD_REG_PROC_ENC (0<<3) +#define S5P_JPEG_MOD_REG_PROC_DEC (1<<3) + +#define S5P_JPEG_MOD_REG_SUBSAMPLE_444 (0<<0) +#define S5P_JPEG_MOD_REG_SUBSAMPLE_422 (1<<0) +#define S5P_JPEG_MOD_REG_SUBSAMPLE_420 (2<<0) +#define S5P_JPEG_MOD_REG_SUBSAMPLE_GRAY (3<<0) + +/* JPEG Operation Status Register bit */ +#define S5P_JPEG_OPR_REG_OPERATE (1<<0) +#define S5P_JPEG_OPR_REG_NO_OPERATE (0<<0) + +/* Quantization Table And Huffman Table Number Register bit */ +#define S5P_JPEG_QHTBL_REG_QT_NUM4 (1<<6) +#define S5P_JPEG_QHTBL_REG_QT_NUM3 (1<<4) +#define S5P_JPEG_QHTBL_REG_QT_NUM2 (1<<2) +#define S5P_JPEG_QHTBL_REG_QT_NUM1 (1<<0) + +#define S5P_JPEG_QHTBL_REG_HT_NUM4_AC (1<<7) +#define S5P_JPEG_QHTBL_REG_HT_NUM4_DC (1<<6) +#define S5P_JPEG_QHTBL_REG_HT_NUM3_AC (1<<5) +#define S5P_JPEG_QHTBL_REG_HT_NUM3_DC (1<<4) +#define S5P_JPEG_QHTBL_REG_HT_NUM2_AC (1<<3) +#define S5P_JPEG_QHTBL_REG_HT_NUM2_DC (1<<2) +#define S5P_JPEG_QHTBL_REG_HT_NUM1_AC (1<<1) +#define S5P_JPEG_QHTBL_REG_HT_NUM1_DC (1<<0) + +/* JPEG Color Mode Register bit */ +#define S5P_JPEG_CMOD_REG_MOD_SEL_RGB (2<<5) +#define S5P_JPEG_CMOD_REG_MOD_SEL_YCBCR422 (1<<5) +#define S5P_JPEG_CMOD_REG_MOD_MODE_Y16 (1<<1) +#define S5P_JPEG_CMOD_REG_MOD_MODE_0 (0<<1) + +/* JPEG Clock Control Register bit */ +#define S5P_JPEG_CLKCON_REG_CLK_DOWN_READY_ENABLE (0<<1) +#define S5P_JPEG_CLKCON_REG_CLK_DOWN_READY_DISABLE (1<<1) +#define S5P_JPEG_CLKCON_REG_POWER_ON_ACTIVATE (1<<0) +#define S5P_JPEG_CLKCON_REG_POWER_ON_DISABLE (0<<0) + +/* JPEG Start Register bit */ +#define S5P_JPEG_JSTART_REG_ENABLE (1<<0) + +/* JPEG Rdstart Register bit */ +#define S5P_JPEG_JRSTART_REG_ENABLE (1<<0) + +/* JPEG SW Reset Register bit */ +#define S5P_JPEG_SW_RESET_REG_ENABLE (1<<0) + +/* JPEG Interrupt Setting Register bit */ +#define S5P_JPEG_INTSE_REG_RSTM_INT_EN (1<<7) +#define S5P_JPEG_INTSE_REG_DATA_NUM_INT_EN (1<<6) +#define S5P_JPEG_INTSE_REG_FINAL_MCU_NUM_INT_EN (1<<5) + +/* JPEG Decompression Output Format Register bit */ +#define S5P_JPEG_OUTFORM_REG_YCBCY422 (0<<0) +#define S5P_JPEG_OUTFORM_REG_YCBCY420 (1<<0) + +/* JPEG Decompression Input Stream Size Register bit */ +#define S5P_JPEG_DEC_STREAM_SIZE_REG_PROHIBIT (0x1FFFFFFF<<0) + +/* JPEG Command Register bit */ +#define S5P_JPEG_COM_INT_RELEASE (1<<2) + +#endif /* __ASM_ARM_REGS_S3C_JPEG_H */ + diff --git a/arch/arm/plat-s5p/include/plat/regs_jpeg_v2_x.h b/arch/arm/plat-s5p/include/plat/regs_jpeg_v2_x.h new file mode 100644 index 0000000..33ad38a --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/regs_jpeg_v2_x.h @@ -0,0 +1,217 @@ +/* linux/arch/arm/plat-s5p/include/plat/regs-jpeg_v2_x.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Register definition file for Samsung JPEG v.2 Encoder/Decoder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARM_REGS_S5P_JPEG_H +#define __ASM_ARM_REGS_S5P_JPEG_H + +/* JPEG Registers part */ + +/* JPEG Codec Control Registers */ +#define S5P_JPEG_CNTL_REG 0x00 +#define S5P_JPEG_INT_EN_REG 0x04 +#define S5P_JPEG_INT_TIMER_COUNT_REG 0x08 +#define S5P_JPEG_INT_STATUS_REG 0x0c +#define S5P_JPEG_OUT_MEM_BASE_REG 0x10 +#define S5P_JPEG_IMG_SIZE_REG 0x14 +#define S5P_JPEG_IMG_BA_PLANE_1_REG 0x18 +#define S5P_JPEG_IMG_SO_PLANE_1_REG 0x1c +#define S5P_JPEG_IMG_PO_PLANE_1_REG 0x20 +#define S5P_JPEG_IMG_BA_PLANE_2_REG 0x24 +#define S5P_JPEG_IMG_SO_PLANE_2_REG 0x28 +#define S5P_JPEG_IMG_PO_PLANE_2_REG 0x2c +#define S5P_JPEG_IMG_BA_PLANE_3_REG 0x30 +#define S5P_JPEG_IMG_SO_PLANE_3_REG 0x34 +#define S5P_JPEG_IMG_PO_PLANE_3_REG 0x38 + +#define S5P_JPEG_TBL_SEL_REG 0x3c + +#define S5P_JPEG_IMG_FMT_REG 0x40 + +#define S5P_JPEG_BITSTREAM_SIZE_REG 0x44 +#define S5P_JPEG_PADDING_REG 0x48 +#define S5P_JPEG_HUFF_CNT_REG 0x4c +#define S5P_JPEG_FIFO_STATUS_REG 0x50 +#define S5P_JPEG_DECODE_XY_SIZE_REG 0x54 +#define S5P_JPEG_DECODE_IMG_FMT_REG 0x58 + +#define S5P_JPEG_QUAN_TBL_ENTRY_REG 0x100 +#define S5P_JPEG_HUFF_TBL_ENTRY_REG 0x200 + + +/****************************************************************/ +/* Bit definition part */ +/****************************************************************/ + +/* JPEG CNTL Register bit */ +#define S5P_JPEG_ENC_DEC_MODE_MASK (0xfffffffc << 0) +#define S5P_JPEG_DEC_MODE (1 << 0) +#define S5P_JPEG_ENC_MODE (1 << 1) +#define S5P_JPEG_AUTO_RST_MARKER (1 << 2) +#define S5P_JPEG_RST_INTERVAL_SHIFT 3 +#define S5P_JPEG_RST_INTERVAL(x) (((x) & 0xffff) << S5P_JPEG_RST_INTERVAL_SHIFT) +#define S5P_JPEG_HUF_TBL_EN (1 << 19) +#define S5P_JPEG_HOR_SCALING_SHIFT 20 +#define S5P_JPEG_HOR_SCALING_MASK (3 << S5P_JPEG_HOR_SCALING_SHIFT) +#define S5P_JPEG_HOR_SCALING(x) (((x) & 0x3) << S5P_JPEG_HOR_SCALING_SHIFT) +#define S5P_JPEG_VER_SCALING_SHIFT 22 +#define S5P_JPEG_VER_SCALING_MASK (3 << S5P_JPEG_VER_SCALING_SHIFT) +#define S5P_JPEG_VER_SCALING(x) (((x) & 0x3) << S5P_JPEG_VER_SCALING_SHIFT) +#define S5P_JPEG_PADDING (1 << 27) +#define S5P_JPEG_SYS_INT_EN (1 << 28) +#define S5P_JPEG_SOFT_RESET_HI (1 << 29) + +/* JPEG INT Register bit */ +#if defined (CONFIG_JPEG_V2_2) +#define S5P_JPEG_INT_EN_MASK (0x1ff << 0) +#define S5P_JPEG_INT_EN_ALL (0x1ff << 0) +#define S5P_JPEG_TIMER_INT_EN (1 << 5) +#define S5P_JPEG_DEC_UPSAMPLING_ERR_EN (1 << 6) +#define S5P_JPEG_ENC_WRONG_CONFIG_ERR_EN (1 << 7) +#define S5P_JPEG_WRONG_IP_CONFIG_ERR_EN (1 << 8) +#elif defined (CONFIG_JPEG_V2_1) +#define S5P_JPEG_INT_EN_MASK (0x1f << 0) +#define S5P_JPEG_INT_EN_ALL (0x1f << 0) +#endif + +#define S5P_JPEG_PROT_ERR_INT_EN (1 << 0) +#define S5P_JPEG_IMG_COMPLETION_INT_EN (1 << 1) +#define S5P_JPEG_DEC_INVALID_FORMAT_EN (1 << 2) +#define S5P_JPEG_MULTI_SCAN_ERROR_EN (1 << 3) +#define S5P_JPEG_FRAME_ERR_EN (1 << 4) + +#define S5P_JPEG_MOD_REG_PROC_ENC (0 << 3) +#define S5P_JPEG_MOD_REG_PROC_DEC (1 << 3) + +#define S5P_JPEG_MOD_REG_SUBSAMPLE_444 (0 << 0) +#define S5P_JPEG_MOD_REG_SUBSAMPLE_422 (1 << 0) +#define S5P_JPEG_MOD_REG_SUBSAMPLE_420 (2 << 0) +#define S5P_JPEG_MOD_REG_SUBSAMPLE_GRAY (3 << 0) + + +/* JPEG IMAGE SIZE Register bit */ +#define S5P_JPEG_X_SIZE_SHIFT 0 +#define S5P_JPEG_X_SIZE_MASK (0xffff << S5P_JPEG_X_SIZE_SHIFT) +#define S5P_JPEG_X_SIZE(x) (((x) & 0xffff) << S5P_JPEG_X_SIZE_SHIFT) +#define S5P_JPEG_Y_SIZE_SHIFT 16 +#define S5P_JPEG_Y_SIZE_MASK (0xffff << S5P_JPEG_Y_SIZE_SHIFT) +#define S5P_JPEG_Y_SIZE(x) (((x) & 0xffff) << S5P_JPEG_Y_SIZE_SHIFT) + +/* JPEG IMAGE FORMAT Register bit */ +#define S5P_JPEG_ENC_IN_FMT_MASK 0xffff0000 +#define S5P_JPEG_ENC_GRAY_IMG (0 << 0) +#define S5P_JPEG_ENC_RGB_IMG (1 << 0) +#define S5P_JPEG_ENC_YUV_444_IMG (2 << 0) +#define S5P_JPEG_ENC_YUV_422_IMG (3 << 0) +#define S5P_JPEG_ENC_YUV_440_IMG (4 << 0) + +#define S5P_JPEG_DEC_GRAY_IMG (0 << 0) +#define S5P_JPEG_DEC_RGB_IMG (1 << 0) +#define S5P_JPEG_DEC_YUV_444_IMG (2 << 0) +#define S5P_JPEG_DEC_YUV_422_IMG (3 << 0) +#define S5P_JPEG_DEC_YUV_420_IMG (4 << 0) + +#define S5P_JPEG_GRAY_IMG_IP_SHIFT 3 +#define S5P_JPEG_GRAY_IMG_IP_MASK (7 << S5P_JPEG_GRAY_IMG_IP_SHIFT) +#define S5P_JPEG_GRAY_IMG_IP (4 << S5P_JPEG_GRAY_IMG_IP_SHIFT) + +#define S5P_JPEG_RGB_IP_SHIFT 6 +#define S5P_JPEG_RGB_IP_MASK (7 << S5P_JPEG_RGB_IP_SHIFT) +#define S5P_JPEG_RGB_IP_RGB_16BIT_IMG (4 << S5P_JPEG_RGB_IP_SHIFT) +#define S5P_JPEG_RGB_IP_RGB_32BIT_IMG (5 << S5P_JPEG_RGB_IP_SHIFT) + +#define S5P_JPEG_YUV_444_IP_SHIFT 9 +#define S5P_JPEG_YUV_444_IP_MASK (7 << S5P_JPEG_YUV_444_IP_SHIFT) +#define S5P_JPEG_YUV_444_IP_YUV_444_2P_IMG (4 << S5P_JPEG_YUV_444_IP_SHIFT) +#define S5P_JPEG_YUV_444_IP_YUV_444_3P_IMG (5 << S5P_JPEG_YUV_444_IP_SHIFT) + +#define S5P_JPEG_YUV_422_IP_SHIFT 12 +#define S5P_JPEG_YUV_422_IP_MASK (7 << S5P_JPEG_YUV_422_IP_SHIFT) +#define S5P_JPEG_YUV_422_IP_YUV_422_1P_IMG (4 << S5P_JPEG_YUV_422_IP_SHIFT) +#define S5P_JPEG_YUV_422_IP_YUV_422_2P_IMG (5 << S5P_JPEG_YUV_422_IP_SHIFT) +#define S5P_JPEG_YUV_422_IP_YUV_422_3P_IMG (6 << S5P_JPEG_YUV_422_IP_SHIFT) + +#define S5P_JPEG_YUV_420_IP_SHIFT 15 +#define S5P_JPEG_YUV_420_IP_MASK (7 << S5P_JPEG_YUV_420_IP_SHIFT) +#define S5P_JPEG_YUV_420_IP_YUV_420_2P_IMG (4 << S5P_JPEG_YUV_420_IP_SHIFT) +#define S5P_JPEG_YUV_420_IP_YUV_420_3P_IMG (5 << S5P_JPEG_YUV_420_IP_SHIFT) + +#define S5P_JPEG_ENC_FMT_SHIFT 24 +#define S5P_JPEG_ENC_FMT_MASK (3 << S5P_JPEG_ENC_FMT_SHIFT) +#define S5P_JPEG_ENC_FMT_GRAY (0 << S5P_JPEG_ENC_FMT_SHIFT) +#define S5P_JPEG_ENC_FMT_YUV_444 (1 << S5P_JPEG_ENC_FMT_SHIFT) +#define S5P_JPEG_ENC_FMT_YUV_422 (2 << S5P_JPEG_ENC_FMT_SHIFT) +#define S5P_JPEG_ENC_FMT_YUV_420 (3 << S5P_JPEG_ENC_FMT_SHIFT) + +#define S5P_JPEG_SWAP_CHROMA_CrCb (1 << 26) +#define S5P_JPEG_SWAP_CHROMA_CbCr (0 << 26) + +#if defined (CONFIG_JPEG_V2_2) +#define S5P_JPEG_SWAP_RGB_SHIFT 29 +#define S5P_JPEG_SWAP_RGB_MASK (1 << S5P_JPEG_SWAP_RGB_SHIFT) +#define S5P_JPEG_ENC_FMT_BGR (1 << S5P_JPEG_SWAP_RGB_SHIFT) +#define S5P_JPEG_ENC_FMT_RGB (0 << S5P_JPEG_SWAP_RGB_SHIFT) + +#define S5P_JPEG_RE_ORDER_YUV_422_1P_SHIFT 27 +#define S5P_JPEG_RE_ORDER_YUV_422_1P_MASK (3 << S5P_JPEG_RE_ORDER_YUV_422_1P_SHIFT) +#define S5P_JPEG_ENC_FMT_YUYV (0 << S5P_JPEG_RE_ORDER_YUV_422_1P_SHIFT) +#define S5P_JPEG_ENC_FMT_YVYU (1 << S5P_JPEG_RE_ORDER_YUV_422_1P_SHIFT) +#define S5P_JPEG_ENC_FMT_UYVY (2 << S5P_JPEG_RE_ORDER_YUV_422_1P_SHIFT) +#define S5P_JPEG_ENC_FMT_VYUY (3 << S5P_JPEG_RE_ORDER_YUV_422_1P_SHIFT) +#endif +/* JPEG HUFF count Register bit */ +#define S5P_JPEG_HUFF_COUNT_MASK 0xffff + +/* JPEG Decoded_img_x_y_size Register bit */ +#define S5P_JPEG_DECODED_SIZE_MASK 0x0000ffff + +/* JPEG Decoded image format Register bit */ +#define S5P_JPEG_DECODED_IMG_FMT_MASK 0x3 + +/* JPEG TBL SEL Register bit */ +#define S5P_JPEG_Q_TBL_COMP1_SHIFT 0 +#define S5P_JPEG_Q_TBL_COMP1_0 (0 << S5P_JPEG_Q_TBL_COMP1_SHIFT) +#define S5P_JPEG_Q_TBL_COMP1_1 (1 << S5P_JPEG_Q_TBL_COMP1_SHIFT) +#define S5P_JPEG_Q_TBL_COMP1_2 (2 << S5P_JPEG_Q_TBL_COMP1_SHIFT) +#define S5P_JPEG_Q_TBL_COMP1_3 (3 << S5P_JPEG_Q_TBL_COMP1_SHIFT) + +#define S5P_JPEG_Q_TBL_COMP2_SHIFT 2 +#define S5P_JPEG_Q_TBL_COMP2_0 (0 << S5P_JPEG_Q_TBL_COMP2_SHIFT) +#define S5P_JPEG_Q_TBL_COMP2_1 (1 << S5P_JPEG_Q_TBL_COMP2_SHIFT) +#define S5P_JPEG_Q_TBL_COMP2_2 (2 << S5P_JPEG_Q_TBL_COMP2_SHIFT) +#define S5P_JPEG_Q_TBL_COMP2_3 (3 << S5P_JPEG_Q_TBL_COMP2_SHIFT) + +#define S5P_JPEG_Q_TBL_COMP3_SHIFT 4 +#define S5P_JPEG_Q_TBL_COMP3_0 (0 << S5P_JPEG_Q_TBL_COMP3_SHIFT) +#define S5P_JPEG_Q_TBL_COMP3_1 (1 << S5P_JPEG_Q_TBL_COMP3_SHIFT) +#define S5P_JPEG_Q_TBL_COMP3_2 (2 << S5P_JPEG_Q_TBL_COMP3_SHIFT) +#define S5P_JPEG_Q_TBL_COMP3_3 (3 << S5P_JPEG_Q_TBL_COMP3_SHIFT) + +#define S5P_JPEG_HUFF_TBL_COMP1_SHIFT 6 +#define S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_0 (0 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT) +#define S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_1 (1 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT) +#define S5P_JPEG_HUFF_TBL_COMP1_AC_1_DC_0 (2 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT) +#define S5P_JPEG_HUFF_TBL_COMP1_AC_1_DC_1 (3 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT) + +#define S5P_JPEG_HUFF_TBL_COMP2_SHIFT 8 +#define S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_0 (0 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT) +#define S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_1 (1 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT) +#define S5P_JPEG_HUFF_TBL_COMP2_AC_1_DC_0 (2 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT) +#define S5P_JPEG_HUFF_TBL_COMP2_AC_1_DC_1 (3 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT) + +#define S5P_JPEG_HUFF_TBL_COMP3_SHIFT 10 +#define S5P_JPEG_HUFF_TBL_COMP3_AC_0_DC_0 (0 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT) +#define S5P_JPEG_HUFF_TBL_COMP3_AC_0_DC_1 (1 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT) +#define S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_0 (2 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT) +#define S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_1 (3 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT) + +#endif /* __ASM_ARM_REGS_S5P_JPEG_H */ + diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h index 2b6dcff..551ee10 100644 --- a/arch/arm/plat-s5p/include/plat/s5p-clock.h +++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h @@ -18,6 +18,9 @@ #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) #define clk_fin_apll clk_ext_xtal_mux +#define clk_fin_bpll clk_ext_xtal_mux +#define clk_fin_gpll clk_ext_xtal_mux +#define clk_fin_cpll clk_ext_xtal_mux #define clk_fin_mpll clk_ext_xtal_mux #define clk_fin_epll clk_ext_xtal_mux #define clk_fin_dpll clk_ext_xtal_mux @@ -47,4 +50,9 @@ extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable); extern int s5p_epll_enable(struct clk *clk, int enable); extern unsigned long s5p_epll_get_rate(struct clk *clk); +/* SPDIF clk operations common for S5PC100/V210/C110 and Exynos4 */ +extern int s5p_spdif_set_rate(struct clk *clk, unsigned long rate); +extern unsigned long s5p_spdif_get_rate(struct clk *clk); + +extern struct clk_ops s5p_sclk_spdif_ops; #endif /* __ASM_PLAT_S5P_CLOCK_H */ diff --git a/arch/arm/plat-s5p/include/plat/s5p-iovmm.h b/arch/arm/plat-s5p/include/plat/s5p-iovmm.h new file mode 100644 index 0000000..2e31ce3 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/s5p-iovmm.h @@ -0,0 +1,55 @@ +/* linux/arch/arm/plat-s5p/include/plat/iovmm.h + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_PLAT_IOVMM_H +#define __ASM_PLAT_IOVMM_H + +#ifdef CONFIG_IOVMM +int iovmm_setup(struct device *dev); +void iovmm_cleanup(struct device *dev); +int iovmm_activate(struct device *dev); +void iovmm_deactivate(struct device *dev); + +/* iovmm_map() - Maps a list of physical memory chunks + * @dev: the owner of the IO address space where the mapping is created + * @sg: list of physical memory chunks to map + * @offset: length in bytes where the mapping starts + * @size: how much memory to map in bytes. @offset + @size must not exceed + * total size of @sg + * + * This function returns mapped IO address in the address space of @dev. + * Returns 0 if mapping fails. + * + * The caller of this function must ensure that iovmm_cleanup() is not called + * while this function is called. + * + */ +dma_addr_t iovmm_map(struct device *dev, struct scatterlist *sg, off_t offset, + size_t size); + +/* iovmm_map() - unmaps the given IO address + * @dev: the owner of the IO address space where @iova belongs + * @iova: IO address that needs to be unmapped and freed. + * + * The caller of this function must ensure that iovmm_cleanup() is not called + * while this function is called. + */ +void iovmm_unmap(struct device *dev, dma_addr_t iova); + +#else +#define iovmm_setup(dev) (-ENOSYS) +#define iovmm_cleanup(dev) +#define iovmm_activate(dev) (-ENOSYS) +#define iovmm_deactivate(dev) +#define iovmm_map(dev, sg) (0) +#define iovmm_unmap(dev, iova) +#endif /* CONFIG_IOVMM */ + +#endif /*__ASM_PLAT_IOVMM_H*/ diff --git a/arch/arm/plat-s5p/include/plat/s5p-mfc.h b/arch/arm/plat-s5p/include/plat/s5p-mfc.h new file mode 100644 index 0000000..f548b0f --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/s5p-mfc.h @@ -0,0 +1,29 @@ +/* linux/arch/arm/plat-s5p/include/plat/s5p-mfc.h + * + * Copyright 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Header file for s5p mfc support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _S5P_MFC_H +#define _S5P_MFC_H + +#include <linux/platform_device.h> + +struct s5p_mfc_platdata { + int clock_rate; +}; + +extern unsigned int mfc_clk_rate; +void s5p_mfc_set_platdata(struct s5p_mfc_platdata *pd); +void s5p_mfc_setname(struct platform_device *pdev,char *name); + +int exynos4_mfc_setup_clock(struct device *dev, + unsigned long clock_rate); + +#endif /* _S5P_MFC_H */ diff --git a/arch/arm/plat-s5p/include/plat/s5p-otghost.h b/arch/arm/plat-s5p/include/plat/s5p-otghost.h new file mode 100644 index 0000000..707cf27 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/s5p-otghost.h @@ -0,0 +1,68 @@ +/* linux/arch/arm/plat-s5p/include/plat/s5p-otghost.h + * + * Copyright 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Platform header file for Samsung OTG Host driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ +#ifndef _PLAT_S5P_OTGHOST_H +#define _PLAT_S5P_OTGHOST_H __FILE__ + +#include <linux/wakelock.h> +#include <linux/clk.h> +#include <linux/platform_device.h> + +/*#define CONFIG_USB_S3C_OTG_HOST_HANDLING_CLOCK*/ +#define CONFIG_USB_S3C_OTG_HOST_DTGDRVVBUS + +union port_flags_t { + /** raw register data */ + u32 d32; + /** register bits */ + struct { + unsigned port_connect_status_change:1; + unsigned port_connect_status:1; + unsigned port_reset_change:1; + unsigned port_enable_change:1; + unsigned port_suspend_change:1; + unsigned port_over_current_change:1; + unsigned reserved:26; + } b; +}; + +struct sec_otghost_data { + bool clk_usage; + + void (*set_pwr_cb)(int on); + void (*host_notify_cb)(int a); + int (*start)(u32 reg); + int (*stop)(void); + + int (*phy_init)(int mode); + int (*phy_exit)(int mode); + + struct platform_device *pdev; + struct clk *clk; + + int sec_whlist_table_num; + void __iomem *regs; +}; + +struct sec_otghost { + spinlock_t lock; + + bool ch_halt; + union port_flags_t port_flag; + struct wake_lock wake_lock; + + struct work_struct work; + struct workqueue_struct *wq; + + struct sec_otghost_data *otg_data; +}; + +#endif /*_PLAT_S5P_OTGHOST_H */ diff --git a/arch/arm/plat-s5p/include/plat/s5p-sysmmu.h b/arch/arm/plat-s5p/include/plat/s5p-sysmmu.h new file mode 100644 index 0000000..ad30a97 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/s5p-sysmmu.h @@ -0,0 +1,120 @@ +/* linux/arch/arm/plat-s5p/include/plat/sysmmu.h + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Samsung System MMU driver for S5P platform + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM__PLAT_SYSMMU_H +#define __ASM__PLAT_SYSMMU_H __FILE__ + +#include <linux/list.h> +#include <linux/atomic.h> +#include <linux/spinlock.h> + +enum S5P_SYSMMU_INTERRUPT_TYPE { + SYSMMU_PAGEFAULT, + SYSMMU_AR_MULTIHIT, + SYSMMU_AW_MULTIHIT, + SYSMMU_BUSERROR, + SYSMMU_AR_SECURITY, + SYSMMU_AR_ACCESS, + SYSMMU_AW_SECURITY, + SYSMMU_AW_PROTECTION, /* 7 */ + SYSMMU_FAULT_UNKNOWN, + SYSMMU_FAULTS_NUM +}; + +/* + * @itype: type of fault. + * @pgtable_base: the physical address of page table base. This is 0 if @itype + * is SYSMMU_BUSERROR. + * @fault_addr: the device (virtual) address that the System MMU tried to + * translated. This is 0 if @itype is SYSMMU_BUSERROR. + */ +typedef int (*s5p_sysmmu_fault_handler_t)(enum S5P_SYSMMU_INTERRUPT_TYPE itype, + unsigned long pgtable_base, unsigned long fault_addr); + +#ifdef CONFIG_S5P_SYSTEM_MMU +/** + * s5p_sysmmu_enable() - enable system mmu + * @owner: The device whose System MMU is about to be enabled. + * @pgd: Base physical address of the 1st level page table + * + * This function enable system mmu to transfer address + * from virtual address to physical address. + * Return non-zero if it fails to enable System MMU. + */ +int s5p_sysmmu_enable(struct device *owner, unsigned long pgd); + +/** + * s5p_sysmmu_disable() - disable sysmmu mmu of ip + * @owner: The device whose System MMU is about to be disabled. + * + * This function disable system mmu to transfer address + * from virtual address to physical address + */ +void s5p_sysmmu_disable(struct device *owner); + +/** + * s5p_sysmmu_set_tablebase_pgd() - set page table base to refer page table + * @owner: The device whose System MMU. + * @pgd: The page table base address. + * + * This function set page table base address + * When system mmu transfer address from virtaul address to physical address, + * system mmu refer address information from page table + */ +void s5p_sysmmu_set_tablebase_pgd(struct device *owner, unsigned long pgd); + +/** + * s5p_sysmmu_tlb_invalidate() - flush all TLB entry in system mmu + * @owner: The device whose System MMU. + * + * This function flush all TLB entry in system mmu + */ +void s5p_sysmmu_tlb_invalidate(struct device *owner); + +/** s5p_sysmmu_set_fault_handler() - Fault handler for System MMUs + * Called when interrupt occurred by the System MMUs + * The device drivers of peripheral devices that has a System MMU can implement + * a fault handler to resolve address translation fault by System MMU. + * The meanings of return value and parameters are described below. + + * return value: non-zero if the fault is correctly resolved. + * zero if the fault is not handled. + */ +void s5p_sysmmu_set_fault_handler(struct device *sysmmu, + s5p_sysmmu_fault_handler_t handler); + +/** s5p_sysmmu_set_prefbuf() - Initialize prefetch buffers of System MMU v3 + * @owner: The device which need to set the prefetch buffers + * @base0: The start virtual address of the area of the @owner device that the + * first prefetch buffer loads translation descriptors + * @size0: The last virtual address of the area of the @owner device that the + * first prefetch buffer loads translation descriptors. + * @base1: The start virtual address of the area of the @owner device that the + * second prefetch buffer loads translation descriptors. This will be + * ignored if @size1 is 0 and this function assigns the 2 prefetch + * buffers with each half of the area specified by @base0 and @size0 + * @size1: The last virtual address of the area of the @owner device that the + * prefetch buffer loads translation descriptors. This can be 0. See + * the description of @base1 for more information with @size1 = 0 + */ +void s5p_sysmmu_set_prefbuf(struct device *owner, + unsigned long base0, unsigned long size0, + unsigned long base1, unsigned long size1); +#else /* !CONFIG_S5P_SYSTEM_MMU */ +#define s5p_sysmmu_enable(owner, pgd) do { } while (0) +#define s5p_sysmmu_disable(owner) do { } while (0) +#define s5p_sysmmu_set_tablebase_pgd(owner, pgd) do { } while (0) +#define s5p_sysmmu_tlb_invalidate(owner) do { } while (0) +#define s5p_sysmmu_set_fault_handler(sysmmu, handler) do { } while (0) +#define s5p_sysmmu_set_prefbuf(owner, base, size) do { } while (0) +#endif +#endif /* __ASM_PLAT_SYSMMU_H */ diff --git a/arch/arm/plat-s5p/include/plat/s5p-tmu.h b/arch/arm/plat-s5p/include/plat/s5p-tmu.h new file mode 100644 index 0000000..24833ed --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/s5p-tmu.h @@ -0,0 +1,108 @@ +/* linux/arch/arm/plat-s5p/include/plat/s5p-tmu.h + * + * Copyright 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Header file for s5p tmu support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _S5P_TMU_H +#define _S5P_TMU_H + +#define TMU_SAVE_NUM 10 + +/* + * struct temperature_params have values to manange throttling, tripping + * and other software safety control + */ +struct temperature_params { + unsigned int stop_1st_throttle; + unsigned int start_1st_throttle; + unsigned int stop_2nd_throttle; + unsigned int start_2nd_throttle; + unsigned int start_tripping; /* temp to do tripping */ + unsigned int start_emergency; /* To protect chip,forcely kernel panic */ + unsigned int stop_mem_throttle; + unsigned int start_mem_throttle; + unsigned int stop_tc; /* temperature compensationfor sram */ + unsigned int start_tc; +}; + +struct cpufreq_params { + unsigned int limit_1st_throttle; + unsigned int limit_2nd_throttle; +}; + +struct temp_compensate_params { + unsigned int arm_volt; /* temperature compensated voltage */ + unsigned int bus_volt; /* temperature compensated voltage */ + unsigned int g3d_volt; /* temperature compensated voltage */ +}; + +struct memory_params { + unsigned int rclk; + unsigned int period_bank_refresh; +}; + +struct tmu_config { + unsigned char mode; + unsigned char slope; + unsigned int sampling_rate; + unsigned int monitoring_rate; +}; + +struct s5p_platform_tmu { + struct temperature_params ts; + struct cpufreq_params cpufreq; + struct temp_compensate_params temp_compensate; + struct memory_params mp; + struct tmu_config cfg; +}; + +struct s5p_tmu_info { + struct device *dev; +#ifdef CONFIG_BUSFREQ_OPP + struct device *bus_dev; +#endif + + int id; + char *s5p_name; + + void __iomem *tmu_base; + struct resource *ioarea; + int irq; + + int mode; + unsigned char te1; /* triminfo_25 */ + unsigned char te2; /* triminfo_85 */ + int slope; + + int tmu_state; + unsigned int last_temperature; + + unsigned int cpufreq_level_1st_throttle; + unsigned int cpufreq_level_2nd_throttle; + unsigned int auto_refresh_tq0; + unsigned int auto_refresh_normal; + /* temperature compensation */ + unsigned int cpulevel_tc; + unsigned int busfreq_tc; + unsigned int g3dlevel_tc; + + struct delayed_work monitor; + struct delayed_work polling; + + unsigned int monitor_period; + unsigned int sampling_rate; + unsigned int reg_save[TMU_SAVE_NUM]; +}; + +void __init s5p_tmu_set_platdata(struct s5p_platform_tmu *pd); +struct s5p_tmu *s5p_tmu_get_platdata(void); +int s5p_tmu_get_irqno(int num); +extern struct platform_device s5p_device_tmu; +#endif /* _S5P_TMU_H */ diff --git a/arch/arm/plat-s5p/include/plat/sysmmu.h b/arch/arm/plat-s5p/include/plat/sysmmu.h deleted file mode 100644 index bf5283c..0000000 --- a/arch/arm/plat-s5p/include/plat/sysmmu.h +++ /dev/null @@ -1,95 +0,0 @@ -/* linux/arch/arm/plat-s5p/include/plat/sysmmu.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Samsung System MMU driver for S5P platform - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM__PLAT_SYSMMU_H -#define __ASM__PLAT_SYSMMU_H __FILE__ - -enum S5P_SYSMMU_INTERRUPT_TYPE { - SYSMMU_PAGEFAULT, - SYSMMU_AR_MULTIHIT, - SYSMMU_AW_MULTIHIT, - SYSMMU_BUSERROR, - SYSMMU_AR_SECURITY, - SYSMMU_AR_ACCESS, - SYSMMU_AW_SECURITY, - SYSMMU_AW_PROTECTION, /* 7 */ - SYSMMU_FAULTS_NUM -}; - -#ifdef CONFIG_S5P_SYSTEM_MMU - -#include <mach/sysmmu.h> - -/** - * s5p_sysmmu_enable() - enable system mmu of ip - * @ips: The ip connected system mmu. - * #pgd: Base physical address of the 1st level page table - * - * This function enable system mmu to transfer address - * from virtual address to physical address - */ -void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd); - -/** - * s5p_sysmmu_disable() - disable sysmmu mmu of ip - * @ips: The ip connected system mmu. - * - * This function disable system mmu to transfer address - * from virtual address to physical address - */ -void s5p_sysmmu_disable(sysmmu_ips ips); - -/** - * s5p_sysmmu_set_tablebase_pgd() - set page table base address to refer page table - * @ips: The ip connected system mmu. - * @pgd: The page table base address. - * - * This function set page table base address - * When system mmu transfer address from virtaul address to physical address, - * system mmu refer address information from page table - */ -void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd); - -/** - * s5p_sysmmu_tlb_invalidate() - flush all TLB entry in system mmu - * @ips: The ip connected system mmu. - * - * This function flush all TLB entry in system mmu - */ -void s5p_sysmmu_tlb_invalidate(sysmmu_ips ips); - -/** s5p_sysmmu_set_fault_handler() - Fault handler for System MMUs - * @itype: type of fault. - * @pgtable_base: the physical address of page table base. This is 0 if @ips is - * SYSMMU_BUSERROR. - * @fault_addr: the device (virtual) address that the System MMU tried to - * translated. This is 0 if @ips is SYSMMU_BUSERROR. - * Called when interrupt occurred by the System MMUs - * The device drivers of peripheral devices that has a System MMU can implement - * a fault handler to resolve address translation fault by System MMU. - * The meanings of return value and parameters are described below. - - * return value: non-zero if the fault is correctly resolved. - * zero if the fault is not handled. - */ -void s5p_sysmmu_set_fault_handler(sysmmu_ips ips, - int (*handler)(enum S5P_SYSMMU_INTERRUPT_TYPE itype, - unsigned long pgtable_base, - unsigned long fault_addr)); -#else -#define s5p_sysmmu_enable(ips, pgd) do { } while (0) -#define s5p_sysmmu_disable(ips) do { } while (0) -#define s5p_sysmmu_set_tablebase_pgd(ips, pgd) do { } while (0) -#define s5p_sysmmu_tlb_invalidate(ips) do { } while (0) -#define s5p_sysmmu_set_fault_handler(ips, handler) do { } while (0) -#endif -#endif /* __ASM_PLAT_SYSMMU_H */ diff --git a/arch/arm/plat-s5p/include/plat/system-reset.h b/arch/arm/plat-s5p/include/plat/system-reset.h index f307f34..9e0a095 100644 --- a/arch/arm/plat-s5p/include/plat/system-reset.h +++ b/arch/arm/plat-s5p/include/plat/system-reset.h @@ -12,20 +12,6 @@ * published by the Free Software Foundation. */ -#include <plat/watchdog-reset.h> +extern void (*s5p_reset_hook)(void); -void (*s5p_reset_hook)(void); - -static void arch_reset(char mode, const char *cmd) -{ - /* SWRESET support in s5p_reset_hook() */ - - if (s5p_reset_hook) - s5p_reset_hook(); - - /* Perform reset using Watchdog reset - * if there is no s5p_reset_hook() - */ - - arch_wdt_reset(); -} +void arch_reset(char mode, const char *cmd); diff --git a/arch/arm/plat-s5p/include/plat/tvout.h b/arch/arm/plat-s5p/include/plat/tvout.h new file mode 100644 index 0000000..e649d69 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/tvout.h @@ -0,0 +1,49 @@ +/* linux/arch/arm/plat-s5p/include/plat/tvout.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Platform Header file for Samsung TV driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ARM_PLAT_TVOUT_H +#define __ARM_PLAT_TVOUT_H __FILE__ + +struct platform_device; + +struct s5p_platform_hpd { + void (*int_src_hdmi_hpd)(struct platform_device *pdev); + void (*int_src_ext_hpd)(struct platform_device *pdev); + int (*read_gpio)(struct platform_device *pdev); +#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC + void (*ext_ic_control)(bool ic_on); +#endif +}; + +extern void s5p_hdmi_hpd_set_platdata(struct s5p_platform_hpd *pd); + +/* defined by architecture to configure gpio */ +extern void s5p_int_src_hdmi_hpd(struct platform_device *pdev); +extern void s5p_int_src_ext_hpd(struct platform_device *pdev); +extern void s5p_v4l2_int_src_hdmi_hpd(void); +extern void s5p_v4l2_int_src_ext_hpd(void); +extern int s5p_hpd_read_gpio(struct platform_device *pdev); +extern int s5p_v4l2_hpd_read_gpio(void); + +struct s5p_platform_cec { + + void (*cfg_gpio)(struct platform_device *pdev); +}; + +extern void s5p_hdmi_cec_set_platdata(struct s5p_platform_cec *pd); + +/* defined by architecture to configure gpio */ +extern void s5p_cec_cfg_gpio(struct platform_device *pdev); + +extern void s5p_tv_setup(void); + +#endif /* __ASM_PLAT_TV_HPD_H */ diff --git a/arch/arm/plat-s5p/include/plat/usb-phy.h b/arch/arm/plat-s5p/include/plat/usb-phy.h index 6dd6bcf..9cd61e6 100644 --- a/arch/arm/plat-s5p/include/plat/usb-phy.h +++ b/arch/arm/plat-s5p/include/plat/usb-phy.h @@ -14,9 +14,22 @@ enum s5p_usb_phy_type { S5P_USB_PHY_DEVICE, S5P_USB_PHY_HOST, + S5P_USB_PHY_DRD, + S5P_USB_PHY_OTGHOST, }; +#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) || \ + defined(CONFIG_CDMA_MODEM_MDM6600) +enum s5p_host_state { + S5P_HOST_OFF, + S5P_HOST_ON, +}; +#endif + extern int s5p_usb_phy_init(struct platform_device *pdev, int type); extern int s5p_usb_phy_exit(struct platform_device *pdev, int type); +extern int s5p_usb_phy_suspend(struct platform_device *pdev, int type); +extern int s5p_usb_phy_resume(struct platform_device *pdev, int type); +extern int exynos4_check_usb_op(void); #endif /* __PLAT_S5P_REGS_USB_PHY_H */ diff --git a/arch/arm/plat-s5p/include/plat/usb-switch.h b/arch/arm/plat-s5p/include/plat/usb-switch.h new file mode 100644 index 0000000..f15d24e --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/usb-switch.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim <jy0922.shim@samsung.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __PLAT_S5P_USB_SWITCH_H +#define __PLAT_S5P_USB_SWITCH_H + +struct s5p_usbswitch_platdata { + unsigned gpio_host_detect; + unsigned gpio_device_detect; + unsigned gpio_host_vbus; + unsigned gpio_drd_host_detect; + unsigned gpio_drd_device_detect; + + struct device *ehci_dev; + struct device *ohci_dev; + struct device *xhci_dev; + + struct device *s3c_udc_dev; + struct device *exynos_udc_dev; +}; + +extern void s5p_usbswitch_set_platdata(struct s5p_usbswitch_platdata *pd); +#endif /* __PLAT_S5P_USB_SWITCH_H */ diff --git a/arch/arm/plat-s5p/include/plat/usbgadget.h b/arch/arm/plat-s5p/include/plat/usbgadget.h new file mode 100644 index 0000000..65bd8cf --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/usbgadget.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2011 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim <jy0922.shim@samsung.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __PLAT_S5P_USBGADGET_H +#define __PLAT_S5P_USBGADGET_H + +struct s5p_usbgadget_platdata { + int (*phy_init)(struct platform_device *pdev, int type); + int (*phy_exit)(struct platform_device *pdev, int type); + +#ifdef CONFIG_USB_S3C_OTG_HOST + irqreturn_t (*udc_irq)(int irq, void *_dev); +#endif + /* Value of USB PHY tune register */ + unsigned int phy_tune; + /* Mask of USB PHY tune register */ + unsigned int phy_tune_mask; +}; + +extern void s5p_usbgadget_set_platdata(struct s5p_usbgadget_platdata *pd); + +#endif /* __PLAT_S5P_EHCI_H */ diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c index b5bb774..2f08070 100644 --- a/arch/arm/plat-s5p/irq-eint.c +++ b/arch/arm/plat-s5p/irq-eint.c @@ -65,6 +65,7 @@ static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type) int shift; u32 ctrl, mask; u32 newvalue = 0; + struct irq_desc *desc = irq_to_desc(data->irq); switch (type) { case IRQ_TYPE_EDGE_RISING: @@ -115,6 +116,11 @@ static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type) else printk(KERN_ERR "No such irq number %d", offs); + if (type & IRQ_TYPE_EDGE_BOTH) + desc->handle_irq = handle_edge_irq; + else + desc->handle_irq = handle_level_irq; + return 0; } @@ -123,6 +129,7 @@ static struct irq_chip s5p_irq_eint = { .irq_mask = s5p_irq_eint_mask, .irq_unmask = s5p_irq_eint_unmask, .irq_mask_ack = s5p_irq_eint_maskack, + .irq_disable = s5p_irq_eint_maskack, .irq_ack = s5p_irq_eint_ack, .irq_set_type = s5p_irq_eint_set_type, #ifdef CONFIG_PM @@ -138,11 +145,12 @@ static struct irq_chip s5p_irq_eint = { * * Each EINT pend/mask registers handle eight of them. */ -static inline void s5p_irq_demux_eint(unsigned int start) +static inline u32 s5p_irq_demux_eint(unsigned int start) { u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); unsigned int irq; + u32 action = 0; status &= ~mask; status &= 0xff; @@ -151,13 +159,21 @@ static inline void s5p_irq_demux_eint(unsigned int start) irq = fls(status) - 1; generic_handle_irq(irq + start); status &= ~(1 << irq); + ++action; } + + return action; } static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) { - s5p_irq_demux_eint(IRQ_EINT(16)); - s5p_irq_demux_eint(IRQ_EINT(24)); + u32 a16_23, a24_31; + + a16_23 = s5p_irq_demux_eint(IRQ_EINT(16)); + a24_31 = s5p_irq_demux_eint(IRQ_EINT(24)); + + if (!a16_23 && !a24_31) + do_bad_IRQ(irq, desc); } static inline void s5p_irq_vic_eint_mask(struct irq_data *data) diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c index 327ab9f..06c6bfb 100644 --- a/arch/arm/plat-s5p/irq-gpioint.c +++ b/arch/arm/plat-s5p/irq-gpioint.c @@ -22,6 +22,10 @@ #include <mach/map.h> #include <plat/gpio-core.h> #include <plat/gpio-cfg.h> +#include <plat/cpu.h> + +#include <asm/mach/irq.h> +#include <mach/regs-gpio.h> #define GPIO_BASE(chip) (((unsigned long)(chip)->base) & 0xFFFFF000u) @@ -46,22 +50,25 @@ static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type) struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct irq_chip_type *ct = gc->chip_types; unsigned int shift = (d->irq - gc->irq_base) << 2; + struct irq_desc *desc = irq_to_desc(d->irq); + unsigned int type_s5p = 0; + struct s3c_gpio_chip *chip = gc->private; switch (type) { case IRQ_TYPE_EDGE_RISING: - type = S5P_IRQ_TYPE_EDGE_RISING; + type_s5p = S5P_IRQ_TYPE_EDGE_RISING; break; case IRQ_TYPE_EDGE_FALLING: - type = S5P_IRQ_TYPE_EDGE_FALLING; + type_s5p = S5P_IRQ_TYPE_EDGE_FALLING; break; case IRQ_TYPE_EDGE_BOTH: - type = S5P_IRQ_TYPE_EDGE_BOTH; + type_s5p = S5P_IRQ_TYPE_EDGE_BOTH; break; case IRQ_TYPE_LEVEL_HIGH: - type = S5P_IRQ_TYPE_LEVEL_HIGH; + type_s5p = S5P_IRQ_TYPE_LEVEL_HIGH; break; case IRQ_TYPE_LEVEL_LOW: - type = S5P_IRQ_TYPE_LEVEL_LOW; + type_s5p = S5P_IRQ_TYPE_LEVEL_LOW; break; case IRQ_TYPE_NONE: default: @@ -70,29 +77,45 @@ static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type) } gc->type_cache &= ~(0x7 << shift); - gc->type_cache |= type << shift; + gc->type_cache |= type_s5p << shift; writel(gc->type_cache, gc->reg_base + ct->regs.type); + + pr_info("%s irq:%d is at %s(%d)\n", __func__, d->irq, chip->chip.label, + (d->irq - chip->irq_base)); + + s3c_gpio_cfgpin(chip->chip.base + (d->irq - chip->irq_base), EINT_MODE); + + if (type & IRQ_TYPE_EDGE_BOTH) + desc->handle_irq = handle_edge_irq; + else + desc->handle_irq = handle_level_irq; + return 0; } static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) { struct s5p_gpioint_bank *bank = irq_get_handler_data(irq); - int group, pend_offset, mask_offset; - unsigned int pend, mask; + int group, eint_offset; + unsigned int pend, mask, action = 0; + + struct irq_chip *chip = irq_get_chip(irq); + chained_irq_enter(chip, desc); for (group = 0; group < bank->nr_groups; group++) { struct s3c_gpio_chip *chip = bank->chips[group]; if (!chip) continue; - - pend_offset = REG_OFFSET(group); - pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset); + if (soc_is_exynos4210() || soc_is_exynos4212() + || soc_is_exynos4412() + || soc_is_exynos5250()) + eint_offset = chip->eint_offset; + else + eint_offset = REG_OFFSET(group); + pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + eint_offset); if (!pend) continue; - - mask_offset = REG_OFFSET(group); - mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset); + mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + eint_offset); pend &= ~mask; while (pend) { @@ -100,28 +123,38 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) int real_irq = chip->irq_base + offset; generic_handle_irq(real_irq); pend &= ~BIT(offset); + ++action; } } + chained_irq_exit(chip, desc); + + if (!action) + do_bad_IRQ(irq, desc); } static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip) { static int used_gpioint_groups = 0; int group = chip->group; - struct s5p_gpioint_bank *bank = NULL; + struct s5p_gpioint_bank *b, *bank = NULL; struct irq_chip_generic *gc; struct irq_chip_type *ct; - if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT) + if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT) { + WARN(1, "used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT\n"); return -ENOMEM; + } - list_for_each_entry(bank, &banks, list) { - if (group >= bank->start && - group < bank->start + bank->nr_groups) + list_for_each_entry(b, &banks, list) { + if (group >= b->start && group < b->start + b->nr_groups) { + bank = b; break; + } } - if (!bank) + if (!bank) { + WARN(1, "bank not found\n"); return -EINVAL; + } if (!bank->handler) { bank->chips = kzalloc(sizeof(struct s3c_gpio_chip *) * @@ -149,16 +182,29 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip) gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base, (void __iomem *)GPIO_BASE(chip), handle_level_irq); - if (!gc) + if (!gc) { + WARN(1, "irq_alloc_generic_chip failed\n"); return -ENOMEM; + } + + gc->private = chip; + ct = gc->chip_types; ct->chip.irq_ack = irq_gc_ack_set_bit; ct->chip.irq_mask = irq_gc_mask_set_bit; ct->chip.irq_unmask = irq_gc_mask_clr_bit; - ct->chip.irq_set_type = s5p_gpioint_set_type, - ct->regs.ack = PEND_OFFSET + REG_OFFSET(chip->group); - ct->regs.mask = MASK_OFFSET + REG_OFFSET(chip->group); - ct->regs.type = CON_OFFSET + REG_OFFSET(chip->group); + ct->chip.irq_disable = irq_gc_mask_and_ack_set; + ct->chip.irq_set_type = s5p_gpioint_set_type; + if (soc_is_exynos4210() || soc_is_exynos4212() || soc_is_exynos4412() + || soc_is_exynos5250()) { + ct->regs.ack = PEND_OFFSET + chip->eint_offset; + ct->regs.mask = MASK_OFFSET + chip->eint_offset; + ct->regs.type = CON_OFFSET + chip->eint_offset; + } else { + ct->regs.ack = PEND_OFFSET + REG_OFFSET(chip->group); + ct->regs.mask = MASK_OFFSET + REG_OFFSET(chip->group); + ct->regs.type = CON_OFFSET + REG_OFFSET(chip->group); + } irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio), IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST | IRQ_NOPROBE, 0); @@ -189,6 +235,7 @@ int __init s5p_register_gpio_interrupt(int pin) group); return my_chip->irq_base + offset; } + return ret; } diff --git a/arch/arm/plat-s5p/reserve_mem.c b/arch/arm/plat-s5p/reserve_mem.c new file mode 100644 index 0000000..5b91823 --- /dev/null +++ b/arch/arm/plat-s5p/reserve_mem.c @@ -0,0 +1,307 @@ +/* linux/arch/arm/plat-s5p/reserve_mem.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Reserve mem helper functions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/err.h> +#include <linux/memblock.h> +#include <linux/mm.h> +#include <linux/swap.h> +#include <asm/setup.h> +#include <linux/io.h> +#include <mach/memory.h> +#include <plat/media.h> +#include <mach/media.h> + +#ifdef CONFIG_CMA +#include <linux/cma.h> +void __init s5p_cma_region_reserve(struct cma_region *regions_normal, + struct cma_region *regions_secure, + size_t align_secure, const char *map) +{ + struct cma_region *reg; + phys_addr_t paddr_last = 0xFFFFFFFF; + + for (reg = regions_normal; reg->size != 0; reg++) { + phys_addr_t paddr; + + if (!IS_ALIGNED(reg->size, PAGE_SIZE)) { + pr_debug("S5P/CMA: size of '%s' is NOT page-aligned\n", + reg->name); + reg->size = PAGE_ALIGN(reg->size); + } + + + if (reg->reserved) { + pr_err("S5P/CMA: '%s' already reserved\n", reg->name); + continue; + } + + if (reg->alignment) { + if ((reg->alignment & ~PAGE_MASK) || + (reg->alignment & ~reg->alignment)) { + pr_err("S5P/CMA: Failed to reserve '%s': " + "incorrect alignment 0x%08x.\n", + reg->name, reg->alignment); + continue; + } + } else { + reg->alignment = PAGE_SIZE; + } + + if (reg->start) { + if (!memblock_is_region_reserved(reg->start, reg->size) + && (memblock_reserve(reg->start, reg->size) == 0)) + reg->reserved = 1; + else { + pr_err("S5P/CMA: Failed to reserve '%s'\n", + reg->name); + continue; + } + + pr_debug("S5P/CMA: " + "Reserved 0x%08x/0x%08x for '%s'\n", + reg->start, reg->size, reg->name); + paddr = reg->start; + } else { + paddr = memblock_find_in_range(0, + MEMBLOCK_ALLOC_ACCESSIBLE, + reg->size, reg->alignment); + } + + if (paddr != MEMBLOCK_ERROR) { + if (memblock_reserve(paddr, reg->size)) { + pr_err("S5P/CMA: Failed to reserve '%s'\n", + reg->name); + continue; + } + + reg->start = paddr; + reg->reserved = 1; + + pr_debug("S5P/CMA: Reserved 0x%08x/0x%08x for '%s'\n", + reg->start, reg->size, reg->name); + } else { + pr_err("S5P/CMA: No free space in memory for '%s'\n", + reg->name); + } + + if (cma_early_region_register(reg)) { + pr_err("S5P/CMA: Failed to register '%s'\n", + reg->name); + memblock_free(reg->start, reg->size); + } else { + paddr_last = min(paddr, paddr_last); + } + } + + if (align_secure & ~align_secure) { + pr_err("S5P/CMA: " + "Wrong alignment requirement for secure region.\n"); + } else if (regions_secure && regions_secure->size) { + size_t size_secure = 0; + + for (reg = regions_secure; reg->size != 0; reg++) + size_secure += reg->size; + + reg--; + + /* Entire secure regions will be merged into 2 + * consecutive regions. */ + if (align_secure == 0) { + size_t size_region2; + size_t order_region2; + size_t aug_size; + + align_secure = 1 << + (get_order((size_secure + 1) / 2) + PAGE_SHIFT); + /* Calculation of a subregion size */ + size_region2 = size_secure - align_secure; + order_region2 = get_order(size_region2) + PAGE_SHIFT; + if (order_region2 < 20) + order_region2 = 20; /* 1MB */ + order_region2 -= 3; /* divide by 8 */ + size_region2 = ALIGN(size_region2, 1 << order_region2); + + aug_size = align_secure + size_region2 - size_secure; + if (aug_size > 0) { + reg->size += aug_size; + size_secure += aug_size; + pr_debug("S5P/CMA: " + "Augmented size of '%s' by %#x B.\n", + reg->name, aug_size); + } + } else + size_secure = ALIGN(size_secure, align_secure); + + pr_debug("S5P/CMA: " + "Reserving %#x for secure region aligned by %#x.\n", + size_secure, align_secure); + + if (paddr_last >= memblock.current_limit) { + paddr_last = memblock_find_in_range(0, + MEMBLOCK_ALLOC_ACCESSIBLE, + size_secure, reg->alignment); + } else { + paddr_last -= size_secure; + paddr_last = round_down(paddr_last, align_secure); + } + + if (paddr_last) { + while (memblock_reserve(paddr_last, size_secure)) + paddr_last -= align_secure; + + do { + reg->start = paddr_last; + reg->reserved = 1; + paddr_last += reg->size; + + pr_info("S5P/CMA: " + "Reserved 0x%08x/0x%08x for '%s'\n", + reg->start, reg->size, reg->name); + if (cma_early_region_register(reg)) { + memblock_free(reg->start, reg->size); + pr_err("S5P/CMA: " + "Failed to register secure region " + "'%s'\n", reg->name); + } else { + size_secure -= reg->size; + } + } while (reg-- != regions_secure); + + if (size_secure > 0) + memblock_free(paddr_last, size_secure); + } else { + pr_err("S5P/CMA: Failed to reserve secure regions\n"); + } + } + + if (map) + cma_set_defaults(NULL, map); +} + +#else +extern struct s5p_media_device media_devs[]; +extern int nr_media_devs; + +static dma_addr_t media_base[NR_BANKS]; + +static struct s5p_media_device *s5p_get_media_device(int dev_id, int bank) +{ + struct s5p_media_device *mdev = NULL; + int i = 0, found = 0; + + if (dev_id < 0) + return NULL; + + while (!found && (i < nr_media_devs)) { + mdev = &media_devs[i]; + if (mdev->id == dev_id && mdev->bank == bank) + found = 1; + else + i++; + } + + if (!found) + mdev = NULL; + + return mdev; +} + +dma_addr_t s5p_get_media_memory_bank(int dev_id, int bank) +{ + struct s5p_media_device *mdev; + + mdev = s5p_get_media_device(dev_id, bank); + if (!mdev) { + printk(KERN_ERR "invalid media device\n"); + return 0; + } + + if (!mdev->paddr) { + printk(KERN_ERR "no memory for %s\n", mdev->name); + return 0; + } + + return mdev->paddr; +} +EXPORT_SYMBOL(s5p_get_media_memory_bank); + +size_t s5p_get_media_memsize_bank(int dev_id, int bank) +{ + struct s5p_media_device *mdev; + + mdev = s5p_get_media_device(dev_id, bank); + if (!mdev) { + printk(KERN_ERR "invalid media device\n"); + return 0; + } + + return mdev->memsize; +} +EXPORT_SYMBOL(s5p_get_media_memsize_bank); + +dma_addr_t s5p_get_media_membase_bank(int bank) +{ + if (bank > meminfo.nr_banks) { + printk(KERN_ERR "invalid bank.\n"); + return -EINVAL; + } + + return media_base[bank]; +} +EXPORT_SYMBOL(s5p_get_media_membase_bank); + +void s5p_reserve_mem(size_t boundary) +{ + struct s5p_media_device *mdev; + u64 start, end; + int i, ret; + + for (i = 0; i < meminfo.nr_banks; i++) + media_base[i] = meminfo.bank[i].start + meminfo.bank[i].size; + + for (i = 0; i < nr_media_devs; i++) { + mdev = &media_devs[i]; + if (mdev->memsize <= 0) + continue; + + if (mdev->bank > meminfo.nr_banks) { + pr_err("mdev %s: mdev->bank(%d), max_bank(%d)\n", + mdev->name, mdev->bank, meminfo.nr_banks); + return; + } + + if (!mdev->paddr) { + start = meminfo.bank[mdev->bank].start; + end = start + meminfo.bank[mdev->bank].size; + + if (boundary && (boundary < end - start)) + start = end - boundary; + + mdev->paddr = memblock_find_in_range(start, end, + mdev->memsize, PAGE_SIZE); + } + + ret = memblock_reserve(mdev->paddr, mdev->memsize); + if (ret < 0) + pr_err("memblock_reserve(%x, %x) failed\n", + mdev->paddr, mdev->memsize); + + if (media_base[mdev->bank] > mdev->paddr) + media_base[mdev->bank] = mdev->paddr; + + printk(KERN_INFO "s5p: %lu bytes system memory reserved " + "for %s at 0x%08x, %d-bank base(0x%08x)\n", + (unsigned long) mdev->memsize, mdev->name, mdev->paddr, + mdev->bank, media_base[mdev->bank]); + } +} +#endif /* CONFIG_CMA */ diff --git a/arch/arm/plat-s5p/reset.c b/arch/arm/plat-s5p/reset.c new file mode 100644 index 0000000..96dfdab --- /dev/null +++ b/arch/arm/plat-s5p/reset.c @@ -0,0 +1,33 @@ +/* linux/arch/arm/plat-s5p/include/plat/system-reset.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Based on arch/arm/mach-s3c2410/include/mach/system-reset.h + * + * S5P - System define for arch_reset() + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <plat/system-reset.h> +#include <plat/watchdog-reset.h> + + +void (*s5p_reset_hook)(void); + +void arch_reset(char mode, const char *cmd) +{ + /* SWRESET support in s5p_reset_hook() */ + + if (s5p_reset_hook) + s5p_reset_hook(); + + /* Perform reset using Watchdog reset + * if there is no s5p_reset_hook() + */ + + arch_wdt_reset(); +} diff --git a/arch/arm/plat-s5p/s5p-sysmmu.c b/arch/arm/plat-s5p/s5p-sysmmu.c new file mode 100644 index 0000000..dae74e1 --- /dev/null +++ b/arch/arm/plat-s5p/s5p-sysmmu.c @@ -0,0 +1,582 @@ +/* linux/arch/arm/plat-s5p/sysmmu.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifdef CONFIG_S5P_SYSTEM_MMU_DEBUG +#define DEBUG +#endif + +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/pm_runtime.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/mm.h> + +#include <asm/pgtable.h> + +#include <mach/map.h> +#include <mach/regs-sysmmu.h> + +#include <plat/s5p-sysmmu.h> + +#define CTRL_ENABLE 0x5 +#define CTRL_BLOCK 0x7 +#define CTRL_DISABLE 0x0 + +static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = { + S5P_PAGE_FAULT_ADDR, + S5P_AR_FAULT_ADDR, + S5P_AW_FAULT_ADDR, + S5P_DEFAULT_SLAVE_ADDR, + S5P_AR_FAULT_ADDR, + S5P_AR_FAULT_ADDR, + S5P_AW_FAULT_ADDR, + S5P_AW_FAULT_ADDR +}; + +static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = { + "PAGE FAULT", + "AR MULTI-HIT FAULT", + "AW MULTI-HIT FAULT", + "BUS ERROR", + "AR SECURITY PROTECTION FAULT", + "AR ACCESS PROTECTION FAULT", + "AW SECURITY PROTECTION FAULT", + "AW ACCESS PROTECTION FAULT", + "UNKNOWN FAULT" +}; + +struct sysmmu_drvdata { + struct list_head node; + struct device *dev; + struct device *owner; + void __iomem *sfrbase; + struct clk *clk; + int activations; + rwlock_t lock; + s5p_sysmmu_fault_handler_t fault_handler; + unsigned long version; +}; + +static LIST_HEAD(sysmmu_list); + +static struct sysmmu_drvdata *get_sysmmu_data(struct device *owner, + struct sysmmu_drvdata *start) +{ + if (start) { + list_for_each_entry_continue(start, &sysmmu_list, node) + if (start->owner == owner) + return start; + } else { + list_for_each_entry(start, &sysmmu_list, node) + if (start->owner == owner) + return start; + } + + return NULL; +} + +static struct sysmmu_drvdata *get_sysmmu_data_rollback(struct device *owner, + struct sysmmu_drvdata *start) +{ + if (start) { + list_for_each_entry_continue_reverse(start, &sysmmu_list, node) + if (start->owner == owner) + return start; + } + + return NULL; +} + +static int set_sysmmu_active(struct sysmmu_drvdata *mmudata) +{ +#ifndef CONFIG_S5P_SYSTEM_MMU_REFCOUNT + if (WARN_ON(mmudata->activations == 1)) + return -EBUSY; +#endif + mmudata->activations++; + + return 0; +} + +static bool is_sysmmu_active(struct sysmmu_drvdata *mmudata) +{ + return mmudata->activations != 0; +} + +static bool set_sysmmu_inactive(struct sysmmu_drvdata *mmudata) +{ + /* return true if the System MMU is needed to be disabled */ + if (WARN_ON(!is_sysmmu_active(mmudata))) + return false; + + mmudata->activations--; + + return !is_sysmmu_active(mmudata); +} + +#ifdef CONFIG_S5P_SYSTEM_MMU_REFCOUNT +static bool need_sysmmu_initialize(struct sysmmu_drvdata *mmudata) +{ + return mmudata->activations == 1; +} +#else +#define need_sysmmu_initialize is_sysmmu_active +#endif + +static void sysmmu_block(void __iomem *sfrbase) +{ + __raw_writel(CTRL_BLOCK, sfrbase + S5P_MMU_CTRL); +} + +static void sysmmu_unblock(void __iomem *sfrbase) +{ + __raw_writel(CTRL_ENABLE, sfrbase + S5P_MMU_CTRL); +} + +static void __sysmmu_tlb_invalidate(void __iomem *sfrbase) +{ + __raw_writel(0x1, sfrbase + S5P_MMU_FLUSH); +} + +static void __sysmmu_set_ptbase(void __iomem *sfrbase, + unsigned long pgd) +{ + if (unlikely(pgd == 0)) { + pgd = page_to_phys(ZERO_PAGE(0)); + __raw_writel(0x20, sfrbase + S5P_MMU_CFG); /* 4KB LV1 */ + } else { + __raw_writel(0x0, sfrbase + S5P_MMU_CFG); /* 16KB LV1 */ + } + + __raw_writel(pgd, sfrbase + S5P_PT_BASE_ADDR); + + __sysmmu_tlb_invalidate(sfrbase); +} + +static void __sysmmu_set_prefbuf(void __iomem *sfrbase, unsigned long base, + unsigned long size, int idx) +{ + __raw_writel(base, sfrbase + S5P_PB0_SADDR + idx * 8); + __raw_writel(size - 1 + base, sfrbase + S5P_PB0_EADDR + idx * 8); +} + +void s5p_sysmmu_set_prefbuf(struct device *owner, + unsigned long base0, unsigned long size0, + unsigned long base1, unsigned long size1) +{ + struct sysmmu_drvdata *data = NULL; + unsigned long flags; + + BUG_ON((base0 + (size0 - 1)) <= base0); + BUG_ON((base1 + (size1 - 1)) <= base1); + + while ((data = get_sysmmu_data(owner, data))) { + if (WARN_ON(data->version != 3)) + continue; + + read_lock_irqsave(&data->lock, flags); + if (is_sysmmu_active(data)) { + sysmmu_block(data->sfrbase); + + if (size1 == 0) { + if (size0 <= SZ_128K) { + base1 = base0; + size1 = size0; + } else { + size1 = size0 - + ALIGN(size0 / 2, SZ_64K); + size0 = size0 - size1; + base1 = base0 + size0; + } + } + + __sysmmu_set_prefbuf(data->sfrbase, base0, size0, 0); + __sysmmu_set_prefbuf(data->sfrbase, base1, size1, 1); + + sysmmu_unblock(data->sfrbase); + } + read_unlock_irqrestore(&data->lock, flags); + } +} + +static void __set_fault_handler(struct sysmmu_drvdata *mmudata, + s5p_sysmmu_fault_handler_t handler) +{ + unsigned long flags; + + write_lock_irqsave(&mmudata->lock, flags); + mmudata->fault_handler = handler; + write_unlock_irqrestore(&mmudata->lock, flags); +} + +void s5p_sysmmu_set_fault_handler(struct device *owner, + s5p_sysmmu_fault_handler_t handler) +{ + struct sysmmu_drvdata *data = NULL; + + while ((data = get_sysmmu_data(owner, data))) + __set_fault_handler(data, handler); +} + +static int default_fault_handler(enum S5P_SYSMMU_INTERRUPT_TYPE itype, + unsigned long pgtable_base, + unsigned long fault_addr) +{ + unsigned long *ent; + + if ((itype >= SYSMMU_FAULTS_NUM) || (itype < SYSMMU_PAGEFAULT)) + itype = SYSMMU_FAULT_UNKNOWN; + + pr_err("%s occured at 0x%lx(Page table base: 0x%lx)\n", + sysmmu_fault_name[itype], fault_addr, pgtable_base); + + pgtable_base += ((fault_addr & 0xFFF00000) >> 20) * 4; + + ent = page_address(phys_to_page(pgtable_base)); + ent += offset_in_page(pgtable_base) / sizeof(unsigned long) ; + + if (likely(ent != NULL)) { + pr_err("\tLv1 entry: 0x%lx\n", *ent); + + if ((*ent & 0x3) == 0x1) { + pgtable_base = *ent & ~0x3FF; + ent = page_address(phys_to_page(pgtable_base)); + + if (likely(ent != NULL)) { + ent += offset_in_page(pgtable_base) / + sizeof(unsigned long); + ent += (fault_addr & 0xFF000) >> 12; + pr_err("\tLv2 entry: 0x%lx\n", *ent); + } + } + } + + pr_err("\t\tGenerating Kernel OOPS... because it is unrecoverable.\n"); + + BUG(); + + return 0; +} + +static irqreturn_t s5p_sysmmu_irq(int irq, void *dev_id) +{ + /* SYSMMU is in blocked when interrupt occurred. */ + unsigned long base = 0; + struct sysmmu_drvdata *mmudata = dev_id; + enum S5P_SYSMMU_INTERRUPT_TYPE itype; + + read_lock(&mmudata->lock); + + WARN_ON(!is_sysmmu_active(mmudata)); + + itype = (enum S5P_SYSMMU_INTERRUPT_TYPE) + __ffs(__raw_readl(mmudata->sfrbase + S5P_INT_STATUS)); + + BUG_ON(!((itype >= 0) && (itype < 8))); + + if (mmudata->fault_handler) { + unsigned long addr; + + base = __raw_readl(mmudata->sfrbase + S5P_PT_BASE_ADDR); + addr = __raw_readl(mmudata->sfrbase + fault_reg_offset[itype]); + + dev_dbg(mmudata->dev, "System MMU %s occurred by %s\n", + sysmmu_fault_name[itype], dev_name(mmudata->owner)); + + if ((mmudata->version == 3) && ((itype == SYSMMU_AR_MULTIHIT) || + (itype == SYSMMU_AW_MULTIHIT))) { + __sysmmu_tlb_invalidate(mmudata->sfrbase); + } else if (mmudata->fault_handler(itype, base, addr) != 0) { + dev_dbg(mmudata->dev, + "%s is resolved. Retrying translation.\n", + sysmmu_fault_name[itype]); + } else { + base = 0; + } + + __raw_writel(1 << itype, mmudata->sfrbase + S5P_INT_CLEAR); + } + + sysmmu_unblock(mmudata->sfrbase); + + read_unlock(&mmudata->lock); + + if (!base) + dev_notice(mmudata->dev, "%s is not handled.\n", + sysmmu_fault_name[itype]); + + return IRQ_HANDLED; +} + +void s5p_sysmmu_set_tablebase_pgd(struct device *owner, unsigned long pgd) +{ + struct sysmmu_drvdata *mmudata = NULL; + + while ((mmudata = get_sysmmu_data(owner, mmudata))) { + unsigned long flags; + + read_lock_irqsave(&mmudata->lock, flags); + + if (is_sysmmu_active(mmudata)) { + sysmmu_block(mmudata->sfrbase); + __sysmmu_set_ptbase(mmudata->sfrbase, pgd); + sysmmu_unblock(mmudata->sfrbase); + dev_dbg(mmudata->dev, "New page table base is %p\n", + (void *)pgd); + } else { + dev_dbg(mmudata->dev, + "Disabled: Skipping setting page table base.\n"); + } + + read_unlock_irqrestore(&mmudata->lock, flags); + } +} + +static bool __sysmmu_disable(struct sysmmu_drvdata *data) +{ + unsigned long flags; + bool disabled = false; + + write_lock_irqsave(&data->lock, flags); + + if (set_sysmmu_inactive(data)) { + __raw_writel(CTRL_DISABLE, data->sfrbase + S5P_MMU_CTRL); + if (data->clk) + clk_disable(data->clk); + disabled = true; + } + + write_unlock_irqrestore(&data->lock, flags); + +#ifndef CONFIG_S5P_SYSTEM_MMU_REFCOUNT + if (disabled) +#endif + pm_runtime_put_sync(data->dev); + + return disabled; +} + +int s5p_sysmmu_enable(struct device *owner, unsigned long pgd) +{ + unsigned long flags; + struct sysmmu_drvdata *mmudata = NULL; + int ret = -ENODEV; + + /* There are some devices that control more System MMUs than one such + * as MFC. + */ + while ((mmudata = get_sysmmu_data(owner, mmudata))) { + ret = pm_runtime_get_sync(mmudata->dev); + if (ret < 0) + break; + + write_lock_irqsave(&mmudata->lock, flags); + + ret = set_sysmmu_active(mmudata); + if (!ret && need_sysmmu_initialize(mmudata)) { + if (mmudata->clk) + clk_enable(mmudata->clk); + + __sysmmu_set_ptbase(mmudata->sfrbase, pgd); + + if (mmudata->version == 0) { + + mmudata->version = readl( + mmudata->sfrbase + S5P_MMU_VERSION); + mmudata->version >>= 28; + } + + if (mmudata->version == 3) { + __raw_writel((1 << 12) | (2 << 28), + mmudata->sfrbase + S5P_MMU_CFG); + __sysmmu_set_prefbuf(mmudata->sfrbase, + 0, -1, 0); + __sysmmu_set_prefbuf(mmudata->sfrbase, + 0, -1, 1); + } + + __raw_writel(CTRL_ENABLE, + mmudata->sfrbase + S5P_MMU_CTRL); + + dev_dbg(mmudata->dev, "Enabled.\n"); + } else { + dev_dbg(mmudata->dev, "Already enabled.\n"); + } + + write_unlock_irqrestore(&mmudata->lock, flags); + + if (ret) /* already enabled and no refcount */ + pm_runtime_put_sync(mmudata->dev); + } + + if (ret < 0) { + while ((mmudata = get_sysmmu_data_rollback(owner, mmudata))) { + __sysmmu_disable(mmudata); + + dev_dbg(mmudata->dev, "Failed to enable.\n"); + } + } else { + ret = 0; + } + + return ret; +} + +void s5p_sysmmu_disable(struct device *owner) +{ + struct sysmmu_drvdata *mmudata = NULL; + + while ((mmudata = get_sysmmu_data(owner, mmudata))) { + if (__sysmmu_disable(mmudata)) + dev_dbg(mmudata->dev, "Disabled.\n"); + else + dev_dbg(mmudata->dev, + "Inactivation request ignorred\n"); + } +} + +void s5p_sysmmu_tlb_invalidate(struct device *owner) +{ + struct sysmmu_drvdata *mmudata = NULL; + + while ((mmudata = get_sysmmu_data(owner, mmudata))) { + unsigned long flags; + + read_lock_irqsave(&mmudata->lock, flags); + + if (is_sysmmu_active(mmudata)) { + sysmmu_block(mmudata->sfrbase); + __sysmmu_tlb_invalidate(mmudata->sfrbase); + sysmmu_unblock(mmudata->sfrbase); + } else { + dev_dbg(mmudata->dev, + "Disabled: Skipping invalidating TLB.\n"); + } + + read_unlock_irqrestore(&mmudata->lock, flags); + } +} + +static int s5p_sysmmu_probe(struct platform_device *pdev) +{ + struct resource *res, *ioarea; + int ret; + int irq; + struct device *dev; + void *sfr; + struct sysmmu_drvdata *data; + + dev = &pdev->dev; + + if (!dev_get_platdata(dev)) { + dev_dbg(dev, "Skipping probing - No owner device.\n"); + return -ENODEV; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + dev_err(dev, "Not enough memory for private data.\n"); + return -ENOMEM; + } + + data->owner = dev_get_platdata(dev); + + ret = dev_set_drvdata(dev, data); + if (ret) { + dev_err(dev, "Unable to set driver's private data.\n"); + goto err_init; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "Failed to get resource.\n"); + goto err_init; + } + + ioarea = request_mem_region(res->start, resource_size(res), + dev_name(dev)); + if (ioarea == NULL) { + dev_err(dev, "Failed to request memory region.\n"); + goto err_init; + } + + sfr = ioremap(res->start, resource_size(res)); + if (!sfr) { + dev_err(dev, "Failed to map IO area\n"); + ret = -ENOENT; + goto err_ioremap; + } + + irq = platform_get_irq(pdev, 0); + if (irq <= 0) { + dev_err(dev, "Failed to get irq resource.\n"); + ret = irq; + goto err_irq; + } + + ret = request_irq(irq, s5p_sysmmu_irq, 0, dev_name(dev), data); + if (ret) { + dev_err(dev, "Failed to request irq.\n"); + goto err_irq; + } + + data->clk = clk_get(dev, "sysmmu"); + if (IS_ERR(data->clk)) { + dev_dbg(dev, "Clock descriptor not found:" + " Skipping clock gating...\n"); + data->clk = NULL; + } + + data->dev = dev; + data->sfrbase = sfr; + rwlock_init(&data->lock); + INIT_LIST_HEAD(&data->node); + + __set_fault_handler(data, &default_fault_handler); + list_add(&data->node, &sysmmu_list); + + if (dev->parent) + pm_runtime_enable(dev); + + if (to_platform_device(data->owner)->id == -1) + dev_info(dev, "Initialized for %s.\n", + to_platform_device(data->owner)->name); + else + dev_info(dev, "Initialized for %s.%d.\n", + to_platform_device(data->owner)->name, + to_platform_device(data->owner)->id); + return 0; +err_irq: + iounmap(sfr); +err_ioremap: + release_resource(ioarea); + kfree(ioarea); +err_init: + kfree(data); + dev_err(dev, "Probing system MMU failed!"); + return ret; +} + +static struct platform_driver s5p_sysmmu_driver = { + .probe = s5p_sysmmu_probe, + .driver = { + .owner = THIS_MODULE, + .name = "s5p-sysmmu", + } +}; + +static int __init s5p_sysmmu_init(void) +{ + return platform_driver_register(&s5p_sysmmu_driver); +} +subsys_initcall(s5p_sysmmu_init); diff --git a/arch/arm/plat-s5p/s5p_iommu.c b/arch/arm/plat-s5p/s5p_iommu.c new file mode 100644 index 0000000..a900c84 --- /dev/null +++ b/arch/arm/plat-s5p/s5p_iommu.c @@ -0,0 +1,459 @@ +/* linux/drivers/iommu/exynos_iommu.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifdef CONFIG_S5P_SYSTEM_MMU_DEBUG +#define DEBUG +#endif + +#include <linux/io.h> +#include <linux/mm.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/iommu.h> +#include <linux/errno.h> +#include <linux/list.h> + +#include <asm/cacheflush.h> + +#include <plat/s5p-sysmmu.h> + +#ifdef CONFIG_S5P_SYSTEM_MMU_DEBUG +#define DEBUG /* for dev_dbg() */ +#endif + +/* We does not consider super section mapping (16MB) */ +#define S5P_SPAGE_SHIFT 12 +#define S5P_LPAGE_SHIFT 16 +#define S5P_SECTION_SHIFT 20 + +#define S5P_SPAGE_SIZE (1 << S5P_SPAGE_SHIFT) +#define S5P_LPAGE_SIZE (1 << S5P_LPAGE_SHIFT) +#define S5P_SECTION_SIZE (1 << S5P_SECTION_SHIFT) + +#define S5P_SPAGE_MASK (~(S5P_SPAGE_SIZE - 1)) +#define S5P_LPAGE_MASK (~(S5P_LPAGE_SIZE - 1)) +#define S5P_SECTION_MASK (~(S5P_SECTION_SIZE - 1)) + +#define S5P_SPAGE_ORDER (S5P_SPAGE_SHIFT - PAGE_SHIFT) +#define S5P_LPAGE_ORDER (S5P_LPAGE_SHIFT - S5P_SPAGE_SHIFT) +#define S5P_SECTION_ORDER (S5P_SECTION_SHIFT - S5P_SPAGE_SHIFT) + +#define S5P_LV1TABLE_ENTRIES (1 << (BITS_PER_LONG - S5P_SECTION_SHIFT)) +#define S5P_LV1TABLE_ORDER 2 /* get_order(S5P_LV1TABLE_ENTRIES) */ + +#define S5P_LV2TABLE_ENTRIES (1 << S5P_SECTION_ORDER) +#define S5P_LV2TABLE_SIZE (S5P_LV2TABLE_ENTRIES * sizeof(long)) +#define S5P_LV2TABLE_MASK (~(S5P_LV2TABLE_SIZE - 1)) /* 0xFFFFFC00 */ + +#define S5P_SECTION_LV1_ENTRY(entry) ((entry & 0x40003) == 2) +#define S5P_SUPSECT_LV1_ENTRY(entry) ((entry & 0x40003) == 0x40002) +#define S5P_PAGE_LV1_ENTRY(entry) ((entry & 3) == 1) +#define S5P_FAULT_LV1_ENTRY(entry) (((entry & 3) == 0) || (entry & 3) == 3) + +#define S5P_LPAGE_LV2_ENTRY(entry) ((entry & 3) == 1) +#define S5P_SPAGE_LV2_ENTRY(entry) ((entry & 2) == 2) +#define S5P_FAULT_LV2_ENTRY(entry) ((entry & 3) == 0) + +#define MAKE_FAULT_ENTRY(entry) do { entry = 0; } while (0) +#define MAKE_SECTION_ENTRY(entry, pa) do { entry = pa | 2; } while (0) +#define MAKE_SUPSECT_ENTRY(entry, pa) do { entry = pa | 0x40002; } while (0) +#define MAKE_LV2TABLE_ENTRY(entry, pa) do { entry = pa | 1; } while (0) + +#define MAKE_LPAGE_ENTRY(entry, pa) do { entry = pa | 1; } while (0) +#define MAKE_SPAGE_ENTRY(entry, pa) do { entry = pa | 3; } while (0) + +#define GET_LV2ENTRY(entry, iova) (\ + (unsigned long *)phys_to_virt(entry & S5P_LV2TABLE_MASK) +\ + ((iova & (~S5P_SECTION_MASK)) >> S5P_SPAGE_SHIFT)) + +struct s5p_iommu_domain { + struct device *dev; + unsigned long *pgtable; + struct mutex lock; +}; + +/* slab cache for level 2 page tables */ +static struct kmem_cache *l2table_cachep; + +static inline void pgtable_flush(void *vastart, void *vaend) +{ + dmac_flush_range(vastart, vaend); + outer_flush_range(virt_to_phys(vastart), + virt_to_phys(vaend)); +} + +static int s5p_iommu_domain_init(struct iommu_domain *domain) +{ + struct s5p_iommu_domain *priv; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->pgtable = (unsigned long *)__get_free_pages(GFP_KERNEL, + S5P_LV1TABLE_ORDER); + if (!priv->pgtable) { + kfree(priv); + return -ENOMEM; + } + + memset(priv->pgtable, 0, S5P_LV1TABLE_ENTRIES * sizeof(unsigned long)); + pgtable_flush(priv->pgtable, priv->pgtable + S5P_LV1TABLE_ENTRIES); + + mutex_init(&priv->lock); + + domain->priv = priv; + pr_debug("%s: Allocated IOMMU domain %p with pgtable @ %#lx\n", + __func__, domain, __pa(priv->pgtable)); + return 0; +} + +static void s5p_iommu_domain_destroy(struct iommu_domain *domain) +{ + struct s5p_iommu_domain *priv = domain->priv; + + free_pages((unsigned long)priv->pgtable, S5P_LV1TABLE_ORDER); + kfree(domain->priv); + domain->priv = NULL; +} + +static int s5p_iommu_attach_device(struct iommu_domain *domain, + struct device *dev) +{ + int ret; + struct s5p_iommu_domain *s5p_domain = domain->priv; + + if (s5p_domain->dev) { + pr_debug("%s: %s is already attached to doamin %p\n", __func__, + dev_name(s5p_domain->dev), domain); + BUG_ON(s5p_domain->dev != dev); + return -EBUSY; + } + + ret = s5p_sysmmu_enable(dev, virt_to_phys(s5p_domain->pgtable)); + if (ret) + return ret; + + mutex_lock(&s5p_domain->lock); + s5p_domain->dev = dev; + mutex_unlock(&s5p_domain->lock); + + return 0; +} + +static void s5p_iommu_detach_device(struct iommu_domain *domain, + struct device *dev) +{ + struct s5p_iommu_domain *s5p_domain = domain->priv; + + mutex_lock(&s5p_domain->lock); + + if (s5p_domain->dev == dev) { + mutex_unlock(&s5p_domain->lock); + + s5p_sysmmu_disable(s5p_domain->dev); + + s5p_domain->dev = NULL; + } else { + pr_debug("%s: %s is not attached to domain of pgtable @ %#lx\n", + __func__, dev_name(dev), __pa(s5p_domain->pgtable)); + mutex_unlock(&s5p_domain->lock); + } + +} + +static bool section_available(struct iommu_domain *domain, + unsigned long *lv1entry) +{ + struct s5p_iommu_domain *s5p_domain = domain->priv; + + if (S5P_SECTION_LV1_ENTRY(*lv1entry)) { + pr_err("1MB entry alread exists at %#x // pgtable %#lx\n", + (lv1entry - s5p_domain->pgtable) * SZ_1M, + __pa(s5p_domain->pgtable)); + return false; + } + + if (S5P_PAGE_LV1_ENTRY(*lv1entry)) { + unsigned long *lv2end, *lv2base; + + lv2base = phys_to_virt(*lv1entry & S5P_LV2TABLE_MASK); + lv2end = lv2base + S5P_LV2TABLE_ENTRIES; + while (lv2base != lv2end) { + if (!S5P_FAULT_LV2_ENTRY(*lv2base)) { + pr_err("Failed to free L2 page table for" + "section mapping. // pgtalle %#lx\n", + __pa(s5p_domain->pgtable)); + return false; + } + lv2base++; + } + + kmem_cache_free(l2table_cachep, + phys_to_virt(*lv1entry & S5P_LV2TABLE_MASK)); + + MAKE_FAULT_ENTRY(*lv1entry); + } + + return true; +} + +static bool write_lpage(unsigned long *head_entry, unsigned long phys_addr) +{ + unsigned long *entry, *end; + + entry = head_entry; + end = entry + (1 << S5P_LPAGE_ORDER); + + while (entry != end) { + if (!S5P_FAULT_LV2_ENTRY(*entry)) + break; + + MAKE_LPAGE_ENTRY(*entry, phys_addr); + + entry++; + } + + if (entry != end) { + end = entry; + while (entry != head_entry) + MAKE_FAULT_ENTRY(*(--entry)); + + return false; + } + + return true; +} + +static int s5p_iommu_map(struct iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, int gfp_order, int prot) +{ + struct s5p_iommu_domain *s5p_domain = domain->priv; + unsigned long *start_entry, *entry, *end_entry; + int num_entry; + int ret = 0; + + BUG_ON(s5p_domain->pgtable== NULL); + + mutex_lock(&s5p_domain->lock); + + start_entry = entry = s5p_domain->pgtable + (iova >> S5P_SECTION_SHIFT); + + if (gfp_order >= S5P_SECTION_ORDER) { + BUG_ON((paddr | iova) & ~S5P_SECTION_MASK); + /* 1MiB mapping */ + + num_entry = 1 << (gfp_order - S5P_SECTION_ORDER); + end_entry = entry + num_entry; + + while (entry != end_entry) { + if (!section_available(domain, entry)) + break; + + MAKE_SECTION_ENTRY(*entry, paddr); + + paddr += S5P_SECTION_SIZE; + entry++; + } + + if (entry != end_entry) + goto mapping_error; + + pgtable_flush(start_entry, entry); + goto mapping_done; + } + + if (S5P_FAULT_LV1_ENTRY(*entry)) { + unsigned long *l2table; + + l2table = kmem_cache_zalloc(l2table_cachep, GFP_KERNEL); + if (!l2table) { + ret = -ENOMEM; + goto nomem_error; + } + + pgtable_flush(l2table, l2table + S5P_LV2TABLE_ENTRIES); + + MAKE_LV2TABLE_ENTRY(*entry, virt_to_phys(l2table)); + pgtable_flush(entry, entry + 1); + } + + /* 'entry' points level 2 entries, hereafter */ + entry = GET_LV2ENTRY(*entry, iova); + + start_entry = entry; + num_entry = 1 << gfp_order; + end_entry = entry + num_entry; + + if (gfp_order >= S5P_LPAGE_ORDER) { + /* large page(64KiB) mapping */ + BUG_ON((paddr | iova) & ~S5P_LPAGE_MASK); + + while (entry != end_entry) { + if (!write_lpage(entry, paddr)) { + pr_err("%s: Failed to allocate large page" + "for IOVA %#lx entry.\n", + __func__, iova); + ret = -EADDRINUSE; + break; + } + + paddr += S5P_LPAGE_SIZE; + entry += (1 << S5P_LPAGE_ORDER); + } + + if (entry != end_entry) { + entry -= 1 << S5P_LPAGE_ORDER; + goto mapping_error; + } + } else { + /* page (4KiB) mapping */ + while (entry != end_entry && S5P_FAULT_LV2_ENTRY(*entry)) { + + MAKE_SPAGE_ENTRY(*entry, paddr); + + entry++; + paddr += S5P_SPAGE_SIZE; + } + + if (entry != end_entry) { + pr_err("%s: Failed to allocate small page entry" + " for IOVA %#lx.\n", __func__, iova); + ret = -EADDRINUSE; + + goto mapping_error; + } + } + + pgtable_flush(start_entry, entry); +mapping_error: + if (entry != end_entry) { + unsigned long *current_entry = entry; + while (entry != start_entry) + MAKE_FAULT_ENTRY(*(--entry)); + pgtable_flush(start_entry, current_entry); + ret = -EADDRINUSE; + } + +nomem_error: +mapping_done: + mutex_unlock(&s5p_domain->lock); + + return ret; +} + +static int s5p_iommu_unmap(struct iommu_domain *domain, unsigned long iova, + int gfp_order) +{ + struct s5p_iommu_domain *s5p_domain = domain->priv; + unsigned long *entry; + int num_entry; + + BUG_ON(s5p_domain->pgtable == NULL); + + mutex_lock(&s5p_domain->lock); + + entry = s5p_domain->pgtable + (iova >> S5P_SECTION_SHIFT); + + if (gfp_order >= S5P_SECTION_ORDER) { + num_entry = 1 << (gfp_order - S5P_SECTION_ORDER); + while (num_entry--) { + if (S5P_SECTION_LV1_ENTRY(*entry)) { + MAKE_FAULT_ENTRY(*entry); + } else if (S5P_PAGE_LV1_ENTRY(*entry)) { + unsigned long *lv2beg, *lv2end; + lv2beg = phys_to_virt( + *entry & S5P_LV2TABLE_MASK); + lv2end = lv2beg + S5P_LV2TABLE_ENTRIES; + while (lv2beg != lv2end) { + MAKE_FAULT_ENTRY(*lv2beg); + lv2beg++; + } + } + entry++; + } + } else { + entry = GET_LV2ENTRY(*entry, iova); + + BUG_ON(S5P_LPAGE_LV2_ENTRY(*entry) && + (gfp_order < S5P_LPAGE_ORDER)); + + num_entry = 1 << gfp_order; + + while (num_entry--) { + MAKE_FAULT_ENTRY(*entry); + entry++; + } + } + + mutex_unlock(&s5p_domain->lock); + + if (s5p_domain->dev) + s5p_sysmmu_tlb_invalidate(s5p_domain->dev); + + return 0; +} + +static phys_addr_t s5p_iommu_iova_to_phys(struct iommu_domain *domain, + unsigned long iova) +{ + struct s5p_iommu_domain *s5p_domain = domain->priv; + unsigned long *entry; + unsigned long offset; + + entry = s5p_domain->pgtable + (iova >> S5P_SECTION_SHIFT); + + if (S5P_FAULT_LV1_ENTRY(*entry)) + return 0; + + offset = iova & ~S5P_SECTION_MASK; + + if (S5P_SECTION_LV1_ENTRY(*entry)) + return (*entry & S5P_SECTION_MASK) + offset; + + entry = GET_LV2ENTRY(*entry, iova); + + if (S5P_SPAGE_LV2_ENTRY(*entry)) + return (*entry & S5P_SPAGE_MASK) + (iova & ~S5P_SPAGE_MASK); + + if (S5P_LPAGE_LV2_ENTRY(*entry)) + return (*entry & S5P_LPAGE_MASK) + (iova & ~S5P_LPAGE_MASK); + + return 0; +} + +static int s5p_iommu_domain_has_cap(struct iommu_domain *domain, + unsigned long cap) +{ + return 0; +} + +static struct iommu_ops s5p_iommu_ops = { + .domain_init = &s5p_iommu_domain_init, + .domain_destroy = &s5p_iommu_domain_destroy, + .attach_dev = &s5p_iommu_attach_device, + .detach_dev = &s5p_iommu_detach_device, + .map = &s5p_iommu_map, + .unmap = &s5p_iommu_unmap, + .iova_to_phys = &s5p_iommu_iova_to_phys, + .domain_has_cap = &s5p_iommu_domain_has_cap, +}; + +static int __init s5p_iommu_init(void) +{ + l2table_cachep = kmem_cache_create("SysMMU Lv2 Tables", + S5P_LV2TABLE_SIZE, S5P_LV2TABLE_SIZE, 0, NULL); + if (!l2table_cachep) + return -ENOMEM; + + register_iommu(&s5p_iommu_ops); + return 0; +} +arch_initcall(s5p_iommu_init); diff --git a/arch/arm/plat-s5p/s5p_iovmm.c b/arch/arm/plat-s5p/s5p_iovmm.c new file mode 100644 index 0000000..a56ccef --- /dev/null +++ b/arch/arm/plat-s5p/s5p_iovmm.c @@ -0,0 +1,365 @@ +/* linux/arch/arm/plat-s5p/s5p_iovmm.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/slab.h> +#include <linux/scatterlist.h> +#include <linux/device.h> +#include <linux/list.h> +#include <linux/ion.h> +#include <linux/iommu.h> +#include <linux/genalloc.h> +#include <linux/err.h> +#include <linux/spinlock.h> + +#include <plat/s5p-iovmm.h> + +struct s5p_vm_region { + struct list_head node; + dma_addr_t start; + size_t size; +}; + +struct s5p_iovmm { + struct list_head node; /* element of s5p_iovmm_list */ + struct iommu_domain *domain; + struct device *dev; + struct gen_pool *vmm_pool; + struct list_head regions_list; /* list of s5p_vm_region */ + bool active; + struct mutex lock; +}; + +static DEFINE_RWLOCK(iovmm_list_lock); +static LIST_HEAD(s5p_iovmm_list); + +static struct s5p_iovmm *find_iovmm(struct device *dev) +{ + struct list_head *pos; + struct s5p_iovmm *vmm = NULL; + + read_lock(&iovmm_list_lock); + list_for_each(pos, &s5p_iovmm_list) { + vmm = list_entry(pos, struct s5p_iovmm, node); + if (vmm->dev == dev) + break; + } + read_unlock(&iovmm_list_lock); + return vmm; +} + +static struct s5p_vm_region *find_region(struct s5p_iovmm *vmm, dma_addr_t iova) +{ + struct list_head *pos; + struct s5p_vm_region *region; + + list_for_each(pos, &vmm->regions_list) { + region = list_entry(pos, struct s5p_vm_region, node); + if (region->start == iova) + return region; + } + return NULL; +} + +int iovmm_setup(struct device *dev) +{ + struct s5p_iovmm *vmm; + int ret; + + vmm = kzalloc(sizeof(*vmm), GFP_KERNEL); + if (!vmm) { + ret = -ENOMEM; + goto err_setup_alloc; + } + + vmm->vmm_pool = gen_pool_create(PAGE_SHIFT, -1); + if (!vmm->vmm_pool) { + ret = -ENOMEM; + goto err_setup_genalloc; + } + + /* 1GB addr space from 0x80000000 */ + ret = gen_pool_add(vmm->vmm_pool, 0x80000000, 0x40000000, -1); + if (ret) + goto err_setup_domain; + + vmm->domain = iommu_domain_alloc(); + if (!vmm->domain) { + ret = -ENOMEM; + goto err_setup_domain; + } + + vmm->dev = dev; + + mutex_init(&vmm->lock); + + INIT_LIST_HEAD(&vmm->node); + INIT_LIST_HEAD(&vmm->regions_list); + + write_lock(&iovmm_list_lock); + list_add(&vmm->node, &s5p_iovmm_list); + write_unlock(&iovmm_list_lock); + + return 0; +err_setup_domain: + gen_pool_destroy(vmm->vmm_pool); +err_setup_genalloc: + kfree(vmm); +err_setup_alloc: + return ret; +} + +void iovmm_cleanup(struct device *dev) +{ + struct s5p_iovmm *vmm; + + vmm = find_iovmm(dev); + + WARN_ON(!vmm); + if (vmm) { + struct list_head *pos, *tmp; + + if (vmm->active) + iommu_detach_device(vmm->domain, dev); + + iommu_domain_free(vmm->domain); + + list_for_each_safe(pos, tmp, &vmm->regions_list) { + struct s5p_vm_region *region; + + region = list_entry(pos, struct s5p_vm_region, node); + + /* No need to unmap the region because + * iommu_domain_free() frees the page table */ + gen_pool_free(vmm->vmm_pool, region->start, + region->size); + + kfree(list_entry(pos, struct s5p_vm_region, node)); + } + + gen_pool_destroy(vmm->vmm_pool); + + write_lock(&iovmm_list_lock); + list_del(&vmm->node); + write_unlock(&iovmm_list_lock); + + kfree(vmm); + } +} + +int iovmm_activate(struct device *dev) +{ + struct s5p_iovmm *vmm; + int ret = 0; + + vmm = find_iovmm(dev); + if (WARN_ON(!vmm)) + return -EINVAL; + + mutex_lock(&vmm->lock); + + ret = iommu_attach_device(vmm->domain, vmm->dev); + if (!ret) + vmm->active = true; + + mutex_unlock(&vmm->lock); + + return ret; +} + +void iovmm_deactivate(struct device *dev) +{ + struct s5p_iovmm *vmm; + + vmm = find_iovmm(dev); + if (WARN_ON(!vmm)) + return; + + iommu_detach_device(vmm->domain, vmm->dev); + + vmm->active = false; +} + +dma_addr_t iovmm_map(struct device *dev, struct scatterlist *sg, off_t offset, + size_t size) +{ + off_t start_off; + dma_addr_t addr, start = 0; + size_t mapped_size = 0; + struct s5p_vm_region *region; + struct s5p_iovmm *vmm; + int order; +#ifdef CONFIG_S5P_SYSTEM_MMU_WA5250ERR + size_t iova_size = 0; +#endif + + BUG_ON(!sg); + + vmm = find_iovmm(dev); + if (WARN_ON(!vmm)) + goto err_map_nomem; + + for (; sg_dma_len(sg) < offset; sg = sg_next(sg)) + offset -= sg_dma_len(sg); + + mutex_lock(&vmm->lock); + + start_off = offset_in_page(sg_phys(sg) + offset); + size = PAGE_ALIGN(size + start_off); + + order = __fls(min(size, (size_t)SZ_1M)); +#ifdef CONFIG_S5P_SYSTEM_MMU_WA5250ERR + iova_size = ALIGN(size, SZ_64K); + start = (dma_addr_t)gen_pool_alloc_aligned(vmm->vmm_pool, iova_size, + order); +#else + start = (dma_addr_t)gen_pool_alloc_aligned(vmm->vmm_pool, size, order); +#endif + if (!start) + goto err_map_nomem_lock; + + addr = start; + do { + phys_addr_t phys; + size_t len; + + phys = sg_phys(sg); + len = sg_dma_len(sg); + + if (offset > 0) { + len -= offset; + phys += offset; + offset = 0; + } + + if (offset_in_page(phys)) { + len += offset_in_page(phys); + phys = round_down(phys, PAGE_SIZE); + } + + len = PAGE_ALIGN(len); + + if (len > (size - mapped_size)) + len = size - mapped_size; + + while (len > 0) { + order = min3(__ffs(phys), __ffs(addr), __fls(len)); + + if (iommu_map(vmm->domain, addr, phys, + order - PAGE_SHIFT, 0)) + goto err_map_map; + + addr += (1 << order); + phys += (1 << order); + len -= (1 << order); + mapped_size += (1 << order); + } + } while ((sg = sg_next(sg)) && (mapped_size < size)); + + BUG_ON(mapped_size > size); + + if (mapped_size < size) + goto err_map_map; + +#ifdef CONFIG_S5P_SYSTEM_MMU_WA5250ERR + if (iova_size != size) { + /* System MMU v3 support in SMDK5250 EVT0 */ + addr = start + size; + size = iova_size; + + for (; addr < start + size; addr += PAGE_SIZE) { + if (iommu_map(vmm->domain, addr, + page_to_phys(ZERO_PAGE(0)), 0, 0)) { + goto err_map_map; + } + mapped_size += PAGE_SIZE; + } + } +#endif + region = kmalloc(sizeof(*region), GFP_KERNEL); + if (!region) + goto err_map_map; + + region->start = start + start_off; + region->size = size; + INIT_LIST_HEAD(®ion->node); + + list_add(®ion->node, &vmm->regions_list); + + mutex_unlock(&vmm->lock); + + return region->start; +err_map_map: + while (addr >= start) { + int order; + mapped_size = addr - start; + + if (mapped_size == 0) /* Mapping failed at the first page */ + mapped_size = size; + + BUG_ON(mapped_size < PAGE_SIZE); + + order = min(__fls(mapped_size), __ffs(start)); + + iommu_unmap(vmm->domain, start, order - PAGE_SHIFT); + + start += 1 << order; + mapped_size -= 1 << order; + } + gen_pool_free(vmm->vmm_pool, start, size); + +err_map_nomem_lock: + mutex_unlock(&vmm->lock); +err_map_nomem: + return (dma_addr_t)0; +} + +void iovmm_unmap(struct device *dev, dma_addr_t iova) +{ + struct s5p_vm_region *region; + struct s5p_iovmm *vmm; + + vmm = find_iovmm(dev); + + if (WARN_ON(!vmm)) + return; + + mutex_lock(&vmm->lock); + + region = find_region(vmm, iova); + if (WARN_ON(!region)) + goto err_region_not_found; + + region->start = round_down(region->start, PAGE_SIZE); + + gen_pool_free(vmm->vmm_pool, region->start, region->size); + list_del(®ion->node); + + while (region->size != 0) { + int order; + + order = min(__fls(region->size), __ffs(region->start)); + + iommu_unmap(vmm->domain, region->start, order - PAGE_SHIFT); + + region->start += 1 << order; + region->size -= 1 << order; + } + + kfree(region); + +err_region_not_found: + mutex_unlock(&vmm->lock); +} + +static int __init s5p_iovmm_init(void) +{ + return 0; +} +arch_initcall(s5p_iovmm_init); diff --git a/arch/arm/plat-s5p/sysmmu.c b/arch/arm/plat-s5p/sysmmu.c deleted file mode 100644 index 54f5edd..0000000 --- a/arch/arm/plat-s5p/sysmmu.c +++ /dev/null @@ -1,312 +0,0 @@ -/* linux/arch/arm/plat-s5p/sysmmu.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/io.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> - -#include <asm/pgtable.h> - -#include <mach/map.h> -#include <mach/regs-sysmmu.h> -#include <plat/sysmmu.h> - -#define CTRL_ENABLE 0x5 -#define CTRL_BLOCK 0x7 -#define CTRL_DISABLE 0x0 - -static struct device *dev; - -static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = { - S5P_PAGE_FAULT_ADDR, - S5P_AR_FAULT_ADDR, - S5P_AW_FAULT_ADDR, - S5P_DEFAULT_SLAVE_ADDR, - S5P_AR_FAULT_ADDR, - S5P_AR_FAULT_ADDR, - S5P_AW_FAULT_ADDR, - S5P_AW_FAULT_ADDR -}; - -static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = { - "PAGE FAULT", - "AR MULTI-HIT FAULT", - "AW MULTI-HIT FAULT", - "BUS ERROR", - "AR SECURITY PROTECTION FAULT", - "AR ACCESS PROTECTION FAULT", - "AW SECURITY PROTECTION FAULT", - "AW ACCESS PROTECTION FAULT" -}; - -static int (*fault_handlers[S5P_SYSMMU_TOTAL_IPNUM])( - enum S5P_SYSMMU_INTERRUPT_TYPE itype, - unsigned long pgtable_base, - unsigned long fault_addr); - -/* - * If adjacent 2 bits are true, the system MMU is enabled. - * The system MMU is disabled, otherwise. - */ -static unsigned long sysmmu_states; - -static inline void set_sysmmu_active(sysmmu_ips ips) -{ - sysmmu_states |= 3 << (ips * 2); -} - -static inline void set_sysmmu_inactive(sysmmu_ips ips) -{ - sysmmu_states &= ~(3 << (ips * 2)); -} - -static inline int is_sysmmu_active(sysmmu_ips ips) -{ - return sysmmu_states & (3 << (ips * 2)); -} - -static void __iomem *sysmmusfrs[S5P_SYSMMU_TOTAL_IPNUM]; - -static inline void sysmmu_block(sysmmu_ips ips) -{ - __raw_writel(CTRL_BLOCK, sysmmusfrs[ips] + S5P_MMU_CTRL); - dev_dbg(dev, "%s is blocked.\n", sysmmu_ips_name[ips]); -} - -static inline void sysmmu_unblock(sysmmu_ips ips) -{ - __raw_writel(CTRL_ENABLE, sysmmusfrs[ips] + S5P_MMU_CTRL); - dev_dbg(dev, "%s is unblocked.\n", sysmmu_ips_name[ips]); -} - -static inline void __sysmmu_tlb_invalidate(sysmmu_ips ips) -{ - __raw_writel(0x1, sysmmusfrs[ips] + S5P_MMU_FLUSH); - dev_dbg(dev, "TLB of %s is invalidated.\n", sysmmu_ips_name[ips]); -} - -static inline void __sysmmu_set_ptbase(sysmmu_ips ips, unsigned long pgd) -{ - if (unlikely(pgd == 0)) { - pgd = (unsigned long)ZERO_PAGE(0); - __raw_writel(0x20, sysmmusfrs[ips] + S5P_MMU_CFG); /* 4KB LV1 */ - } else { - __raw_writel(0x0, sysmmusfrs[ips] + S5P_MMU_CFG); /* 16KB LV1 */ - } - - __raw_writel(pgd, sysmmusfrs[ips] + S5P_PT_BASE_ADDR); - - dev_dbg(dev, "Page table base of %s is initialized with 0x%08lX.\n", - sysmmu_ips_name[ips], pgd); - __sysmmu_tlb_invalidate(ips); -} - -void sysmmu_set_fault_handler(sysmmu_ips ips, - int (*handler)(enum S5P_SYSMMU_INTERRUPT_TYPE itype, - unsigned long pgtable_base, - unsigned long fault_addr)) -{ - BUG_ON(!((ips >= SYSMMU_MDMA) && (ips < S5P_SYSMMU_TOTAL_IPNUM))); - fault_handlers[ips] = handler; -} - -static irqreturn_t s5p_sysmmu_irq(int irq, void *dev_id) -{ - /* SYSMMU is in blocked when interrupt occurred. */ - unsigned long base = 0; - sysmmu_ips ips = (sysmmu_ips)dev_id; - enum S5P_SYSMMU_INTERRUPT_TYPE itype; - - itype = (enum S5P_SYSMMU_INTERRUPT_TYPE) - __ffs(__raw_readl(sysmmusfrs[ips] + S5P_INT_STATUS)); - - BUG_ON(!((itype >= 0) && (itype < 8))); - - dev_alert(dev, "%s occurred by %s.\n", sysmmu_fault_name[itype], - sysmmu_ips_name[ips]); - - if (fault_handlers[ips]) { - unsigned long addr; - - base = __raw_readl(sysmmusfrs[ips] + S5P_PT_BASE_ADDR); - addr = __raw_readl(sysmmusfrs[ips] + fault_reg_offset[itype]); - - if (fault_handlers[ips](itype, base, addr)) { - __raw_writel(1 << itype, - sysmmusfrs[ips] + S5P_INT_CLEAR); - dev_notice(dev, "%s from %s is resolved." - " Retrying translation.\n", - sysmmu_fault_name[itype], sysmmu_ips_name[ips]); - } else { - base = 0; - } - } - - sysmmu_unblock(ips); - - if (!base) - dev_notice(dev, "%s from %s is not handled.\n", - sysmmu_fault_name[itype], sysmmu_ips_name[ips]); - - return IRQ_HANDLED; -} - -void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd) -{ - if (is_sysmmu_active(ips)) { - sysmmu_block(ips); - __sysmmu_set_ptbase(ips, pgd); - sysmmu_unblock(ips); - } else { - dev_dbg(dev, "%s is disabled. " - "Skipping initializing page table base.\n", - sysmmu_ips_name[ips]); - } -} - -void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd) -{ - if (!is_sysmmu_active(ips)) { - sysmmu_clk_enable(ips); - - __sysmmu_set_ptbase(ips, pgd); - - __raw_writel(CTRL_ENABLE, sysmmusfrs[ips] + S5P_MMU_CTRL); - - set_sysmmu_active(ips); - dev_dbg(dev, "%s is enabled.\n", sysmmu_ips_name[ips]); - } else { - dev_dbg(dev, "%s is already enabled.\n", sysmmu_ips_name[ips]); - } -} - -void s5p_sysmmu_disable(sysmmu_ips ips) -{ - if (is_sysmmu_active(ips)) { - __raw_writel(CTRL_DISABLE, sysmmusfrs[ips] + S5P_MMU_CTRL); - set_sysmmu_inactive(ips); - sysmmu_clk_disable(ips); - dev_dbg(dev, "%s is disabled.\n", sysmmu_ips_name[ips]); - } else { - dev_dbg(dev, "%s is already disabled.\n", sysmmu_ips_name[ips]); - } -} - -void s5p_sysmmu_tlb_invalidate(sysmmu_ips ips) -{ - if (is_sysmmu_active(ips)) { - sysmmu_block(ips); - __sysmmu_tlb_invalidate(ips); - sysmmu_unblock(ips); - } else { - dev_dbg(dev, "%s is disabled. " - "Skipping invalidating TLB.\n", sysmmu_ips_name[ips]); - } -} - -static int s5p_sysmmu_probe(struct platform_device *pdev) -{ - int i, ret; - struct resource *res, *mem; - - dev = &pdev->dev; - - for (i = 0; i < S5P_SYSMMU_TOTAL_IPNUM; i++) { - int irq; - - sysmmu_clk_init(dev, i); - sysmmu_clk_disable(i); - - res = platform_get_resource(pdev, IORESOURCE_MEM, i); - if (!res) { - dev_err(dev, "Failed to get the resource of %s.\n", - sysmmu_ips_name[i]); - ret = -ENODEV; - goto err_res; - } - - mem = request_mem_region(res->start, - ((res->end) - (res->start)) + 1, pdev->name); - if (!mem) { - dev_err(dev, "Failed to request the memory region of %s.\n", - sysmmu_ips_name[i]); - ret = -EBUSY; - goto err_res; - } - - sysmmusfrs[i] = ioremap(res->start, res->end - res->start + 1); - if (!sysmmusfrs[i]) { - dev_err(dev, "Failed to ioremap() for %s.\n", - sysmmu_ips_name[i]); - ret = -ENXIO; - goto err_reg; - } - - irq = platform_get_irq(pdev, i); - if (irq <= 0) { - dev_err(dev, "Failed to get the IRQ resource of %s.\n", - sysmmu_ips_name[i]); - ret = -ENOENT; - goto err_map; - } - - if (request_irq(irq, s5p_sysmmu_irq, IRQF_DISABLED, - pdev->name, (void *)i)) { - dev_err(dev, "Failed to request IRQ for %s.\n", - sysmmu_ips_name[i]); - ret = -ENOENT; - goto err_map; - } - } - - return 0; - -err_map: - iounmap(sysmmusfrs[i]); -err_reg: - release_mem_region(mem->start, resource_size(mem)); -err_res: - return ret; -} - -static int s5p_sysmmu_remove(struct platform_device *pdev) -{ - return 0; -} -int s5p_sysmmu_runtime_suspend(struct device *dev) -{ - return 0; -} - -int s5p_sysmmu_runtime_resume(struct device *dev) -{ - return 0; -} - -const struct dev_pm_ops s5p_sysmmu_pm_ops = { - .runtime_suspend = s5p_sysmmu_runtime_suspend, - .runtime_resume = s5p_sysmmu_runtime_resume, -}; - -static struct platform_driver s5p_sysmmu_driver = { - .probe = s5p_sysmmu_probe, - .remove = s5p_sysmmu_remove, - .driver = { - .owner = THIS_MODULE, - .name = "s5p-sysmmu", - .pm = &s5p_sysmmu_pm_ops, - } -}; - -static int __init s5p_sysmmu_init(void) -{ - return platform_driver_register(&s5p_sysmmu_driver); -} -arch_initcall(s5p_sysmmu_init); |