ARM: S5P: Add support for MFC device
Add support for MFC device to plat-s5p, mach-exynos4, mach-s5pv210: - clock support - memory mapping and reserving - s5p_device_mfc platform device Signed-off-by: Kamil Debski <k.debski@samsung.com> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
This commit is contained in:
parent
35ce909ee6
commit
0f75a96bc0
10 changed files with 234 additions and 1 deletions
|
@ -753,6 +753,7 @@ config ARCH_S5PV210
|
|||
bool "Samsung S5PV210/S5PC110"
|
||||
select CPU_V7
|
||||
select ARCH_SPARSEMEM_ENABLE
|
||||
select ARCH_HAS_HOLES_MEMORYMODEL
|
||||
select GENERIC_GPIO
|
||||
select HAVE_CLK
|
||||
select CLKDEV_LOOKUP
|
||||
|
@ -770,6 +771,7 @@ config ARCH_EXYNOS4
|
|||
bool "Samsung EXYNOS4"
|
||||
select CPU_V7
|
||||
select ARCH_SPARSEMEM_ENABLE
|
||||
select ARCH_HAS_HOLES_MEMORYMODEL
|
||||
select GENERIC_GPIO
|
||||
select HAVE_CLK
|
||||
select CLKDEV_LOOKUP
|
||||
|
|
|
@ -527,6 +527,11 @@ static struct clk init_clocks_off[] = {
|
|||
.name = "fimg2d",
|
||||
.enable = exynos4_clk_ip_image_ctrl,
|
||||
.ctrlbit = (1 << 0),
|
||||
}, {
|
||||
.name = "mfc",
|
||||
.devname = "s5p-mfc",
|
||||
.enable = exynos4_clk_ip_mfc_ctrl,
|
||||
.ctrlbit = (1 << 0),
|
||||
}, {
|
||||
.name = "i2c",
|
||||
.devname = "s3c2440-i2c.0",
|
||||
|
@ -731,6 +736,52 @@ static struct clksrc_sources clkset_mout_g2d = {
|
|||
.nr_sources = ARRAY_SIZE(clkset_mout_g2d_list),
|
||||
};
|
||||
|
||||
static struct clk *clkset_mout_mfc0_list[] = {
|
||||
[0] = &clk_mout_mpll.clk,
|
||||
[1] = &clk_sclk_apll.clk,
|
||||
};
|
||||
|
||||
static struct clksrc_sources clkset_mout_mfc0 = {
|
||||
.sources = clkset_mout_mfc0_list,
|
||||
.nr_sources = ARRAY_SIZE(clkset_mout_mfc0_list),
|
||||
};
|
||||
|
||||
static struct clksrc_clk clk_mout_mfc0 = {
|
||||
.clk = {
|
||||
.name = "mout_mfc0",
|
||||
},
|
||||
.sources = &clkset_mout_mfc0,
|
||||
.reg_src = { .reg = S5P_CLKSRC_MFC, .shift = 0, .size = 1 },
|
||||
};
|
||||
|
||||
static struct clk *clkset_mout_mfc1_list[] = {
|
||||
[0] = &clk_mout_epll.clk,
|
||||
[1] = &clk_sclk_vpll.clk,
|
||||
};
|
||||
|
||||
static struct clksrc_sources clkset_mout_mfc1 = {
|
||||
.sources = clkset_mout_mfc1_list,
|
||||
.nr_sources = ARRAY_SIZE(clkset_mout_mfc1_list),
|
||||
};
|
||||
|
||||
static struct clksrc_clk clk_mout_mfc1 = {
|
||||
.clk = {
|
||||
.name = "mout_mfc1",
|
||||
},
|
||||
.sources = &clkset_mout_mfc1,
|
||||
.reg_src = { .reg = S5P_CLKSRC_MFC, .shift = 4, .size = 1 },
|
||||
};
|
||||
|
||||
static struct clk *clkset_mout_mfc_list[] = {
|
||||
[0] = &clk_mout_mfc0.clk,
|
||||
[1] = &clk_mout_mfc1.clk,
|
||||
};
|
||||
|
||||
static struct clksrc_sources clkset_mout_mfc = {
|
||||
.sources = clkset_mout_mfc_list,
|
||||
.nr_sources = ARRAY_SIZE(clkset_mout_mfc_list),
|
||||
};
|
||||
|
||||
static struct clksrc_clk clk_dout_mmc0 = {
|
||||
.clk = {
|
||||
.name = "dout_mmc0",
|
||||
|
@ -972,6 +1023,14 @@ static struct clksrc_clk clksrcs[] = {
|
|||
.sources = &clkset_mout_g2d,
|
||||
.reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
|
||||
.reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
|
||||
}, {
|
||||
.clk = {
|
||||
.name = "sclk_mfc",
|
||||
.devname = "s5p-mfc",
|
||||
},
|
||||
.sources = &clkset_mout_mfc,
|
||||
.reg_src = { .reg = S5P_CLKSRC_MFC, .shift = 8, .size = 1 },
|
||||
.reg_div = { .reg = S5P_CLKDIV_MFC, .shift = 0, .size = 4 },
|
||||
}, {
|
||||
.clk = {
|
||||
.name = "sclk_mmc",
|
||||
|
@ -1049,6 +1108,8 @@ static struct clksrc_clk *sysclks[] = {
|
|||
&clk_dout_mmc2,
|
||||
&clk_dout_mmc3,
|
||||
&clk_dout_mmc4,
|
||||
&clk_mout_mfc0,
|
||||
&clk_mout_mfc1,
|
||||
};
|
||||
|
||||
static int xtal_rate;
|
||||
|
|
|
@ -108,6 +108,7 @@
|
|||
|
||||
#define EXYNOS4_PA_EHCI 0x12580000
|
||||
#define EXYNOS4_PA_HSPHY 0x125B0000
|
||||
#define EXYNOS4_PA_MFC 0x13400000
|
||||
|
||||
#define EXYNOS4_PA_UART 0x13800000
|
||||
|
||||
|
@ -155,6 +156,7 @@
|
|||
#define S5P_PA_ONENAND_DMA EXYNOS4_PA_ONENAND_DMA
|
||||
#define S5P_PA_SDRAM EXYNOS4_PA_SDRAM
|
||||
#define S5P_PA_SROMC EXYNOS4_PA_SROMC
|
||||
#define S5P_PA_MFC EXYNOS4_PA_MFC
|
||||
#define S5P_PA_SYSCON EXYNOS4_PA_SYSCON
|
||||
#define S5P_PA_TIMER EXYNOS4_PA_TIMER
|
||||
#define S5P_PA_EHCI EXYNOS4_PA_EHCI
|
||||
|
|
|
@ -323,6 +323,12 @@ static struct clk init_clocks_off[] = {
|
|||
.parent = &clk_hclk_dsys.clk,
|
||||
.enable = s5pv210_clk_ip0_ctrl,
|
||||
.ctrlbit = (1 << 26),
|
||||
}, {
|
||||
.name = "mfc",
|
||||
.devname = "s5p-mfc",
|
||||
.parent = &clk_pclk_psys.clk,
|
||||
.enable = s5pv210_clk_ip0_ctrl,
|
||||
.ctrlbit = (1 << 16),
|
||||
}, {
|
||||
.name = "otg",
|
||||
.parent = &clk_hclk_psys.clk,
|
||||
|
@ -914,6 +920,7 @@ static struct clksrc_clk clksrcs[] = {
|
|||
}, {
|
||||
.clk = {
|
||||
.name = "sclk_mfc",
|
||||
.devname = "s5p-mfc",
|
||||
.enable = s5pv210_clk_ip0_ctrl,
|
||||
.ctrlbit = (1 << 16),
|
||||
},
|
||||
|
|
|
@ -59,6 +59,8 @@
|
|||
|
||||
#define S5PV210_PA_CFCON 0xE8200000
|
||||
|
||||
#define S5PV210_PA_MFC 0xF1700000
|
||||
|
||||
#define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000))
|
||||
|
||||
#define S5PV210_PA_HSOTG 0xEC000000
|
||||
|
@ -107,6 +109,7 @@
|
|||
#define S5P_PA_FIMC1 S5PV210_PA_FIMC1
|
||||
#define S5P_PA_FIMC2 S5PV210_PA_FIMC2
|
||||
#define S5P_PA_MIPI_CSIS0 S5PV210_PA_MIPI_CSIS
|
||||
#define S5P_PA_MFC S5PV210_PA_MFC
|
||||
#define S5P_PA_ONENAND S5PC110_PA_ONENAND
|
||||
#define S5P_PA_ONENAND_DMA S5PC110_PA_ONENAND_DMA
|
||||
#define S5P_PA_SDRAM S5PV210_PA_SDRAM
|
||||
|
|
|
@ -76,6 +76,11 @@ config S5P_DEV_FIMD0
|
|||
help
|
||||
Compile in platform device definitions for FIMD controller 0
|
||||
|
||||
config S5P_DEV_MFC
|
||||
bool
|
||||
help
|
||||
Compile in platform device definitions for MFC
|
||||
|
||||
config S5P_DEV_ONENAND
|
||||
bool
|
||||
help
|
||||
|
|
|
@ -25,7 +25,7 @@ obj-$(CONFIG_PM) += irq-pm.o
|
|||
obj-$(CONFIG_S5P_HRT) += s5p-time.o
|
||||
|
||||
# devices
|
||||
|
||||
obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.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
|
||||
|
|
123
arch/arm/plat-s5p/dev-mfc.c
Normal file
123
arch/arm/plat-s5p/dev-mfc.c
Normal file
|
@ -0,0 +1,123 @@
|
|||
/* linux/arch/arm/plat-s5p/dev-mfc.c
|
||||
*
|
||||
* Copyright (C) 2010-2011 Samsung Electronics Co.Ltd
|
||||
*
|
||||
* 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/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/ioport.h>
|
||||
|
||||
#include <mach/map.h>
|
||||
#include <plat/devs.h>
|
||||
#include <plat/irqs.h>
|
||||
#include <plat/mfc.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 = "s5p-mfc",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(s5p_mfc_resource),
|
||||
.resource = s5p_mfc_resource,
|
||||
};
|
||||
|
||||
/*
|
||||
* MFC hardware has 2 memory interfaces which are modelled as two separate
|
||||
* platform devices to let dma-mapping distinguish between them.
|
||||
*
|
||||
* MFC parent device (s5p_device_mfc) must be registered before memory
|
||||
* interface specific devices (s5p_device_mfc_l and s5p_device_mfc_r).
|
||||
*/
|
||||
|
||||
static u64 s5p_mfc_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
struct platform_device s5p_device_mfc_l = {
|
||||
.name = "s5p-mfc-l",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.parent = &s5p_device_mfc.dev,
|
||||
.dma_mask = &s5p_mfc_dma_mask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device s5p_device_mfc_r = {
|
||||
.name = "s5p-mfc-r",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.parent = &s5p_device_mfc.dev,
|
||||
.dma_mask = &s5p_mfc_dma_mask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
},
|
||||
};
|
||||
|
||||
struct s5p_mfc_reserved_mem {
|
||||
phys_addr_t base;
|
||||
unsigned long size;
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
static struct s5p_mfc_reserved_mem s5p_mfc_mem[2] __initdata;
|
||||
|
||||
void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
|
||||
phys_addr_t lbase, unsigned int lsize)
|
||||
{
|
||||
int i;
|
||||
|
||||
s5p_mfc_mem[0].dev = &s5p_device_mfc_r.dev;
|
||||
s5p_mfc_mem[0].base = rbase;
|
||||
s5p_mfc_mem[0].size = rsize;
|
||||
|
||||
s5p_mfc_mem[1].dev = &s5p_device_mfc_l.dev;
|
||||
s5p_mfc_mem[1].base = lbase;
|
||||
s5p_mfc_mem[1].size = lsize;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) {
|
||||
struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i];
|
||||
if (memblock_remove(area->base, area->size)) {
|
||||
printk(KERN_ERR "Failed to reserve memory for MFC device (%ld bytes at 0x%08lx)\n",
|
||||
area->size, (unsigned long) area->base);
|
||||
area->base = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int __init s5p_mfc_memory_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) {
|
||||
struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i];
|
||||
if (!area->base)
|
||||
continue;
|
||||
|
||||
if (dma_declare_coherent_memory(area->dev, area->base,
|
||||
area->base, area->size,
|
||||
DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0)
|
||||
printk(KERN_ERR "Failed to declare coherent memory for MFC device (%ld bytes at 0x%08lx)\n",
|
||||
area->size, (unsigned long) area->base);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
device_initcall(s5p_mfc_memory_init);
|
27
arch/arm/plat-s5p/include/plat/mfc.h
Normal file
27
arch/arm/plat-s5p/include/plat/mfc.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef __PLAT_S5P_MFC_H
|
||||
#define __PLAT_S5P_MFC_H
|
||||
|
||||
/**
|
||||
* s5p_mfc_reserve_mem - function to early reserve memory for MFC driver
|
||||
* @rbase: base address for MFC 'right' memory interface
|
||||
* @rsize: size of the memory reserved for MFC 'right' interface
|
||||
* @lbase: base address for MFC 'left' memory interface
|
||||
* @lsize: size of the memory reserved for MFC 'left' interface
|
||||
*
|
||||
* This function reserves system memory for both MFC device memory
|
||||
* interfaces and registers it to respective struct device entries as
|
||||
* coherent memory.
|
||||
*/
|
||||
void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
|
||||
phys_addr_t lbase, unsigned int lsize);
|
||||
|
||||
#endif /* __PLAT_S5P_MFC_H */
|
|
@ -139,6 +139,9 @@ extern struct platform_device s5p_device_fimc1;
|
|||
extern struct platform_device s5p_device_fimc2;
|
||||
extern struct platform_device s5p_device_fimc3;
|
||||
|
||||
extern struct platform_device s5p_device_mfc;
|
||||
extern struct platform_device s5p_device_mfc_l;
|
||||
extern struct platform_device s5p_device_mfc_r;
|
||||
extern struct platform_device s5p_device_mipi_csis0;
|
||||
extern struct platform_device s5p_device_mipi_csis1;
|
||||
|
||||
|
|
Loading…
Reference in a new issue