mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-12-27 13:36:47 +02:00
jz4740: Remove imem and ipu support from proc
It's not used and wastes 4MB of mem.
This commit is contained in:
parent
928b8ba548
commit
bc0684a065
@ -166,26 +166,6 @@ static int cgm_write_proc(struct file *file, const char *buffer, unsigned long c
|
||||
}
|
||||
|
||||
|
||||
/* USAGE:
|
||||
* echo n > /proc/jz/ipu // n = [1,...,9], alloc mem, 2^n pages.
|
||||
* echo FF > /proc/jz/ipu // 255, free all buffer
|
||||
* echo xxxx > /proc/jz/ipu // free buffer which addr is xxxx
|
||||
* echo llll > /proc/jz/ipu // add_wired_entry(l,l,l,l)
|
||||
* echo 0 > /proc/jz/ipu // debug, print ipu_buf
|
||||
* od -X /proc/jz/ipu // read mem addr
|
||||
*/
|
||||
|
||||
typedef struct _ipu_buf {
|
||||
unsigned int addr; /* phys addr */
|
||||
unsigned int page_shift;
|
||||
} ipu_buf_t;
|
||||
|
||||
#define IPU_BUF_MAX 4 /* 4 buffers */
|
||||
|
||||
static struct _ipu_buf ipu_buf[IPU_BUF_MAX];
|
||||
static int ipu_buf_cnt = 0;
|
||||
static unsigned char g_asid=0;
|
||||
|
||||
extern void local_flush_tlb_all(void);
|
||||
|
||||
/* CP0 hazard avoidance. */
|
||||
@ -235,244 +215,6 @@ void show_tlb(void)
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static void ipu_add_wired_entry(unsigned long pid,
|
||||
unsigned long entrylo0, unsigned long entrylo1,
|
||||
unsigned long entryhi, unsigned long pagemask)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long wired;
|
||||
unsigned long old_pagemask;
|
||||
unsigned long old_ctx;
|
||||
struct task_struct *g, *p;
|
||||
|
||||
/* We will lock an 4MB page size entry to map the 4MB reserved IPU memory */
|
||||
wired = read_c0_wired();
|
||||
if (wired) return;
|
||||
|
||||
do_each_thread(g, p) {
|
||||
if (p->pid == pid )
|
||||
g_asid = p->mm->context[0];
|
||||
} while_each_thread(g, p);
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
entrylo0 = entrylo0 >> 6; /* PFN */
|
||||
entrylo0 |= 0x6 | (0 << 3); /* Write-through cacheable, dirty, valid */
|
||||
|
||||
/* Save old context and create impossible VPN2 value */
|
||||
old_ctx = read_c0_entryhi() & 0xff;
|
||||
old_pagemask = read_c0_pagemask();
|
||||
write_c0_wired(wired + 1);
|
||||
write_c0_index(wired);
|
||||
BARRIER;
|
||||
entryhi &= ~0xff; /* new add, 20070906 */
|
||||
entryhi |= g_asid; /* new add, 20070906 */
|
||||
// entryhi |= old_ctx; /* new add, 20070906 */
|
||||
write_c0_pagemask(pagemask);
|
||||
write_c0_entryhi(entryhi);
|
||||
write_c0_entrylo0(entrylo0);
|
||||
write_c0_entrylo1(entrylo1);
|
||||
BARRIER;
|
||||
tlb_write_indexed();
|
||||
BARRIER;
|
||||
|
||||
write_c0_entryhi(old_ctx);
|
||||
BARRIER;
|
||||
write_c0_pagemask(old_pagemask);
|
||||
local_flush_tlb_all();
|
||||
local_irq_restore(flags);
|
||||
#if defined(DEBUG)
|
||||
printk("\nold_ctx=%03d\n", old_ctx);
|
||||
|
||||
show_tlb();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ipu_del_wired_entry( void )
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long wired;
|
||||
|
||||
/* Free all lock entry */
|
||||
local_irq_save(flags);
|
||||
wired = read_c0_wired();
|
||||
if (wired)
|
||||
write_c0_wired(0);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static inline void ipu_buf_get( unsigned int page_shift )
|
||||
{
|
||||
unsigned char * virt_addr;
|
||||
int i;
|
||||
for ( i=0; i< IPU_BUF_MAX; ++i ) {
|
||||
if ( ipu_buf[i].addr == 0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( (ipu_buf_cnt = i) == IPU_BUF_MAX ) {
|
||||
printk("Error, no free ipu buffer.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
virt_addr = (unsigned char *)__get_free_pages(GFP_KERNEL, page_shift);
|
||||
|
||||
if ( virt_addr ) {
|
||||
ipu_buf[ipu_buf_cnt].addr = (unsigned int)virt_to_phys((void *)virt_addr);
|
||||
ipu_buf[ipu_buf_cnt].page_shift = page_shift;
|
||||
|
||||
for (i = 0; i < (1<<page_shift); i++) {
|
||||
SetPageReserved(virt_to_page(virt_addr));
|
||||
virt_addr += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printk("get memory Failed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ipu_buf_free( unsigned int phys_addr )
|
||||
{
|
||||
unsigned char * virt_addr, *addr;
|
||||
int cnt, i;
|
||||
|
||||
if ( phys_addr == 0 )
|
||||
return ;
|
||||
|
||||
for ( cnt=0; cnt<IPU_BUF_MAX; ++cnt )
|
||||
if ( phys_addr == ipu_buf[cnt].addr )
|
||||
break;
|
||||
|
||||
if ( cnt == IPU_BUF_MAX ) { /* addr not in the ipu buffers */
|
||||
printk("Invalid addr:0x%08x\n", (unsigned int)phys_addr);
|
||||
}
|
||||
|
||||
virt_addr = (unsigned char *)phys_to_virt(ipu_buf[cnt].addr);
|
||||
addr = virt_addr;
|
||||
for (i = 0; i < (1<<ipu_buf[cnt].page_shift); i++) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
addr += PAGE_SIZE;
|
||||
}
|
||||
|
||||
if ( cnt == 0 )
|
||||
ipu_del_wired_entry();
|
||||
|
||||
free_pages((unsigned long )virt_addr, ipu_buf[cnt].page_shift);
|
||||
|
||||
ipu_buf[cnt].addr = 0;
|
||||
ipu_buf[cnt].page_shift = 0;
|
||||
}
|
||||
|
||||
static int ipu_read_proc (char *page, char **start, off_t off,
|
||||
int count, int *eof, void *data)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
/* read as binary */
|
||||
unsigned int * pint;
|
||||
pint = (unsigned int *) (page+len);
|
||||
|
||||
if ( ipu_buf_cnt >= IPU_BUF_MAX ) { /* failed alloc mem, rturn 0 */
|
||||
printk("no free buffer.\n");
|
||||
*pint = 0;
|
||||
}
|
||||
else
|
||||
*pint = (unsigned int )ipu_buf[ipu_buf_cnt].addr; /* phys addr */
|
||||
len += sizeof(unsigned int);
|
||||
|
||||
#if defined(DEBUG)
|
||||
show_tlb();
|
||||
#endif
|
||||
return len;
|
||||
|
||||
}
|
||||
|
||||
static int ipu_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
|
||||
{
|
||||
unsigned int val ;
|
||||
int cnt,i;
|
||||
char buf[12];
|
||||
unsigned long pid, entrylo0, entrylo1, entryhi, pagemask;
|
||||
#if defined(DEBUG)
|
||||
printk("ipu write count=%u\n", count);
|
||||
#endif
|
||||
if (count == (8*5+1)) {
|
||||
for (i=0;i<12;i++) buf[i]=0;
|
||||
strncpy(buf, buffer+8*0, 8);
|
||||
pid = simple_strtoul(buf, 0, 16);
|
||||
for (i=0;i<12;i++) buf[i]=0;
|
||||
strncpy(buf, buffer+8*1, 8);
|
||||
entrylo0 = simple_strtoul(buf, 0, 16);
|
||||
for (i=0;i<12;i++) buf[i]=0;
|
||||
strncpy(buf, buffer+8*2, 8);
|
||||
entrylo1 = simple_strtoul(buf, 0, 16);
|
||||
for (i=0;i<12;i++) buf[i]=0;
|
||||
strncpy(buf, buffer+8*3, 8);
|
||||
entryhi = simple_strtoul(buf, 0, 16);
|
||||
for (i=0;i<12;i++) buf[i]=0;
|
||||
strncpy(buf, buffer+8*4, 8);
|
||||
pagemask = simple_strtoul(buf, 0, 16);
|
||||
|
||||
#if defined(DEBUG)
|
||||
printk("pid=0x%08x, entrylo0=0x%08x, entrylo1=0x%08x, entryhi=0x%08x, pagemask=0x%08x\n",
|
||||
pid, entrylo0, entrylo1, entryhi, pagemask);
|
||||
#endif
|
||||
ipu_add_wired_entry( pid, entrylo0, entrylo1, entryhi, pagemask);
|
||||
return 41;
|
||||
} else if ( count <= 8+1 ) {
|
||||
for (i=0;i<12;i++) buf[i]=0;
|
||||
strncpy(buf, buffer, 8);
|
||||
val = simple_strtoul(buf, 0, 16);
|
||||
} else if (count == 44) {
|
||||
for (i = 0; i < 12; i++)
|
||||
buf[i] = 0;
|
||||
strncpy(buf, buffer, 10);
|
||||
pid = simple_strtoul(buf, 0, 16);
|
||||
for (i = 0; i < 12; i++)
|
||||
buf[i] = 0;
|
||||
strncpy(buf, buffer + 11, 10);
|
||||
entryhi = simple_strtoul(buf, 0, 16);//vaddr
|
||||
for (i = 0; i < 12; i++)
|
||||
buf[i] = 0;
|
||||
strncpy(buf, buffer + 22, 10);
|
||||
entrylo0 = simple_strtoul(buf, 0, 16);//paddr
|
||||
for (i = 0; i < 12; i++)
|
||||
buf[i] = 0;
|
||||
strncpy(buf, buffer + 33, 10);
|
||||
pagemask = simple_strtoul(buf, 0, 16);
|
||||
pagemask = 0x3ff << 13; /* Fixed to 4MB page size */
|
||||
ipu_add_wired_entry(pid, entrylo0, 0, entryhi, pagemask);
|
||||
return 44;
|
||||
} else {
|
||||
printk("ipu write count error, count=%d\n.", (unsigned int)count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* val: 1-9, page_shift, val>= 10: ipu_buf.addr */
|
||||
if ( val == 0 ) { /* debug, print ipu_buf info */
|
||||
for ( cnt=0; cnt<IPU_BUF_MAX; ++cnt)
|
||||
printk("ipu_buf[%d]: addr=0x%08x, page_shift=%d\n",
|
||||
cnt, ipu_buf[cnt].addr, ipu_buf[cnt].page_shift );
|
||||
#if defined(DEBUG)
|
||||
show_tlb();
|
||||
#endif
|
||||
}
|
||||
else if ( 0< val && val < 10 ) {
|
||||
ipu_buf_get(val);
|
||||
}
|
||||
else if ( val == 0xff ) { /* 255: free all ipu_buf */
|
||||
for ( cnt=0; cnt<IPU_BUF_MAX; ++cnt ) {
|
||||
ipu_buf_free(ipu_buf[cnt].addr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ipu_buf_free(val);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* UDC hotplug
|
||||
*/
|
||||
@ -517,245 +259,6 @@ static int udc_read_proc(char *page, char **start, off_t off,
|
||||
return len;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* IPU memory management (used by mplayer and other apps)
|
||||
*
|
||||
* We reserved 4MB memory for IPU
|
||||
* The memory base address is jz_ipu_framebuf
|
||||
*/
|
||||
|
||||
/* Usage:
|
||||
*
|
||||
* echo n > /proc/jz/imem // n = [0,...,10], allocate memory, 2^n pages
|
||||
* echo xxxxxxxx > /proc/jz/imem // free buffer which addr is xxxxxxxx
|
||||
* echo FF > /proc/jz/ipu // FF, free all buffers
|
||||
* od -X /proc/jz/imem // return the allocated buffer address and the max order of free buffer
|
||||
*/
|
||||
|
||||
//#define DEBUG_IMEM 1
|
||||
|
||||
#define IMEM_MAX_ORDER 10 /* max 2^10 * 4096 = 4MB */
|
||||
|
||||
static unsigned int jz_imem_base; /* physical base address of ipu memory */
|
||||
|
||||
static unsigned int allocated_phys_addr = 0;
|
||||
|
||||
/*
|
||||
* Allocated buffer list
|
||||
*/
|
||||
typedef struct imem_list {
|
||||
unsigned int phys_start; /* physical start addr */
|
||||
unsigned int phys_end; /* physical end addr */
|
||||
struct imem_list *next;
|
||||
} imem_list_t;
|
||||
|
||||
static struct imem_list *imem_list_head = NULL; /* up sorted by phys_start */
|
||||
|
||||
#ifdef DEBUG_IMEM
|
||||
static void dump_imem_list(void)
|
||||
{
|
||||
struct imem_list *imem;
|
||||
|
||||
printk("*** dump_imem_list 0x%x ***\n", (u32)imem_list_head);
|
||||
imem = imem_list_head;
|
||||
while (imem) {
|
||||
printk("imem=0x%x phys_start=0x%x phys_end=0x%x next=0x%x\n", (u32)imem, imem->phys_start, imem->phys_end, (u32)imem->next);
|
||||
imem = imem->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* allocate 2^order pages inside the 4MB memory */
|
||||
static int imem_alloc(unsigned int order)
|
||||
{
|
||||
int alloc_ok = 0;
|
||||
unsigned int start, end;
|
||||
unsigned int size = (1 << order) * PAGE_SIZE;
|
||||
struct imem_list *imem, *imemn, *imemp;
|
||||
|
||||
allocated_phys_addr = 0;
|
||||
|
||||
start = jz_imem_base;
|
||||
end = start + (1 << IMEM_MAX_ORDER) * PAGE_SIZE;
|
||||
|
||||
imem = imem_list_head;
|
||||
while (imem) {
|
||||
if ((imem->phys_start - start) >= size) {
|
||||
/* we got a valid address range */
|
||||
alloc_ok = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
start = imem->phys_end + 1;
|
||||
imem = imem->next;
|
||||
}
|
||||
|
||||
if (!alloc_ok) {
|
||||
if ((end - start) >= size)
|
||||
alloc_ok = 1;
|
||||
}
|
||||
|
||||
if (alloc_ok) {
|
||||
end = start + size - 1;
|
||||
allocated_phys_addr = start;
|
||||
|
||||
/* add to imem_list, up sorted by phys_start */
|
||||
imemn = kmalloc(sizeof(struct imem_list), GFP_KERNEL);
|
||||
if (!imemn) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
imemn->phys_start = start;
|
||||
imemn->phys_end = end;
|
||||
imemn->next = NULL;
|
||||
|
||||
if (!imem_list_head)
|
||||
imem_list_head = imemn;
|
||||
else {
|
||||
imem = imemp = imem_list_head;
|
||||
while (imem) {
|
||||
if (start < imem->phys_start) {
|
||||
break;
|
||||
}
|
||||
|
||||
imemp = imem;
|
||||
imem = imem->next;
|
||||
}
|
||||
|
||||
if (imem == imem_list_head) {
|
||||
imem_list_head = imemn;
|
||||
imemn->next = imem;
|
||||
}
|
||||
else {
|
||||
imemn->next = imemp->next;
|
||||
imemp->next = imemn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_IMEM
|
||||
dump_imem_list();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void imem_free(unsigned int phys_addr)
|
||||
{
|
||||
struct imem_list *imem, *imemp;
|
||||
|
||||
imem = imemp = imem_list_head;
|
||||
while (imem) {
|
||||
if (phys_addr == imem->phys_start) {
|
||||
if (imem == imem_list_head) {
|
||||
imem_list_head = imem->next;
|
||||
}
|
||||
else {
|
||||
imemp->next = imem->next;
|
||||
}
|
||||
|
||||
kfree(imem);
|
||||
break;
|
||||
}
|
||||
|
||||
imemp = imem;
|
||||
imem = imem->next;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_IMEM
|
||||
dump_imem_list();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void imem_free_all(void)
|
||||
{
|
||||
struct imem_list *imem;
|
||||
|
||||
imem = imem_list_head;
|
||||
while (imem) {
|
||||
kfree(imem);
|
||||
imem = imem->next;
|
||||
}
|
||||
|
||||
imem_list_head = NULL;
|
||||
|
||||
allocated_phys_addr = 0;
|
||||
|
||||
#ifdef DEBUG_IMEM
|
||||
dump_imem_list();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the allocated buffer address and the max order of free buffer
|
||||
*/
|
||||
static int imem_read_proc(char *page, char **start, off_t off,
|
||||
int count, int *eof, void *data)
|
||||
{
|
||||
int len = 0;
|
||||
unsigned int start_addr, end_addr, max_order, max_size;
|
||||
struct imem_list *imem;
|
||||
|
||||
unsigned int *tmp = (unsigned int *)(page + len);
|
||||
|
||||
start_addr = jz_imem_base;
|
||||
end_addr = start_addr + (1 << IMEM_MAX_ORDER) * PAGE_SIZE;
|
||||
|
||||
if (!imem_list_head)
|
||||
max_size = end_addr - start_addr;
|
||||
else {
|
||||
max_size = 0;
|
||||
imem = imem_list_head;
|
||||
while (imem) {
|
||||
if (max_size < (imem->phys_start - start_addr))
|
||||
max_size = imem->phys_start - start_addr;
|
||||
|
||||
start_addr = imem->phys_end + 1;
|
||||
imem = imem->next;
|
||||
}
|
||||
|
||||
if (max_size < (end_addr - start_addr))
|
||||
max_size = end_addr - start_addr;
|
||||
}
|
||||
|
||||
if (max_size > 0) {
|
||||
max_order = get_order(max_size);
|
||||
if (((1 << max_order) * PAGE_SIZE) > max_size)
|
||||
max_order--;
|
||||
}
|
||||
else {
|
||||
max_order = 0xffffffff; /* No any free buffer */
|
||||
}
|
||||
|
||||
*tmp++ = allocated_phys_addr; /* address allocated by 'echo n > /proc/jz/imem' */
|
||||
*tmp = max_order; /* max order of current free buffers */
|
||||
|
||||
len += 2 * sizeof(unsigned int);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int imem_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
val = simple_strtoul(buffer, 0, 16);
|
||||
|
||||
if (val == 0xff) {
|
||||
/* free all memory */
|
||||
imem_free_all();
|
||||
ipu_del_wired_entry();
|
||||
}
|
||||
else if ((val >= 0) && (val <= IMEM_MAX_ORDER)) {
|
||||
/* allocate 2^val pages */
|
||||
imem_alloc(val);
|
||||
}
|
||||
else {
|
||||
/* free buffer which phys_addr is val */
|
||||
imem_free(val);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* /proc/jz/xxx entry
|
||||
*
|
||||
@ -791,14 +294,6 @@ static int __init jz_proc_init(void)
|
||||
res->data = NULL;
|
||||
}
|
||||
|
||||
/* Image process unit */
|
||||
res = create_proc_entry("ipu", 0644, proc_jz_root);
|
||||
if (res) {
|
||||
res->read_proc = ipu_read_proc;
|
||||
res->write_proc = ipu_write_proc;
|
||||
res->data = NULL;
|
||||
}
|
||||
|
||||
/* udc hotplug */
|
||||
res = create_proc_entry("udc", 0644, proc_jz_root);
|
||||
if (res) {
|
||||
@ -807,33 +302,6 @@ static int __init jz_proc_init(void)
|
||||
res->data = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reserve a 4MB memory for IPU on JZ4740.
|
||||
*/
|
||||
jz_imem_base = (unsigned int)__get_free_pages(GFP_KERNEL, IMEM_MAX_ORDER);
|
||||
if (jz_imem_base) {
|
||||
/* imem (IPU memory management) */
|
||||
res = create_proc_entry("imem", 0644, proc_jz_root);
|
||||
if (res) {
|
||||
res->read_proc = imem_read_proc;
|
||||
res->write_proc = imem_write_proc;
|
||||
res->data = NULL;
|
||||
}
|
||||
|
||||
/* Set page reserved */
|
||||
virt_addr = jz_imem_base;
|
||||
for (i = 0; i < (1 << IMEM_MAX_ORDER); i++) {
|
||||
SetPageReserved(virt_to_page((void *)virt_addr));
|
||||
virt_addr += PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* Convert to physical address */
|
||||
jz_imem_base = virt_to_phys((void *)jz_imem_base);
|
||||
|
||||
printk("Total %dMB memory at 0x%x was reserved for IPU\n",
|
||||
(unsigned int)((1 << IMEM_MAX_ORDER) * PAGE_SIZE)/1000000, jz_imem_base);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user