From 3c7241bd36e2a618fe20c91f6c69cc20f2d981f2 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 15 Aug 2011 11:09:52 +0800 Subject: ARM: mmp: add sram allocator On mmp platform, there have two sram banks: audio sram and internal sram. The audio sram is mainly for audio; the internal sram is for video, wtm and power management. So add the sram allocator using genalloc to manage them. Every sram bank will register its own platform device info, after the sram allocator create the generic pool for the sram bank, the user module can use the pool's name to get the pool handler; then it can use the handler to alloc/free memory with genalloc APIs. Signed-off-by: Leo Yan Acked-by: Haojian Zhuang Signed-off-by: Eric Miao --- arch/arm/mach-mmp/Makefile | 2 +- arch/arm/mach-mmp/include/mach/sram.h | 35 +++++++ arch/arm/mach-mmp/sram.c | 168 ++++++++++++++++++++++++++++++++++ 3 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-mmp/include/mach/sram.h create mode 100644 arch/arm/mach-mmp/sram.c (limited to 'arch/arm/mach-mmp') diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index b0ac942327aa..169c6743bde8 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -7,7 +7,7 @@ obj-y += common.o clock.o devices.o time.o # SoC support obj-$(CONFIG_CPU_PXA168) += pxa168.o irq-pxa168.o obj-$(CONFIG_CPU_PXA910) += pxa910.o irq-pxa168.o -obj-$(CONFIG_CPU_MMP2) += mmp2.o irq-mmp2.o +obj-$(CONFIG_CPU_MMP2) += mmp2.o irq-mmp2.o sram.o # board support obj-$(CONFIG_MACH_ASPENITE) += aspenite.o diff --git a/arch/arm/mach-mmp/include/mach/sram.h b/arch/arm/mach-mmp/include/mach/sram.h new file mode 100644 index 000000000000..239e0fc1bb1f --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/sram.h @@ -0,0 +1,35 @@ +/* + * linux/arch/arm/mach-mmp/include/mach/sram.h + * + * SRAM Memory Management + * + * Copyright (c) 2011 Marvell Semiconductors Inc. + * + * 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_SRAM_H +#define __ASM_ARCH_SRAM_H + +#include + +/* ARBITRARY: SRAM allocations are multiples of this 2^N size */ +#define SRAM_GRANULARITY 512 + +enum sram_type { + MMP_SRAM_UNDEFINED = 0, + MMP_ASRAM, + MMP_ISRAM, +}; + +struct sram_platdata { + char *pool_name; + int granularity; +}; + +extern struct gen_pool *sram_get_gpool(char *pool_name); + +#endif /* __ASM_ARCH_SRAM_H */ diff --git a/arch/arm/mach-mmp/sram.c b/arch/arm/mach-mmp/sram.c new file mode 100644 index 000000000000..4304f9519372 --- /dev/null +++ b/arch/arm/mach-mmp/sram.c @@ -0,0 +1,168 @@ +/* + * linux/arch/arm/mach-mmp/sram.c + * + * based on mach-davinci/sram.c - DaVinci simple SRAM allocator + * + * Copyright (c) 2011 Marvell Semiconductors Inc. + * All Rights Reserved + * + * Add for mmp sram support - Leo Yan + * + * 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 +#include +#include +#include +#include +#include +#include + +#include + +struct sram_bank_info { + char *pool_name; + struct gen_pool *gpool; + int granularity; + + phys_addr_t sram_phys; + void __iomem *sram_virt; + u32 sram_size; + + struct list_head node; +}; + +static DEFINE_MUTEX(sram_lock); +static LIST_HEAD(sram_bank_list); + +struct gen_pool *sram_get_gpool(char *pool_name) +{ + struct sram_bank_info *info = NULL; + + if (!pool_name) + return NULL; + + mutex_lock(&sram_lock); + + list_for_each_entry(info, &sram_bank_list, node) + if (!strcmp(pool_name, info->pool_name)) + break; + + mutex_unlock(&sram_lock); + + if (&info->node == &sram_bank_list) + return NULL; + + return info->gpool; +} +EXPORT_SYMBOL(sram_get_gpool); + +static int __devinit sram_probe(struct platform_device *pdev) +{ + struct sram_platdata *pdata = pdev->dev.platform_data; + struct sram_bank_info *info; + struct resource *res; + int ret = 0; + + if (!pdata && !pdata->pool_name) + return -ENODEV; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(&pdev->dev, "no memory resource defined\n"); + ret = -ENODEV; + goto out; + } + + if (!resource_size(res)) + return 0; + + info->sram_phys = (phys_addr_t)res->start; + info->sram_size = resource_size(res); + info->sram_virt = ioremap(info->sram_phys, info->sram_size); + info->pool_name = kstrdup(pdata->pool_name, GFP_KERNEL); + info->granularity = pdata->granularity; + + info->gpool = gen_pool_create(ilog2(info->granularity), -1); + if (!info->gpool) { + dev_err(&pdev->dev, "create pool failed\n"); + ret = -ENOMEM; + goto create_pool_err; + } + + ret = gen_pool_add_virt(info->gpool, (unsigned long)info->sram_virt, + info->sram_phys, info->sram_size, -1); + if (ret < 0) { + dev_err(&pdev->dev, "add new chunk failed\n"); + ret = -ENOMEM; + goto add_chunk_err; + } + + mutex_lock(&sram_lock); + list_add(&info->node, &sram_bank_list); + mutex_unlock(&sram_lock); + + platform_set_drvdata(pdev, info); + + dev_info(&pdev->dev, "initialized\n"); + return 0; + +add_chunk_err: + gen_pool_destroy(info->gpool); +create_pool_err: + iounmap(info->sram_virt); + kfree(info->pool_name); +out: + kfree(info); + return ret; +} + +static int __devexit sram_remove(struct platform_device *pdev) +{ + struct sram_bank_info *info; + + info = platform_get_drvdata(pdev); + if (info == NULL) + return -ENODEV; + + mutex_lock(&sram_lock); + list_del(&info->node); + mutex_unlock(&sram_lock); + + gen_pool_destroy(info->gpool); + iounmap(info->sram_virt); + kfree(info->pool_name); + kfree(info); + return 0; +} + +static const struct platform_device_id sram_id_table[] = { + { "asram", MMP_ASRAM }, + { "isram", MMP_ISRAM }, + { } +}; + +static struct platform_driver sram_driver = { + .probe = sram_probe, + .remove = sram_remove, + .driver = { + .name = "mmp-sram", + }, + .id_table = sram_id_table, +}; + +static int __init sram_init(void) +{ + return platform_driver_register(&sram_driver); +} +core_initcall(sram_init); + +MODULE_LICENSE("GPL"); -- cgit v1.2.3-58-ga151 From 101bf4c19672b519f6d50a7b11e1e03b25a929b6 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 15 Aug 2011 11:09:53 +0800 Subject: ARM: mmp: register audio sram bank MMP platform has sram for the audio island; Add the device structure for the audio sram, and register the audio sram device at init phase. Signed-off-by: Leo Yan Acked-by: Haojian Zhuang Signed-off-by: Eric Miao --- arch/arm/mach-mmp/brownstone.c | 5 +++++ arch/arm/mach-mmp/include/mach/mmp2.h | 7 +++++++ arch/arm/mach-mmp/mmp2.c | 1 + 3 files changed, 13 insertions(+) (limited to 'arch/arm/mach-mmp') diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c index c79162a50f28..db4b5fd4e9d2 100644 --- a/arch/arm/mach-mmp/brownstone.c +++ b/arch/arm/mach-mmp/brownstone.c @@ -186,6 +186,10 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = { | PXA_FLAG_SD_8_BIT_CAPABLE_SLOT, }; +static struct sram_platdata mmp2_asram_platdata = { + .pool_name = "asram", + .granularity = SRAM_GRANULARITY, +}; static void __init brownstone_init(void) { @@ -197,6 +201,7 @@ static void __init brownstone_init(void) mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info)); mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */ mmp2_add_sdhost(2, &mmp2_sdh_platdata_mmc2); /* eMMC */ + mmp2_add_asram(&mmp2_asram_platdata); /* enable 5v regulator */ platform_device_register(&brownstone_v_5vp_device); diff --git a/arch/arm/mach-mmp/include/mach/mmp2.h b/arch/arm/mach-mmp/include/mach/mmp2.h index de7b88826ad7..c2273287eda4 100644 --- a/arch/arm/mach-mmp/include/mach/mmp2.h +++ b/arch/arm/mach-mmp/include/mach/mmp2.h @@ -13,6 +13,7 @@ extern void mmp2_clear_pmic_int(void); #include #include #include +#include extern struct pxa_device_desc mmp2_device_uart1; extern struct pxa_device_desc mmp2_device_uart2; @@ -28,6 +29,7 @@ extern struct pxa_device_desc mmp2_device_sdh0; extern struct pxa_device_desc mmp2_device_sdh1; extern struct pxa_device_desc mmp2_device_sdh2; extern struct pxa_device_desc mmp2_device_sdh3; +extern struct pxa_device_desc mmp2_device_asram; static inline int mmp2_add_uart(int id) { @@ -85,5 +87,10 @@ static inline int mmp2_add_sdhost(int id, struct sdhci_pxa_platdata *data) return pxa_register_device(d, data, sizeof(*data)); } +static inline int mmp2_add_asram(struct sram_platdata *data) +{ + return pxa_register_device(&mmp2_device_asram, data, sizeof(*data)); +} + #endif /* __ASM_MACH_MMP2_H */ diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c index 079c18861d5c..9d0075475349 100644 --- a/arch/arm/mach-mmp/mmp2.c +++ b/arch/arm/mach-mmp/mmp2.c @@ -226,4 +226,5 @@ MMP2_DEVICE(sdh0, "sdhci-pxav3", 0, MMC, 0xd4280000, 0x120); MMP2_DEVICE(sdh1, "sdhci-pxav3", 1, MMC2, 0xd4280800, 0x120); MMP2_DEVICE(sdh2, "sdhci-pxav3", 2, MMC3, 0xd4281000, 0x120); MMP2_DEVICE(sdh3, "sdhci-pxav3", 3, MMC4, 0xd4281800, 0x120); +MMP2_DEVICE(asram, "asram", -1, NONE, 0xe0000000, 0x4000); -- cgit v1.2.3-58-ga151 From bca7ab316edd819edd0e3d59f9ccb26c6b2173f5 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 15 Aug 2011 11:09:54 +0800 Subject: ARM: mmp: register internal sram bank MMP2 have the internal sram, this sram can be allocated for video, power management and secure processor. Now the sram usage is: 0xd1000000 ~ 0xd101ffff (128KB) : reserved for secure processor 0xd1020000 ~ 0xd1037fff (96KB) : for video and PM Register the internal sram's second half 96KB buffer, so that video and PM can dynamically alloc/free from it. Signed-off-by: Leo Yan Acked-by: Haojian Zhuang Signed-off-by: Eric Miao --- arch/arm/mach-mmp/brownstone.c | 6 ++++++ arch/arm/mach-mmp/include/mach/mmp2.h | 6 ++++++ arch/arm/mach-mmp/mmp2.c | 2 ++ 3 files changed, 14 insertions(+) (limited to 'arch/arm/mach-mmp') diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c index db4b5fd4e9d2..59dcf9df1537 100644 --- a/arch/arm/mach-mmp/brownstone.c +++ b/arch/arm/mach-mmp/brownstone.c @@ -191,6 +191,11 @@ static struct sram_platdata mmp2_asram_platdata = { .granularity = SRAM_GRANULARITY, }; +static struct sram_platdata mmp2_isram_platdata = { + .pool_name = "isram", + .granularity = SRAM_GRANULARITY, +}; + static void __init brownstone_init(void) { mfp_config(ARRAY_AND_SIZE(brownstone_pin_config)); @@ -202,6 +207,7 @@ static void __init brownstone_init(void) mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */ mmp2_add_sdhost(2, &mmp2_sdh_platdata_mmc2); /* eMMC */ mmp2_add_asram(&mmp2_asram_platdata); + mmp2_add_isram(&mmp2_isram_platdata); /* enable 5v regulator */ platform_device_register(&brownstone_v_5vp_device); diff --git a/arch/arm/mach-mmp/include/mach/mmp2.h b/arch/arm/mach-mmp/include/mach/mmp2.h index c2273287eda4..2f7b2d3c2b18 100644 --- a/arch/arm/mach-mmp/include/mach/mmp2.h +++ b/arch/arm/mach-mmp/include/mach/mmp2.h @@ -30,6 +30,7 @@ extern struct pxa_device_desc mmp2_device_sdh1; extern struct pxa_device_desc mmp2_device_sdh2; extern struct pxa_device_desc mmp2_device_sdh3; extern struct pxa_device_desc mmp2_device_asram; +extern struct pxa_device_desc mmp2_device_isram; static inline int mmp2_add_uart(int id) { @@ -92,5 +93,10 @@ static inline int mmp2_add_asram(struct sram_platdata *data) return pxa_register_device(&mmp2_device_asram, data, sizeof(*data)); } +static inline int mmp2_add_isram(struct sram_platdata *data) +{ + return pxa_register_device(&mmp2_device_isram, data, sizeof(*data)); +} + #endif /* __ASM_MACH_MMP2_H */ diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c index 9d0075475349..43266c44cb36 100644 --- a/arch/arm/mach-mmp/mmp2.c +++ b/arch/arm/mach-mmp/mmp2.c @@ -227,4 +227,6 @@ MMP2_DEVICE(sdh1, "sdhci-pxav3", 1, MMC2, 0xd4280800, 0x120); MMP2_DEVICE(sdh2, "sdhci-pxav3", 2, MMC3, 0xd4281000, 0x120); MMP2_DEVICE(sdh3, "sdhci-pxav3", 3, MMC4, 0xd4281800, 0x120); MMP2_DEVICE(asram, "asram", -1, NONE, 0xe0000000, 0x4000); +/* 0xd1000000 ~ 0xd101ffff is reserved for secure processor */ +MMP2_DEVICE(isram, "isram", -1, NONE, 0xd1020000, 0x18000); -- cgit v1.2.3-58-ga151