-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
powerpc/85xx: add cache-sram support
It adds cache-sram support in P1/P2 QorIQ platforms as under: * A small abstraction over powerpc's remote heap allocator * Exports mpc85xx_cache_sram_alloc()/free() APIs * Supports only one contiguous SRAM window * Drivers can do the following in Kconfig to use these APIs "select FSL_85XX_CACHE_SRAM if MPC85xx" * Required SRAM size and the offset where SRAM should be mapped must be provided at kernel command line as : cache-sram-size=<value> cache-sram-offset=<offset> Signed-off-by: Harninder Rai <harninder.rai@freescale.com> Signed-off-by: Vivek Mahajan <vivek.mahajan@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
- Loading branch information
Harninder Rai
authored and
Kumar Gala
committed
Oct 14, 2010
1 parent
6341efe
commit 6db92cc
Showing
5 changed files
with
540 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Copyright 2009 Freescale Semiconductor, Inc. | ||
* | ||
* Cache SRAM handling for QorIQ platform | ||
* | ||
* Author: Vivek Mahajan <vivek.mahajan@freescale.com> | ||
* This file is derived from the original work done | ||
* by Sylvain Munaut for the Bestcomm SRAM allocator. | ||
* | ||
* 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. | ||
*/ | ||
|
||
#ifndef __ASM_POWERPC_FSL_85XX_CACHE_SRAM_H__ | ||
#define __ASM_POWERPC_FSL_85XX_CACHE_SRAM_H__ | ||
|
||
#include <asm/rheap.h> | ||
#include <linux/spinlock.h> | ||
|
||
/* | ||
* Cache-SRAM | ||
*/ | ||
|
||
struct mpc85xx_cache_sram { | ||
phys_addr_t base_phys; | ||
void *base_virt; | ||
unsigned int size; | ||
rh_info_t *rh; | ||
spinlock_t lock; | ||
}; | ||
|
||
extern void mpc85xx_cache_sram_free(void *ptr); | ||
extern void *mpc85xx_cache_sram_alloc(unsigned int size, | ||
phys_addr_t *phys, unsigned int align); | ||
|
||
#endif /* __AMS_POWERPC_FSL_85XX_CACHE_SRAM_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/* | ||
* Copyright 2009-2010 Freescale Semiconductor, Inc | ||
* | ||
* QorIQ based Cache Controller Memory Mapped Registers | ||
* | ||
* Author: Vivek Mahajan <vivek.mahajan@freescale.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. | ||
*/ | ||
|
||
#ifndef __FSL_85XX_CACHE_CTLR_H__ | ||
#define __FSL_85XX_CACHE_CTLR_H__ | ||
|
||
#define L2CR_L2FI 0x40000000 /* L2 flash invalidate */ | ||
#define L2CR_L2IO 0x00200000 /* L2 instruction only */ | ||
#define L2CR_SRAM_ZERO 0x00000000 /* L2SRAM zero size */ | ||
#define L2CR_SRAM_FULL 0x00010000 /* L2SRAM full size */ | ||
#define L2CR_SRAM_HALF 0x00020000 /* L2SRAM half size */ | ||
#define L2CR_SRAM_TWO_HALFS 0x00030000 /* L2SRAM two half sizes */ | ||
#define L2CR_SRAM_QUART 0x00040000 /* L2SRAM one quarter size */ | ||
#define L2CR_SRAM_TWO_QUARTS 0x00050000 /* L2SRAM two quarter size */ | ||
#define L2CR_SRAM_EIGHTH 0x00060000 /* L2SRAM one eighth size */ | ||
#define L2CR_SRAM_TWO_EIGHTH 0x00070000 /* L2SRAM two eighth size */ | ||
|
||
#define L2SRAM_OPTIMAL_SZ_SHIFT 0x00000003 /* Optimum size for L2SRAM */ | ||
|
||
#define L2SRAM_BAR_MSK_LO18 0xFFFFC000 /* Lower 18 bits */ | ||
#define L2SRAM_BARE_MSK_HI4 0x0000000F /* Upper 4 bits */ | ||
|
||
enum cache_sram_lock_ways { | ||
LOCK_WAYS_ZERO, | ||
LOCK_WAYS_EIGHTH, | ||
LOCK_WAYS_TWO_EIGHTH, | ||
LOCK_WAYS_HALF = 4, | ||
LOCK_WAYS_FULL = 8, | ||
}; | ||
|
||
struct mpc85xx_l2ctlr { | ||
u32 ctl; /* 0x000 - L2 control */ | ||
u8 res1[0xC]; | ||
u32 ewar0; /* 0x010 - External write address 0 */ | ||
u32 ewarea0; /* 0x014 - External write address extended 0 */ | ||
u32 ewcr0; /* 0x018 - External write ctrl */ | ||
u8 res2[4]; | ||
u32 ewar1; /* 0x020 - External write address 1 */ | ||
u32 ewarea1; /* 0x024 - External write address extended 1 */ | ||
u32 ewcr1; /* 0x028 - External write ctrl 1 */ | ||
u8 res3[4]; | ||
u32 ewar2; /* 0x030 - External write address 2 */ | ||
u32 ewarea2; /* 0x034 - External write address extended 2 */ | ||
u32 ewcr2; /* 0x038 - External write ctrl 2 */ | ||
u8 res4[4]; | ||
u32 ewar3; /* 0x040 - External write address 3 */ | ||
u32 ewarea3; /* 0x044 - External write address extended 3 */ | ||
u32 ewcr3; /* 0x048 - External write ctrl 3 */ | ||
u8 res5[0xB4]; | ||
u32 srbar0; /* 0x100 - SRAM base address 0 */ | ||
u32 srbarea0; /* 0x104 - SRAM base addr reg ext address 0 */ | ||
u32 srbar1; /* 0x108 - SRAM base address 1 */ | ||
u32 srbarea1; /* 0x10C - SRAM base addr reg ext address 1 */ | ||
u8 res6[0xCF0]; | ||
u32 errinjhi; /* 0xE00 - Error injection mask high */ | ||
u32 errinjlo; /* 0xE04 - Error injection mask low */ | ||
u32 errinjctl; /* 0xE08 - Error injection tag/ecc control */ | ||
u8 res7[0x14]; | ||
u32 captdatahi; /* 0xE20 - Error data high capture */ | ||
u32 captdatalo; /* 0xE24 - Error data low capture */ | ||
u32 captecc; /* 0xE28 - Error syndrome */ | ||
u8 res8[0x14]; | ||
u32 errdet; /* 0xE40 - Error detect */ | ||
u32 errdis; /* 0xE44 - Error disable */ | ||
u32 errinten; /* 0xE48 - Error interrupt enable */ | ||
u32 errattr; /* 0xE4c - Error attribute capture */ | ||
u32 erradrrl; /* 0xE50 - Error address capture low */ | ||
u32 erradrrh; /* 0xE54 - Error address capture high */ | ||
u32 errctl; /* 0xE58 - Error control */ | ||
u8 res9[0x1A4]; | ||
}; | ||
|
||
struct sram_parameters { | ||
unsigned int sram_size; | ||
uint64_t sram_offset; | ||
}; | ||
|
||
extern int instantiate_cache_sram(struct platform_device *dev, | ||
struct sram_parameters sram_params); | ||
extern void remove_cache_sram(struct platform_device *dev); | ||
|
||
#endif /* __FSL_85XX_CACHE_CTLR_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
/* | ||
* Copyright 2009-2010 Freescale Semiconductor, Inc. | ||
* | ||
* Simple memory allocator abstraction for QorIQ (P1/P2) based Cache-SRAM | ||
* | ||
* Author: Vivek Mahajan <vivek.mahajan@freescale.com> | ||
* | ||
* This file is derived from the original work done | ||
* by Sylvain Munaut for the Bestcomm SRAM allocator. | ||
* | ||
* 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/kernel.h> | ||
#include <linux/slab.h> | ||
#include <linux/err.h> | ||
#include <linux/of_platform.h> | ||
#include <asm/pgtable.h> | ||
#include <asm/fsl_85xx_cache_sram.h> | ||
|
||
#include "fsl_85xx_cache_ctlr.h" | ||
|
||
struct mpc85xx_cache_sram *cache_sram; | ||
|
||
void *mpc85xx_cache_sram_alloc(unsigned int size, | ||
phys_addr_t *phys, unsigned int align) | ||
{ | ||
unsigned long offset; | ||
unsigned long flags; | ||
|
||
if (unlikely(cache_sram == NULL)) | ||
return NULL; | ||
|
||
if (!size || (size > cache_sram->size) || (align > cache_sram->size)) { | ||
pr_err("%s(): size(=%x) or align(=%x) zero or too big\n", | ||
__func__, size, align); | ||
return NULL; | ||
} | ||
|
||
if ((align & (align - 1)) || align <= 1) { | ||
pr_err("%s(): align(=%x) must be power of two and >1\n", | ||
__func__, align); | ||
return NULL; | ||
} | ||
|
||
spin_lock_irqsave(&cache_sram->lock, flags); | ||
offset = rh_alloc_align(cache_sram->rh, size, align, NULL); | ||
spin_unlock_irqrestore(&cache_sram->lock, flags); | ||
|
||
if (IS_ERR_VALUE(offset)) | ||
return NULL; | ||
|
||
*phys = cache_sram->base_phys + offset; | ||
|
||
return (unsigned char *)cache_sram->base_virt + offset; | ||
} | ||
EXPORT_SYMBOL(mpc85xx_cache_sram_alloc); | ||
|
||
void mpc85xx_cache_sram_free(void *ptr) | ||
{ | ||
unsigned long flags; | ||
BUG_ON(!ptr); | ||
|
||
spin_lock_irqsave(&cache_sram->lock, flags); | ||
rh_free(cache_sram->rh, ptr - cache_sram->base_virt); | ||
spin_unlock_irqrestore(&cache_sram->lock, flags); | ||
} | ||
EXPORT_SYMBOL(mpc85xx_cache_sram_free); | ||
|
||
int __init instantiate_cache_sram(struct platform_device *dev, | ||
struct sram_parameters sram_params) | ||
{ | ||
int ret = 0; | ||
|
||
if (cache_sram) { | ||
dev_err(&dev->dev, "Already initialized cache-sram\n"); | ||
return -EBUSY; | ||
} | ||
|
||
cache_sram = kzalloc(sizeof(struct mpc85xx_cache_sram), GFP_KERNEL); | ||
if (!cache_sram) { | ||
dev_err(&dev->dev, "Out of memory for cache_sram structure\n"); | ||
return -ENOMEM; | ||
} | ||
|
||
cache_sram->base_phys = sram_params.sram_offset; | ||
cache_sram->size = sram_params.sram_size; | ||
|
||
if (!request_mem_region(cache_sram->base_phys, cache_sram->size, | ||
"fsl_85xx_cache_sram")) { | ||
dev_err(&dev->dev, "%s: request memory failed\n", | ||
dev->dev.of_node->full_name); | ||
ret = -ENXIO; | ||
goto out_free; | ||
} | ||
|
||
cache_sram->base_virt = ioremap_flags(cache_sram->base_phys, | ||
cache_sram->size, _PAGE_COHERENT | PAGE_KERNEL); | ||
if (!cache_sram->base_virt) { | ||
dev_err(&dev->dev, "%s: ioremap_flags failed\n", | ||
dev->dev.of_node->full_name); | ||
ret = -ENOMEM; | ||
goto out_release; | ||
} | ||
|
||
cache_sram->rh = rh_create(sizeof(unsigned int)); | ||
if (IS_ERR(cache_sram->rh)) { | ||
dev_err(&dev->dev, "%s: Unable to create remote heap\n", | ||
dev->dev.of_node->full_name); | ||
ret = PTR_ERR(cache_sram->rh); | ||
goto out_unmap; | ||
} | ||
|
||
rh_attach_region(cache_sram->rh, 0, cache_sram->size); | ||
spin_lock_init(&cache_sram->lock); | ||
|
||
dev_info(&dev->dev, "[base:0x%llx, size:0x%x] configured and loaded\n", | ||
(unsigned long long)cache_sram->base_phys, cache_sram->size); | ||
|
||
return 0; | ||
|
||
out_unmap: | ||
iounmap(cache_sram->base_virt); | ||
|
||
out_release: | ||
release_mem_region(cache_sram->base_phys, cache_sram->size); | ||
|
||
out_free: | ||
kfree(cache_sram); | ||
return ret; | ||
} | ||
|
||
void remove_cache_sram(struct platform_device *dev) | ||
{ | ||
BUG_ON(!cache_sram); | ||
|
||
rh_detach_region(cache_sram->rh, 0, cache_sram->size); | ||
rh_destroy(cache_sram->rh); | ||
|
||
iounmap(cache_sram->base_virt); | ||
release_mem_region(cache_sram->base_phys, cache_sram->size); | ||
|
||
kfree(cache_sram); | ||
cache_sram = NULL; | ||
|
||
dev_info(&dev->dev, "MPC85xx Cache-SRAM driver unloaded\n"); | ||
} |
Oops, something went wrong.