From: Grant Likely <hidden> Date: 2007-10-14 04:43:17
Second respin of bestcomm patches; this time with some documentation for no
extra charge!
Cheers,
g.
--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
@@ -320,6 +323,7 @@ void rh_init(rh_info_t * info, unsigned int alignment, int max_blocks,for(i=0,blk=block;i<max_blocks;i++,blk++)list_add(&blk->list,&info->empty_list);}+EXPORT_SYMBOL_GPL(rh_init);/* Attach a free memory region, coalesces regions if adjuscent */intrh_attach_region(rh_info_t*info,unsignedlongstart,intsize)
@@ -360,6 +364,7 @@ int rh_attach_region(rh_info_t * info, unsigned long start, int size)return0;}+EXPORT_SYMBOL_GPL(rh_attach_region);/* Detatch given address range, splits free block if needed. */unsignedlongrh_detach_region(rh_info_t*info,unsignedlongstart,intsize)
@@ -428,6 +433,7 @@ unsigned long rh_detach_region(rh_info_t * info, unsigned long start, int size)returns;}+EXPORT_SYMBOL_GPL(rh_detach_region);/* Allocate a block of memory at the specified alignment. The value returned*isanoffsetintothebufferinitializedbyrh_init(),oranegativenumber
@@ -502,6 +508,7 @@ unsigned long rh_alloc_align(rh_info_t * info, int size, int alignment, const chreturnstart;}+EXPORT_SYMBOL_GPL(rh_alloc_align);/* Allocate a block of memory at the default alignment. The value returned is*anoffsetintothebufferinitializedbyrh_init(),oranegativenumberif
@@ -511,6 +518,7 @@ unsigned long rh_alloc(rh_info_t * info, int size, const char *owner){returnrh_alloc_align(info,size,info->alignment,owner);}+EXPORT_SYMBOL_GPL(rh_alloc);/* Allocate a block of memory at the given offset, rounded up to the default*alignment.Thevaluereturnedisanoffsetintothebufferinitializedby
@@ -594,6 +602,7 @@ unsigned long rh_alloc_fixed(rh_info_t * info, unsigned long start, int size, coreturnstart;}+EXPORT_SYMBOL_GPL(rh_alloc_fixed);/* Deallocate the memory previously allocated by one of the rh_alloc functions.*Thereturnvalueisthesizeofthedeallocatedblock,oranegativenumber
@@ -626,6 +635,7 @@ int rh_free(rh_info_t * info, unsigned long start)returnsize;}+EXPORT_SYMBOL_GPL(rh_free);intrh_get_stats(rh_info_t*info,intwhat,intmax_stats,rh_stats_t*stats){
@@ -663,6 +673,7 @@ int rh_get_stats(rh_info_t * info, int what, int max_stats, rh_stats_t * stats)returnnr;}+EXPORT_SYMBOL_GPL(rh_get_stats);intrh_set_owner(rh_info_t*info,unsignedlongstart,constchar*owner){
@@ -687,6 +698,7 @@ int rh_set_owner(rh_info_t * info, unsigned long start, const char *owner)returnsize;}+EXPORT_SYMBOL_GPL(rh_set_owner);voidrh_dump(rh_info_t*info){
From: Grant Likely <hidden> Date: 2007-10-14 04:42:17
From: Sylvain Munaut <redacted>
On the mpc5200b the ccr register is 32 bits wide while on the
mpc5200 it's only 16 bits. It's up to the driver to use the
correct format depending on the chip it's running on.
The 5200b also offers some more registers & status in AC97
mode. Again, if not running on a 5200b the driver should not
use those.
Signed-off-by: Sylvain Munaut <redacted>
Signed-off-by: Grant Likely <redacted>
---
include/asm-ppc/mpc52xx_psc.h | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
From: Grant Likely <hidden> Date: 2007-10-14 04:42:18
From: Sylvain Munaut <redacted>
This is the microcode for the ATA task and the associated
support code.
The microcode itself comes directly from the offical
API (v2.2)
Signed-off-by: Sylvain Munaut <redacted>
Signed-off-by: Grant Likely <redacted>
---
arch/powerpc/sysdev/bestcomm/Kconfig | 7 +
arch/powerpc/sysdev/bestcomm/Makefile | 2
arch/powerpc/sysdev/bestcomm/ata.c | 154 ++++++++++++++++++++++++++
arch/powerpc/sysdev/bestcomm/ata.h | 37 ++++++
arch/powerpc/sysdev/bestcomm/bcom_ata_task.c | 67 +++++++++++
5 files changed, 267 insertions(+), 0 deletions(-)
@@ -0,0 +1,154 @@+/*+*BestcommATAtaskdriver+*+*+*Patternedafterbestcomm/fec.cbyDaleFarnsworth<dfarnsworth@mvista.com>+*2003-2004(c)MontaVista,Software,Inc.+*+*Copyright(C)2006-2007SylvainMunaut<tnt@246tNt.com>+*Copyright(C)2006Freescale-JohnRigby+*+*ThisfileislicensedunderthetermsoftheGNUGeneralPublicLicense+*version2.Thisprogramislicensed"as is"withoutanywarrantyofany+*kind,whetherexpressorimplied.+*/++#include<linux/kernel.h>+#include<linux/module.h>+#include<linux/types.h>+#include<asm/io.h>++#include"bestcomm.h"+#include"bestcomm_priv.h"+#include"ata.h"+++/* ======================================================================== */+/* Task image/var/inc */+/* ======================================================================== */++/* ata task image */+externu32bcom_ata_task[];++/* ata task vars that need to be set before enabling the task */+structbcom_ata_var{+u32enable;/* (u16*) address of task's control register */+u32bd_base;/* (struct bcom_bd*) beginning of ring buffer */+u32bd_last;/* (struct bcom_bd*) end of ring buffer */+u32bd_start;/* (struct bcom_bd*) current bd */+u32buffer_size;/* size of receive buffer */+};++/* ata task incs that need to be set before enabling the task */+structbcom_ata_inc{+u16pad0;+s16incr_bytes;+u16pad1;+s16incr_dst;+u16pad2;+s16incr_src;+};+++/* ======================================================================== */+/* Task support code */+/* ======================================================================== */++structbcom_task*+bcom_ata_init(intqueue_len,intmaxbufsize)+{+structbcom_task*tsk;+structbcom_ata_var*var;+structbcom_ata_inc*inc;++tsk=bcom_task_alloc(queue_len,sizeof(structbcom_ata_bd),0);+if(!tsk)+returnNULL;++tsk->flags=BCOM_FLAGS_NONE;++bcom_ata_reset_bd(tsk);++var=(structbcom_ata_var*)bcom_task_var(tsk->tasknum);+inc=(structbcom_ata_inc*)bcom_task_inc(tsk->tasknum);++if(bcom_load_image(tsk->tasknum,bcom_ata_task)){+bcom_task_free(tsk);+returnNULL;+}++var->enable=bcom_eng->regs_base++offsetof(structmpc52xx_sdma,tcr[tsk->tasknum]);+var->bd_base=tsk->bd_pa;+var->bd_last=tsk->bd_pa+((tsk->num_bd-1)*tsk->bd_size);+var->bd_start=tsk->bd_pa;+var->buffer_size=maxbufsize;++/* Configure some stuff */+bcom_set_task_pragma(tsk->tasknum,BCOM_ATA_PRAGMA);+bcom_set_task_auto_start(tsk->tasknum,tsk->tasknum);++out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ATA_RX],BCOM_IPR_ATA_RX);+out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ATA_TX],BCOM_IPR_ATA_TX);++out_be32(&bcom_eng->regs->IntPend,1<<tsk->tasknum);/* Clear ints */++returntsk;+}+EXPORT_SYMBOL_GPL(bcom_ata_init);++voidbcom_ata_rx_prepare(structbcom_task*tsk)+{+structbcom_ata_inc*inc;++inc=(structbcom_ata_inc*)bcom_task_inc(tsk->tasknum);++inc->incr_bytes=-(s16)sizeof(u32);+inc->incr_src=0;+inc->incr_dst=sizeof(u32);++bcom_set_initiator(tsk->tasknum,BCOM_INITIATOR_ATA_RX);+}+EXPORT_SYMBOL_GPL(bcom_ata_rx_prepare);++voidbcom_ata_tx_prepare(structbcom_task*tsk)+{+structbcom_ata_inc*inc;++inc=(structbcom_ata_inc*)bcom_task_inc(tsk->tasknum);++inc->incr_bytes=-(s16)sizeof(u32);+inc->incr_src=sizeof(u32);+inc->incr_dst=0;++bcom_set_initiator(tsk->tasknum,BCOM_INITIATOR_ATA_TX);+}+EXPORT_SYMBOL_GPL(bcom_ata_tx_prepare);++voidbcom_ata_reset_bd(structbcom_task*tsk)+{+structbcom_ata_var*var;++/* Reset all BD */+memset(tsk->bd,0x00,tsk->num_bd*tsk->bd_size);++tsk->index=0;+tsk->outdex=0;++var=(structbcom_ata_var*)bcom_task_var(tsk->tasknum);+var->bd_start=var->bd_base;+}+EXPORT_SYMBOL_GPL(bcom_ata_reset_bd);++voidbcom_ata_release(structbcom_task*tsk)+{+/* Nothing special for the ATA tasks */+bcom_task_free(tsk);+}+EXPORT_SYMBOL_GPL(bcom_ata_release);+++MODULE_DESCRIPTION("BestComm ATA task driver");+MODULE_AUTHOR("John Rigby");+MODULE_LICENSE("GPL v2");+
From: Grant Likely <hidden> Date: 2007-10-14 04:42:18
From: Sylvain Munaut <redacted>
This patch adds support for the core of the BestComm API
for the Freescale MPC5200(b). The BestComm engine is a
microcode-controlled / tasks-based DMA used by several
of the onchip devices.
Setting up the tasks / memory allocation and all common
low level functions are handled by this patch.
The specifics details of each tasks and their microcode
are split-out in separate patches.
This is not the official API, but a much cleaner one.
(hopefully)
Signed-off-by: Sylvain Munaut <redacted>
Signed-off-by: Grant Likely <redacted>
---
arch/powerpc/platforms/Kconfig | 2
arch/powerpc/sysdev/Makefile | 1
arch/powerpc/sysdev/bestcomm/Kconfig | 18 +
arch/powerpc/sysdev/bestcomm/Makefile | 8
arch/powerpc/sysdev/bestcomm/bestcomm.c | 528 ++++++++++++++++++++++++++
arch/powerpc/sysdev/bestcomm/bestcomm.h | 190 +++++++++
arch/powerpc/sysdev/bestcomm/bestcomm_priv.h | 334 ++++++++++++++++
arch/powerpc/sysdev/bestcomm/sram.c | 177 +++++++++
arch/powerpc/sysdev/bestcomm/sram.h | 54 +++
9 files changed, 1312 insertions(+), 0 deletions(-)
@@ -0,0 +1,528 @@+/*+*DriverforMPC52xxprocessorBestCommperipheralcontroller+*+*+*Copyright(C)2006-2007SylvainMunaut<tnt@246tNt.com>+*Copyright(C)2005VarmaElectronicsOy,+*(byAndreyVolkov<avolkov@varma-el.com>)+*Copyright(C)2003-2004MontaVista,Software,Inc.+*(byDaleFarnsworth<dfarnsworth@mvista.com>)+*+*ThisfileislicensedunderthetermsoftheGNUGeneralPublicLicense+*version2.Thisprogramislicensed"as is"withoutanywarrantyofany+*kind,whetherexpressorimplied.+*/++#include<linux/module.h>+#include<linux/kernel.h>+#include<linux/slab.h>+#include<linux/of.h>+#include<linux/of_device.h>+#include<linux/of_platform.h>+#include<asm/io.h>+#include<asm/irq.h>+#include<asm/mpc52xx.h>++#include"sram.h"+#include"bestcomm_priv.h"+#include"bestcomm.h"++#define DRIVER_NAME "bestcomm-core"+++structbcom_engine*bcom_eng=NULL;+EXPORT_SYMBOL_GPL(bcom_eng);/* needed for inline functions */+++/* ======================================================================== */+/* Public and private API */+/* ======================================================================== */++/* Private API */++structbcom_task*+bcom_task_alloc(intbd_count,intbd_size,intpriv_size)+{+inti,tasknum=-1;+structbcom_task*tsk;++/* Get and reserve a task num */+spin_lock(&bcom_eng->lock);++for(i=0;i<BCOM_MAX_TASKS;i++)+if(!bcom_eng->tdt[i].stop){/* we use stop as a marker */+bcom_eng->tdt[i].stop=0xfffffffful;/* dummy addr */+tasknum=i;+break;+}++spin_unlock(&bcom_eng->lock);++if(tasknum<0)+returnNULL;++/* Allocate our structure */+tsk=kzalloc(sizeof(structbcom_task)+priv_size,GFP_KERNEL);+if(!tsk)+gotoerror;++tsk->tasknum=tasknum;+if(priv_size)+tsk->priv=(void*)tsk+sizeof(structbcom_task);++/* Get IRQ of that task */+tsk->irq=irq_of_parse_and_map(bcom_eng->ofnode,tsk->tasknum);+if(tsk->irq==NO_IRQ)+gotoerror;++/* Init the BDs, if needed */+if(bd_count){+tsk->cookie=kmalloc(sizeof(void*)*bd_count,GFP_KERNEL);+if(!tsk->cookie)+gotoerror;++tsk->bd=bcom_sram_alloc(bd_count*bd_size,4,&tsk->bd_pa);+if(!tsk->bd)+gotoerror;+memset(tsk->bd,0x00,bd_count*bd_size);++tsk->num_bd=bd_count;+tsk->bd_size=bd_size;+}++returntsk;++error:+if(tsk){+if(tsk->irq!=NO_IRQ)+irq_dispose_mapping(tsk->irq);+bcom_sram_free(tsk->bd);+kfree(tsk->cookie);+kfree(tsk);+}++bcom_eng->tdt[tasknum].stop=0;++returnNULL;+}+EXPORT_SYMBOL_GPL(bcom_task_alloc);++void+bcom_task_free(structbcom_task*tsk)+{+/* Stop the task */+bcom_disable_task(tsk->tasknum);++/* Clear TDT */+bcom_eng->tdt[tsk->tasknum].start=0;+bcom_eng->tdt[tsk->tasknum].stop=0;++/* Free everything */+irq_dispose_mapping(tsk->irq);+bcom_sram_free(tsk->bd);+kfree(tsk->cookie);+kfree(tsk);+}+EXPORT_SYMBOL_GPL(bcom_task_free);++int+bcom_load_image(inttask,u32*task_image)+{+structbcom_task_header*hdr=(structbcom_task_header*)task_image;+structbcom_tdt*tdt;+u32*desc,*var,*inc;+u32*desc_src,*var_src,*inc_src;++/* Safety checks */+if(hdr->magic!=BCOM_TASK_MAGIC){+printk(KERN_ERRDRIVER_NAME+": Trying to load invalid microcode\n");+return-EINVAL;+}++if((task<0)||(task>=BCOM_MAX_TASKS)){+printk(KERN_ERRDRIVER_NAME+": Trying to load invalid task %d\n",task);+return-EINVAL;+}++/* Initial load or reload */+tdt=&bcom_eng->tdt[task];++if(tdt->start){+desc=bcom_task_desc(task);+if(hdr->desc_size!=bcom_task_num_descs(task)){+printk(KERN_ERRDRIVER_NAME+": Trying to reload wrong task image "+"(%d size %d/%d)!\n",+task,+hdr->desc_size,+bcom_task_num_descs(task));+return-EINVAL;+}+}else{+phys_addr_tstart_pa;++desc=bcom_sram_alloc(hdr->desc_size*sizeof(u32),4,&start_pa);+if(!desc)+return-ENOMEM;++tdt->start=start_pa;+tdt->stop=start_pa+((hdr->desc_size-1)*sizeof(u32));+}++var=bcom_task_var(task);+inc=bcom_task_inc(task);++/* Clear & copy */+memset(var,0x00,BCOM_VAR_SIZE);+memset(inc,0x00,BCOM_INC_SIZE);++desc_src=(u32*)(hdr+1);+var_src=desc_src+hdr->desc_size;+inc_src=var_src+hdr->var_size;++memcpy(desc,desc_src,hdr->desc_size*sizeof(u32));+memcpy(var+hdr->first_var,var_src,hdr->var_size*sizeof(u32));+memcpy(inc,inc_src,hdr->inc_size*sizeof(u32));++return0;+}+EXPORT_SYMBOL_GPL(bcom_load_image);++void+bcom_set_initiator(inttask,intinitiator)+{+inti;+intnum_descs;+u32*desc;+intnext_drd_has_initiator;++bcom_set_tcr_initiator(task,initiator);++/* Just setting tcr is apparently not enough due to some problem */+/* with it. So we just go thru all the microcode and replace in */+/* the DRD directly */++desc=bcom_task_desc(task);+next_drd_has_initiator=1;+num_descs=bcom_task_num_descs(task);++for(i=0;i<num_descs;i++,desc++){+if(!bcom_desc_is_drd(*desc))+continue;+if(next_drd_has_initiator)+if(bcom_desc_initiator(*desc)!=BCOM_INITIATOR_ALWAYS)+bcom_set_desc_initiator(desc,initiator);+next_drd_has_initiator=!bcom_drd_is_extended(*desc);+}+}+EXPORT_SYMBOL_GPL(bcom_set_initiator);+++/* Public API */++void+bcom_enable(structbcom_task*tsk)+{+bcom_enable_task(tsk->tasknum);+}+EXPORT_SYMBOL_GPL(bcom_enable);++void+bcom_disable(structbcom_task*tsk)+{+bcom_disable_task(tsk->tasknum);+}+EXPORT_SYMBOL_GPL(bcom_disable);+++/* ======================================================================== */+/* Engine init/cleanup */+/* ======================================================================== */++/* Function Descriptor table */+/* this will need to be updated if Freescale changes their task code FDT */+staticu32fdt_ops[]={+0xa0045670,/* FDT[48] - load_acc() */+0x80045670,/* FDT[49] - unload_acc() */+0x21800000,/* FDT[50] - and() */+0x21e00000,/* FDT[51] - or() */+0x21500000,/* FDT[52] - xor() */+0x21400000,/* FDT[53] - andn() */+0x21500000,/* FDT[54] - not() */+0x20400000,/* FDT[55] - add() */+0x20500000,/* FDT[56] - sub() */+0x20800000,/* FDT[57] - lsh() */+0x20a00000,/* FDT[58] - rsh() */+0xc0170000,/* FDT[59] - crc8() */+0xc0145670,/* FDT[60] - crc16() */+0xc0345670,/* FDT[61] - crc32() */+0xa0076540,/* FDT[62] - endian32() */+0xa0000760,/* FDT[63] - endian16() */+};+++staticint__devinit+bcom_engine_init(void)+{+inttask;+phys_addr_ttdt_pa,ctx_pa,var_pa,fdt_pa;+unsignedinttdt_size,ctx_size,var_size,fdt_size;++/* Allocate & clear SRAM zones for FDT, TDTs, contexts and vars/incs */+tdt_size=BCOM_MAX_TASKS*sizeof(structbcom_tdt);+ctx_size=BCOM_MAX_TASKS*BCOM_CTX_SIZE;+var_size=BCOM_MAX_TASKS*(BCOM_VAR_SIZE+BCOM_INC_SIZE);+fdt_size=BCOM_FDT_SIZE;++bcom_eng->tdt=bcom_sram_alloc(tdt_size,sizeof(u32),&tdt_pa);+bcom_eng->ctx=bcom_sram_alloc(ctx_size,BCOM_CTX_ALIGN,&ctx_pa);+bcom_eng->var=bcom_sram_alloc(var_size,BCOM_VAR_ALIGN,&var_pa);+bcom_eng->fdt=bcom_sram_alloc(fdt_size,BCOM_FDT_ALIGN,&fdt_pa);++if(!bcom_eng->tdt||!bcom_eng->ctx||!bcom_eng->var||!bcom_eng->fdt){+printk(KERN_ERR"DMA: SRAM alloc failed in engine init !\n");++bcom_sram_free(bcom_eng->tdt);+bcom_sram_free(bcom_eng->ctx);+bcom_sram_free(bcom_eng->var);+bcom_sram_free(bcom_eng->fdt);++return-ENOMEM;+}++memset(bcom_eng->tdt,0x00,tdt_size);+memset(bcom_eng->ctx,0x00,ctx_size);+memset(bcom_eng->var,0x00,var_size);+memset(bcom_eng->fdt,0x00,fdt_size);++/* Copy the FDT for the EU#3 */+memcpy(&bcom_eng->fdt[48],fdt_ops,sizeof(fdt_ops));++/* Initialize Task base structure */+for(task=0;task<BCOM_MAX_TASKS;task++)+{+out_be16(&bcom_eng->regs->tcr[task],0);+out_8(&bcom_eng->regs->ipr[task],0);++bcom_eng->tdt[task].context=ctx_pa;+bcom_eng->tdt[task].var=var_pa;+bcom_eng->tdt[task].fdt=fdt_pa;++var_pa+=BCOM_VAR_SIZE+BCOM_INC_SIZE;+ctx_pa+=BCOM_CTX_SIZE;+}++out_be32(&bcom_eng->regs->taskBar,tdt_pa);++/* Init 'always' initiator */+out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS],BCOM_IPR_ALWAYS);++/* Disable COMM Bus Prefetch, apparently it's not reliable yet */+/* FIXME: This should be done on 5200 and not 5200B ... */+out_be16(&bcom_eng->regs->PtdCntrl,in_be16(&bcom_eng->regs->PtdCntrl)|1);++/* Init lock */+spin_lock_init(&bcom_eng->lock);++return0;+}++staticvoid+bcom_engine_cleanup(void)+{+inttask;++/* Stop all tasks */+for(task=0;task<BCOM_MAX_TASKS;task++)+{+out_be16(&bcom_eng->regs->tcr[task],0);+out_8(&bcom_eng->regs->ipr[task],0);+}++out_be32(&bcom_eng->regs->taskBar,0ul);++/* Release the SRAM zones */+bcom_sram_free(bcom_eng->tdt);+bcom_sram_free(bcom_eng->ctx);+bcom_sram_free(bcom_eng->var);+bcom_sram_free(bcom_eng->fdt);+}+++/* ======================================================================== */+/* OF platform driver */+/* ======================================================================== */++staticint__devinit+mpc52xx_bcom_probe(structof_device*op,conststructof_device_id*match)+{+structdevice_node*ofn_sram;+structresourceres_bcom;++intrv;++/* Inform user we're ok so far */+printk(KERN_INFO"DMA: MPC52xx BestComm driver\n");++/* Get the bestcomm node */+of_node_get(op->node);++/* Prepare SRAM */+ofn_sram=of_find_compatible_node(NULL,"sram","mpc5200-sram");+if(!ofn_sram){+printk(KERN_ERRDRIVER_NAME": "+"No SRAM found in device tree\n");+rv=-ENODEV;+gotoerror_ofput;+}+rv=bcom_sram_init(ofn_sram,DRIVER_NAME);+of_node_put(ofn_sram);++if(rv){+printk(KERN_ERRDRIVER_NAME": "+"Error in SRAM init\n");+gotoerror_ofput;+}++/* Get a clean struct */+bcom_eng=kzalloc(sizeof(structbcom_engine),GFP_KERNEL);+if(!bcom_eng){+printk(KERN_ERRDRIVER_NAME": "+"Can't allocate state structure\n");+rv=-ENOMEM;+gotoerror_sramclean;+}++/* Save the node */+bcom_eng->ofnode=op->node;++/* Get, reserve & map io */+if(of_address_to_resource(op->node,0,&res_bcom)){+printk(KERN_ERRDRIVER_NAME": "+"Can't get resource\n");+rv=-EINVAL;+gotoerror_sramclean;+}++if(!request_mem_region(res_bcom.start,sizeof(structmpc52xx_sdma),+DRIVER_NAME)){+printk(KERN_ERRDRIVER_NAME": "+"Can't request registers region\n");+rv=-EBUSY;+gotoerror_sramclean;+}++bcom_eng->regs_base=res_bcom.start;+bcom_eng->regs=ioremap(res_bcom.start,sizeof(structmpc52xx_sdma));+if(!bcom_eng->regs){+printk(KERN_ERRDRIVER_NAME": "+"Can't map registers\n");+rv=-ENOMEM;+gotoerror_release;+}++/* Now, do the real init */+rv=bcom_engine_init();+if(rv)+gotoerror_unmap;++/* Done ! */+printk(KERN_INFO"DMA: MPC52xx BestComm engine @%08lx ok !\n",+bcom_eng->regs_base);++return0;++/* Error path */+error_unmap:+iounmap(bcom_eng->regs);+error_release:+release_mem_region(res_bcom.start,sizeof(structmpc52xx_sdma));+error_sramclean:+kfree(bcom_eng);+bcom_sram_cleanup();+error_ofput:+of_node_put(op->node);++printk(KERN_ERR"DMA: MPC52xx BestComm init failed !\n");++returnrv;+}+++staticint+mpc52xx_bcom_remove(structof_device*op)+{+/* Clean up the engine */+bcom_engine_cleanup();++/* Cleanup SRAM */+bcom_sram_cleanup();++/* Release regs */+iounmap(bcom_eng->regs);+release_mem_region(bcom_eng->regs_base,sizeof(structmpc52xx_sdma));++/* Release the node */+of_node_put(bcom_eng->ofnode);++/* Release memory */+kfree(bcom_eng);+bcom_eng=NULL;++return0;+}++staticstructof_device_idmpc52xx_bcom_of_match[]={+{+.type="dma-controller",+.compatible="mpc5200-bestcomm",+},+{},+};++MODULE_DEVICE_TABLE(of,mpc52xx_bcom_of_match);+++staticstructof_platform_drivermpc52xx_bcom_of_platform_driver={+.owner=THIS_MODULE,+.name=DRIVER_NAME,+.match_table=mpc52xx_bcom_of_match,+.probe=mpc52xx_bcom_probe,+.remove=mpc52xx_bcom_remove,+.driver={+.name=DRIVER_NAME,+.owner=THIS_MODULE,+},+};+++/* ======================================================================== */+/* Module */+/* ======================================================================== */++staticint__init+mpc52xx_bcom_init(void)+{+returnof_register_platform_driver(&mpc52xx_bcom_of_platform_driver);+}++staticvoid__exit+mpc52xx_bcom_exit(void)+{+of_unregister_platform_driver(&mpc52xx_bcom_of_platform_driver);+}++/* If we're not a module, we must make sure everything is setup before */+/* anyone tries to use us ... that's why we use subsys_initcall instead */+/* of module_init. */+subsys_initcall(mpc52xx_bcom_init);+module_exit(mpc52xx_bcom_exit);++MODULE_DESCRIPTION("Freescale MPC52xx BestComm DMA");+MODULE_AUTHOR("Sylvain Munaut <tnt@246tNt.com>");+MODULE_AUTHOR("Andrey Volkov <avolkov@varma-el.com>");+MODULE_AUTHOR("Dale Farnsworth <dfarnsworth@mvista.com>");+MODULE_LICENSE("GPL v2");+
@@ -0,0 +1,190 @@+/*+*PublicheaderfortheMPC52xxprocessorBestCommdriver+*+*+*Copyright(C)2006SylvainMunaut<tnt@246tNt.com>+*Copyright(C)2005VarmaElectronicsOy,+*(byAndreyVolkov<avolkov@varma-el.com>)+*Copyright(C)2003-2004MontaVista,Software,Inc.+*(byDaleFarnsworth<dfarnsworth@mvista.com>)+*+*ThisfileislicensedunderthetermsoftheGNUGeneralPublicLicense+*version2.Thisprogramislicensed"as is"withoutanywarrantyofany+*kind,whetherexpressorimplied.+*/++#ifndef __BESTCOMM_H__+#define __BESTCOMM_H__++structbcom_bd;/* defined later on ... */+++/* ======================================================================== */+/* Generic task managment */+/* ======================================================================== */++/**+*structbcom_task-StructuredescribingaloadedBestCommtask+*+*Thisstructureisneverbuiltbythedriveritself.It'sbuiltand+*filledtheintermediatelayeroftheBestCommAPI,thetaskdependent+*supportcode.+*+*Mostlikelyyoudon'tneedtopokearoundinsidethisstructure.The+*fieldsareexposedintheheaderjustforthesakeofinlinefunctions+*/+structbcom_task{+unsignedinttasknum;+unsignedintflags;+intirq;++structbcom_bd*bd;+phys_addr_tbd_pa;+void**cookie;+unsignedshortindex;+unsignedshortoutdex;+unsignedintnum_bd;+unsignedintbd_size;++void*priv;+};++#define BCOM_FLAGS_NONE 0x00000000ul+#define BCOM_FLAGS_ENABLE_TASK (1ul << 0)++/**+*bcom_enable-EnableaBestCommtask+*@tsk:TheBestCommtaskstructure+*+*Thisfunctionmakessurethegiventaskisenabledandcanberun+*bytheBestCommengineasneeded+*/+externvoidbcom_enable(structbcom_task*tsk);++/**+*bcom_disable-DisableaBestCommtask+*@tsk:TheBestCommtaskstructure+*+*Thisfunctiondisableagiventask,makingsureit'snotexecuted+*bytheBestCommengine.+*/+externvoidbcom_disable(structbcom_task*tsk);+++/**+*bcom_get_task_irq-ReturnstheirqnumberofaBestCommtask+*@tsk:TheBestCommtaskstructure+*/+staticinlineint+bcom_get_task_irq(structbcom_task*tsk){+returntsk->irq;+}++/* ======================================================================== */+/* BD based tasks helpers */+/* ======================================================================== */++/**+*structbcom_bd-StructuredescribingagenericBestCommbufferdescriptor+*@status:Thecurrentstatusofthisbuffer.Exactmeaningdependsonthe+*tasktype+*@data:Anarrayofu32whosemeaningdependsonthetasktype.+*/+structbcom_bd{+u32status;+u32data[1];/* variable, but at least 1 */+};++#define BCOM_BD_READY 0x40000000ul++/** _bcom_next_index - Get next input index.+*@tsk:pointertotaskstructure+*+*Supportfunction;Devicedriversshouldnotcallthis+*/+staticinlineint+_bcom_next_index(structbcom_task*tsk)+{+return((tsk->index+1)==tsk->num_bd)?0:tsk->index+1;+}++/** _bcom_next_outdex - Get next output index.+*@tsk:pointertotaskstructure+*+*Supportfunction;Devicedriversshouldnotcallthis+*/+staticinlineint+_bcom_next_outdex(structbcom_task*tsk)+{+return((tsk->outdex+1)==tsk->num_bd)?0:tsk->outdex+1;+}++/**+*bcom_queue_empty-ChecksifaBestCommtaskBDqueueisempty+*@tsk:TheBestCommtaskstructure+*/+staticinlineint+bcom_queue_empty(structbcom_task*tsk)+{+returntsk->index==tsk->outdex;+}++/**+*bcom_queue_full-ChecksifaBestCommtaskBDqueueisfull+*@tsk:TheBestCommtaskstructure+*/+staticinlineint+bcom_queue_full(structbcom_task*tsk)+{+returntsk->outdex==_bcom_next_index(tsk);+}++/**+*bcom_buffer_done-ChecksifaBestComm+*@tsk:TheBestCommtaskstructure+*/+staticinlineint+bcom_buffer_done(structbcom_task*tsk)+{+if(bcom_queue_empty(tsk))+return0;+return!(tsk->bd[tsk->outdex].status&BCOM_BD_READY);+}++/**+*bcom_prepare_next_buffer-clearstatusofnextavailablebuffer.+*@tsk:TheBestCommtaskstructure+*+*Returnspointertonextbufferdescriptor+*/+staticinlinestructbcom_bd*+bcom_prepare_next_buffer(structbcom_task*tsk)+{+tsk->bd[tsk->index].status=0;/* cleanup last status */+return&tsk->bd[tsk->index];+}++staticinlinevoid+bcom_submit_next_buffer(structbcom_task*tsk,void*cookie)+{+tsk->cookie[tsk->index]=cookie;+mb();/* ensure the bd is really up-to-date */+tsk->bd[tsk->index].status|=BCOM_BD_READY;+tsk->index=_bcom_next_index(tsk);+if(tsk->flags&BCOM_FLAGS_ENABLE_TASK)+bcom_enable(tsk);+}++staticinlinevoid*+bcom_retrieve_buffer(structbcom_task*tsk,u32*p_status,structbcom_bd**p_bd)+{+void*cookie=tsk->cookie[tsk->outdex];+if(p_status)+*p_status=tsk->bd[tsk->outdex].status;+if(p_bd)+*p_bd=&tsk->bd[tsk->outdex];+tsk->outdex=_bcom_next_outdex(tsk);+returncookie;+}++#endif /* __BESTCOMM_H__ */
@@ -0,0 +1,177 @@+/*+*Simplememoryallocatorforon-boardSRAM+*+*+*Maintainer:SylvainMunaut<tnt@246tNt.com>+*+*Copyright(C)2005SylvainMunaut<tnt@246tNt.com>+*+*ThisfileislicensedunderthetermsoftheGNUGeneralPublicLicense+*version2.Thisprogramislicensed"as is"withoutanywarrantyofany+*kind,whetherexpressorimplied.+*/++#include<linux/kernel.h>+#include<linux/module.h>+#include<linux/slab.h>+#include<linux/spinlock.h>+#include<linux/string.h>+#include<linux/ioport.h>+#include<linux/of.h>++#include<asm/io.h>+#include<asm/mmu.h>++#include"sram.h"+++/* Struct keeping our 'state' */+structbcom_sram*bcom_sram=NULL;+EXPORT_SYMBOL_GPL(bcom_sram);/* needed for inline functions */+++/* ======================================================================== */+/* Public API */+/* ======================================================================== */+/* DO NOT USE in interrupts, if needed in irq handler, we should use the+_irqsaveversionofthespin_locks*/++intbcom_sram_init(structdevice_node*sram_node,char*owner)+{+intrv;+constu32*regaddr_p;+u64regaddr64,size64;+unsignedintpsize;++/* Create our state struct */+if(bcom_sram){+printk(KERN_ERR"%s: bcom_sram_init: "+"Already initialiwed !\n",owner);+return-EBUSY;+}++bcom_sram=kmalloc(sizeof(structbcom_sram),GFP_KERNEL);+if(!bcom_sram){+printk(KERN_ERR"%s: bcom_sram_init: "+"Couldn't allocate internal state !\n",owner);+return-ENOMEM;+}++/* Get address and size of the sram */+regaddr_p=of_get_address(sram_node,0,&size64,NULL);+if(!regaddr_p){+printk(KERN_ERR"%s: bcom_sram_init: "+"Invalid device node !\n",owner);+rv=-EINVAL;+gotoerror_free;+}++regaddr64=of_translate_address(sram_node,regaddr_p);++bcom_sram->base_phys=(phys_addr_t)regaddr64;+bcom_sram->size=(unsignedint)size64;++/* Request region */+if(!request_mem_region(bcom_sram->base_phys,bcom_sram->size,owner)){+printk(KERN_ERR"%s: bcom_sram_init: "+"Couln't request region !\n",owner);+rv=-EBUSY;+gotoerror_free;+}++/* Map SRAM */+/* sram is not really __iomem */+bcom_sram->base_virt=(void*)ioremap(bcom_sram->base_phys,bcom_sram->size);++if(!bcom_sram->base_virt){+printk(KERN_ERR"%s: bcom_sram_init: "+"Map error SRAM zone 0x%08lx (0x%0x)!\n",+owner,bcom_sram->base_phys,bcom_sram->size);+rv=-ENOMEM;+gotoerror_release;+}++/* Create an rheap (defaults to 32 bits word alignment) */+bcom_sram->rh=rh_create(4);++/* Attach the free zones */+#if 0+/* Currently disabled ... for future use only */+reg_addr_p=of_get_property(sram_node,"available",&psize);+#else+regaddr_p=NULL;+psize=0;+#endif++if(!regaddr_p||!psize){+/* Attach the whole zone */+rh_attach_region(bcom_sram->rh,0,bcom_sram->size);+}else{+/* Attach each zone independently */+while(psize>=2*sizeof(u32)){+phys_addr_tzbase=of_translate_address(sram_node,regaddr_p);+rh_attach_region(bcom_sram->rh,zbase-bcom_sram->base_phys,regaddr_p[1]);+regaddr_p+=2;+psize-=2*sizeof(u32);+}+}++/* Init our spinlock */+spin_lock_init(&bcom_sram->lock);++return0;++error_release:+release_mem_region(bcom_sram->base_phys,bcom_sram->size);+error_free:+kfree(bcom_sram);+bcom_sram=NULL;++returnrv;+}+EXPORT_SYMBOL_GPL(bcom_sram_init);++voidbcom_sram_cleanup(void)+{+/* Free resources */+if(bcom_sram){+rh_destroy(bcom_sram->rh);+iounmap((void__iomem*)bcom_sram->base_virt);+release_mem_region(bcom_sram->base_phys,bcom_sram->size);+kfree(bcom_sram);+bcom_sram=NULL;+}+}+EXPORT_SYMBOL_GPL(bcom_sram_cleanup);++void*bcom_sram_alloc(intsize,intalign,phys_addr_t*phys)+{+unsignedlongoffset;++spin_lock(&bcom_sram->lock);+offset=rh_alloc_align(bcom_sram->rh,size,align,NULL);+spin_unlock(&bcom_sram->lock);++if(IS_ERR_VALUE(offset))+returnNULL;++*phys=bcom_sram->base_phys+offset;+returnbcom_sram->base_virt+offset;+}+EXPORT_SYMBOL_GPL(bcom_sram_alloc);++voidbcom_sram_free(void*ptr)+{+unsignedlongoffset;++if(!ptr)+return;++offset=ptr-bcom_sram->base_virt;++spin_lock(&bcom_sram->lock);+rh_free(bcom_sram->rh,offset);+spin_unlock(&bcom_sram->lock);+}+EXPORT_SYMBOL_GPL(bcom_sram_free);+
@@ -0,0 +1,54 @@+/*+*Handlingofasramzoneforbestcomm+*+*+*Copyright(C)2007SylvainMunaut<tnt@246tNt.com>+*+*ThisfileislicensedunderthetermsoftheGNUGeneralPublicLicense+*version2.Thisprogramislicensed"as is"withoutanywarrantyofany+*kind,whetherexpressorimplied.+*/++#ifndef __BESTCOMM_SRAM_H__+#define __BESTCOMM_SRAM_H__++#include<asm/rheap.h>+#include<asm/mmu.h>+#include<linux/spinlock.h>+++/* Structure used internally */+/* The internals are here for the inline functions+*sake,certainlynotfortheusertomesswith!+*/+structbcom_sram{+phys_addr_tbase_phys;+void*base_virt;+unsignedintsize;+rh_info_t*rh;+spinlock_tlock;+};++externstructbcom_sram*bcom_sram;+++/* Public API */+externintbcom_sram_init(structdevice_node*sram_node,char*owner);+externvoidbcom_sram_cleanup(void);++externvoid*bcom_sram_alloc(intsize,intalign,phys_addr_t*phys);+externvoidbcom_sram_free(void*ptr);++staticinlinephys_addr_tbcom_sram_va2pa(void*va){+returnbcom_sram->base_phys++(unsignedlong)(va-bcom_sram->base_virt);+}++staticinlinevoid*bcom_sram_pa2va(phys_addr_tpa){+returnbcom_sram->base_virt++(unsignedlong)(pa-bcom_sram->base_phys);+}+++#endif /* __BESTCOMM_SRAM_H__ */+
From: Grant Likely <hidden> Date: 2007-10-14 04:42:20
From: Sylvain Munaut <redacted>
This is the microcode for the FEC task and the associated
support code.
The microcode itself comes directly from the offical
API (v2.2)
Signed-off-by: Sylvain Munaut <redacted>
Signed-off-by: Grant Likely <redacted>
---
arch/powerpc/sysdev/bestcomm/Kconfig | 7 +
arch/powerpc/sysdev/bestcomm/Makefile | 2
arch/powerpc/sysdev/bestcomm/bcom_fec_rx_task.c | 78 +++++++
arch/powerpc/sysdev/bestcomm/bcom_fec_tx_task.c | 91 ++++++++
arch/powerpc/sysdev/bestcomm/fec.c | 270 +++++++++++++++++++++++
arch/powerpc/sysdev/bestcomm/fec.h | 48 ++++
6 files changed, 496 insertions(+), 0 deletions(-)
@@ -0,0 +1,270 @@+/*+*BestcommFECtasksdriver+*+*+*Copyright(C)2006-2007SylvainMunaut<tnt@246tNt.com>+*Copyright(C)2003-2004MontaVista,Software,Inc.+*(byDaleFarnsworth<dfarnsworth@mvista.com>)+*+*ThisfileislicensedunderthetermsoftheGNUGeneralPublicLicense+*version2.Thisprogramislicensed"as is"withoutanywarrantyofany+*kind,whetherexpressorimplied.+*/++#include<linux/kernel.h>+#include<linux/module.h>+#include<linux/types.h>+#include<asm/io.h>++#include"bestcomm.h"+#include"bestcomm_priv.h"+#include"fec.h"+++/* ======================================================================== */+/* Task image/var/inc */+/* ======================================================================== */++/* fec tasks images */+externu32bcom_fec_rx_task[];+externu32bcom_fec_tx_task[];++/* rx task vars that need to be set before enabling the task */+structbcom_fec_rx_var{+u32enable;/* (u16*) address of task's control register */+u32fifo;/* (u32*) address of fec's fifo */+u32bd_base;/* (struct bcom_bd*) beginning of ring buffer */+u32bd_last;/* (struct bcom_bd*) end of ring buffer */+u32bd_start;/* (struct bcom_bd*) current bd */+u32buffer_size;/* size of receive buffer */+};++/* rx task incs that need to be set before enabling the task */+structbcom_fec_rx_inc{+u16pad0;+s16incr_bytes;+u16pad1;+s16incr_dst;+u16pad2;+s16incr_dst_ma;+};++/* tx task vars that need to be set before enabling the task */+structbcom_fec_tx_var{+u32DRD;/* (u32*) address of self-modified DRD */+u32fifo;/* (u32*) address of fec's fifo */+u32enable;/* (u16*) address of task's control register */+u32bd_base;/* (struct bcom_bd*) beginning of ring buffer */+u32bd_last;/* (struct bcom_bd*) end of ring buffer */+u32bd_start;/* (struct bcom_bd*) current bd */+u32buffer_size;/* set by uCode for each packet */+};++/* tx task incs that need to be set before enabling the task */+structbcom_fec_tx_inc{+u16pad0;+s16incr_bytes;+u16pad1;+s16incr_src;+u16pad2;+s16incr_src_ma;+};++/* private structure in the task */+structbcom_fec_priv{+phys_addr_tfifo;+intmaxbufsize;+};+++/* ======================================================================== */+/* Task support code */+/* ======================================================================== */++structbcom_task*+bcom_fec_rx_init(intqueue_len,phys_addr_tfifo,intmaxbufsize)+{+structbcom_task*tsk;+structbcom_fec_priv*priv;++tsk=bcom_task_alloc(queue_len,sizeof(structbcom_fec_bd),+sizeof(structbcom_fec_priv));+if(!tsk)+returnNULL;++tsk->flags=BCOM_FLAGS_NONE;++priv=tsk->priv;+priv->fifo=fifo;+priv->maxbufsize=maxbufsize;++if(bcom_fec_rx_reset(tsk)){+bcom_task_free(tsk);+returnNULL;+}++returntsk;+}+EXPORT_SYMBOL_GPL(bcom_fec_rx_init);++int+bcom_fec_rx_reset(structbcom_task*tsk)+{+structbcom_fec_priv*priv=tsk->priv;+structbcom_fec_rx_var*var;+structbcom_fec_rx_inc*inc;++/* Shutdown the task */+bcom_disable_task(tsk->tasknum);++/* Reset the microcode */+var=(structbcom_fec_rx_var*)bcom_task_var(tsk->tasknum);+inc=(structbcom_fec_rx_inc*)bcom_task_inc(tsk->tasknum);++if(bcom_load_image(tsk->tasknum,bcom_fec_rx_task))+return-1;++var->enable=bcom_eng->regs_base++offsetof(structmpc52xx_sdma,tcr[tsk->tasknum]);+var->fifo=(u32)priv->fifo;+var->bd_base=tsk->bd_pa;+var->bd_last=tsk->bd_pa+((tsk->num_bd-1)*tsk->bd_size);+var->bd_start=tsk->bd_pa;+var->buffer_size=priv->maxbufsize;++inc->incr_bytes=-(s16)sizeof(u32);/* These should be in the */+inc->incr_dst=sizeof(u32);/* task image, but we stick */+inc->incr_dst_ma=sizeof(u8);/* to the official ones */++/* Reset the BDs */+tsk->index=0;+tsk->outdex=0;++memset(tsk->bd,0x00,tsk->num_bd*tsk->bd_size);++/* Configure some stuff */+bcom_set_task_pragma(tsk->tasknum,BCOM_FEC_RX_BD_PRAGMA);+bcom_set_task_auto_start(tsk->tasknum,tsk->tasknum);++out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_FEC_RX],BCOM_IPR_FEC_RX);++out_be32(&bcom_eng->regs->IntPend,1<<tsk->tasknum);/* Clear ints */++return0;+}+EXPORT_SYMBOL_GPL(bcom_fec_rx_reset);++void+bcom_fec_rx_release(structbcom_task*tsk)+{+/* Nothing special for the FEC tasks */+bcom_task_free(tsk);+}+EXPORT_SYMBOL_GPL(bcom_fec_rx_release);++++/* Return 2nd to last DRD */+/* This is an ugly hack, but at least it's only done+onceatinitialization*/+staticu32*self_modified_drd(inttasknum)+{+u32*desc;+intnum_descs;+intdrd_count;+inti;++num_descs=bcom_task_num_descs(tasknum);+desc=bcom_task_desc(tasknum)+num_descs-1;+drd_count=0;+for(i=0;i<num_descs;i++,desc--)+if(bcom_desc_is_drd(*desc)&&++drd_count==3)+break;+returndesc;+}++structbcom_task*+bcom_fec_tx_init(intqueue_len,phys_addr_tfifo)+{+structbcom_task*tsk;+structbcom_fec_priv*priv;++tsk=bcom_task_alloc(queue_len,sizeof(structbcom_fec_bd),+sizeof(structbcom_fec_priv));+if(!tsk)+returnNULL;++tsk->flags=BCOM_FLAGS_ENABLE_TASK;++priv=tsk->priv;+priv->fifo=fifo;++if(bcom_fec_tx_reset(tsk)){+bcom_task_free(tsk);+returnNULL;+}++returntsk;+}+EXPORT_SYMBOL_GPL(bcom_fec_tx_init);++int+bcom_fec_tx_reset(structbcom_task*tsk)+{+structbcom_fec_priv*priv=tsk->priv;+structbcom_fec_tx_var*var;+structbcom_fec_tx_inc*inc;++/* Shutdown the task */+bcom_disable_task(tsk->tasknum);++/* Reset the microcode */+var=(structbcom_fec_tx_var*)bcom_task_var(tsk->tasknum);+inc=(structbcom_fec_tx_inc*)bcom_task_inc(tsk->tasknum);++if(bcom_load_image(tsk->tasknum,bcom_fec_tx_task))+return-1;++var->enable=bcom_eng->regs_base++offsetof(structmpc52xx_sdma,tcr[tsk->tasknum]);+var->fifo=(u32)priv->fifo;+var->DRD=bcom_sram_va2pa(self_modified_drd(tsk->tasknum));+var->bd_base=tsk->bd_pa;+var->bd_last=tsk->bd_pa+((tsk->num_bd-1)*tsk->bd_size);+var->bd_start=tsk->bd_pa;++inc->incr_bytes=-(s16)sizeof(u32);/* These should be in the */+inc->incr_src=sizeof(u32);/* task image, but we stick */+inc->incr_src_ma=sizeof(u8);/* to the official ones */++/* Reset the BDs */+tsk->index=0;+tsk->outdex=0;++memset(tsk->bd,0x00,tsk->num_bd*tsk->bd_size);++/* Configure some stuff */+bcom_set_task_pragma(tsk->tasknum,BCOM_FEC_TX_BD_PRAGMA);+bcom_set_task_auto_start(tsk->tasknum,tsk->tasknum);++out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_FEC_TX],BCOM_IPR_FEC_TX);++out_be32(&bcom_eng->regs->IntPend,1<<tsk->tasknum);/* Clear ints */++return0;+}+EXPORT_SYMBOL_GPL(bcom_fec_tx_reset);++void+bcom_fec_tx_release(structbcom_task*tsk)+{+/* Nothing special for the FEC tasks */+bcom_task_free(tsk);+}+EXPORT_SYMBOL_GPL(bcom_fec_tx_release);+++MODULE_DESCRIPTION("BestComm FEC tasks driver");+MODULE_AUTHOR("Dale Farnsworth <dfarnsworth@mvista.com>");+MODULE_LICENSE("GPL v2");+
From: Grant Likely <hidden> Date: 2007-10-14 04:42:25
From: Sylvain Munaut <redacted>
Instead of having in the makefile all the option that
requires rheap, we define a configuration symbol
and when needed we make sure it's selected.
Signed-off-by: Sylvain Munaut <redacted>
Signed-off-by: Grant Likely <redacted>
---
arch/powerpc/Kconfig | 4 ++++
arch/powerpc/lib/Makefile | 5 +----
arch/powerpc/platforms/Kconfig | 2 ++
arch/powerpc/platforms/Kconfig.cputype | 1 +
arch/ppc/Kconfig | 6 ++++++
5 files changed, 14 insertions(+), 4 deletions(-)
@@ -23,6 +22,4 @@ ifeq ($(CONFIG_PPC64),y)obj-$(CONFIG_SMP)+=locks.oendif-# Temporary hack until we have migrated to asm-powerpc-obj-$(CONFIG_8xx)+=rheap.o-obj-$(CONFIG_CPM2)+=rheap.o+obj-$(CONFIG_PPC_LIB_RHEAP)+=rheap.o
From: Grant Likely <hidden> Date: 2007-10-14 04:42:26
From: Sylvain Munaut <redacted>
This is the microcode for the GenBD task and the associated
support code. This is a generic task that copy data to/from
a hardware FIFO. This is currently locked to 32bits wide
access but could be extended as needed.
The microcode itself comes directly from the offical
API (v2.2)
Signed-off-by: Sylvain Munaut <redacted>
Signed-off-by: Grant Likely <redacted>
---
arch/powerpc/sysdev/bestcomm/Kconfig | 7 +
arch/powerpc/sysdev/bestcomm/Makefile | 2
arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.c | 63 +++++
arch/powerpc/sysdev/bestcomm/bcom_gen_bd_tx_task.c | 69 +++++
arch/powerpc/sysdev/bestcomm/gen_bd.c | 260 ++++++++++++++++++++
arch/powerpc/sysdev/bestcomm/gen_bd.h | 48 ++++
6 files changed, 449 insertions(+), 0 deletions(-)
@@ -0,0 +1,260 @@+/*+*DriverforMPC52xxprocessorBestCommGeneralBufferDescriptor+*+*Copyright(C)2007SylvainMunaut<tnt@246tNt.com>+*Copyright(C)2006AppSpecComputerTechnologiesCorp.+*JeffGibbons<jeff.gibbons@appspec.com>+*+*Thisprogramisfreesoftware;youcanredistributeitand/ormodifyit+*underthetermsoftheGNUGeneralPublicLicenseversion2aspublished+*bytheFreeSoftwareFoundation.+*+*/++#include<linux/version.h>+#include<linux/module.h>+#include<linux/kernel.h>+#include<linux/string.h>+#include<linux/types.h>+#include<asm/errno.h>+#include<asm/io.h>++#include<asm/mpc52xx.h>++#include"bestcomm.h"+#include"bestcomm_priv.h"+#include"gen_bd.h"+++/* ======================================================================== */+/* Task image/var/inc */+/* ======================================================================== */++/* gen_bd tasks images */+externu32bcom_gen_bd_rx_task[];+externu32bcom_gen_bd_tx_task[];++/* rx task vars that need to be set before enabling the task */+structbcom_gen_bd_rx_var{+u32enable;/* (u16*) address of task's control register */+u32fifo;/* (u32*) address of gen_bd's fifo */+u32bd_base;/* (struct bcom_bd*) beginning of ring buffer */+u32bd_last;/* (struct bcom_bd*) end of ring buffer */+u32bd_start;/* (struct bcom_bd*) current bd */+u32buffer_size;/* size of receive buffer */+};++/* rx task incs that need to be set before enabling the task */+structbcom_gen_bd_rx_inc{+u16pad0;+s16incr_bytes;+u16pad1;+s16incr_dst;+};++/* tx task vars that need to be set before enabling the task */+structbcom_gen_bd_tx_var{+u32fifo;/* (u32*) address of gen_bd's fifo */+u32enable;/* (u16*) address of task's control register */+u32bd_base;/* (struct bcom_bd*) beginning of ring buffer */+u32bd_last;/* (struct bcom_bd*) end of ring buffer */+u32bd_start;/* (struct bcom_bd*) current bd */+u32buffer_size;/* set by uCode for each packet */+};++/* tx task incs that need to be set before enabling the task */+structbcom_gen_bd_tx_inc{+u16pad0;+s16incr_bytes;+u16pad1;+s16incr_src;+u16pad2;+s16incr_src_ma;+};++/* private structure */+structbcom_gen_bd_priv{+phys_addr_tfifo;+intinitiator;+intipr;+intmaxbufsize;+};+++/* ======================================================================== */+/* Task support code */+/* ======================================================================== */++structbcom_task*+bcom_gen_bd_rx_init(intqueue_len,phys_addr_tfifo,+intinitiator,intipr,intmaxbufsize)+{+structbcom_task*tsk;+structbcom_gen_bd_priv*priv;++tsk=bcom_task_alloc(queue_len,sizeof(structbcom_gen_bd),+sizeof(structbcom_gen_bd_priv));+if(!tsk)+returnNULL;++tsk->flags=BCOM_FLAGS_NONE;++priv=tsk->priv;+priv->fifo=fifo;+priv->initiator=initiator;+priv->ipr=ipr;+priv->maxbufsize=maxbufsize;++if(bcom_gen_bd_rx_reset(tsk)){+bcom_task_free(tsk);+returnNULL;+}++returntsk;+}+EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_init);++int+bcom_gen_bd_rx_reset(structbcom_task*tsk)+{+structbcom_gen_bd_priv*priv=tsk->priv;+structbcom_gen_bd_rx_var*var;+structbcom_gen_bd_rx_inc*inc;++/* Shutdown the task */+bcom_disable_task(tsk->tasknum);++/* Reset the microcode */+var=(structbcom_gen_bd_rx_var*)bcom_task_var(tsk->tasknum);+inc=(structbcom_gen_bd_rx_inc*)bcom_task_inc(tsk->tasknum);++if(bcom_load_image(tsk->tasknum,bcom_gen_bd_rx_task))+return-1;++var->enable=bcom_eng->regs_base++offsetof(structmpc52xx_sdma,tcr[tsk->tasknum]);+var->fifo=(u32)priv->fifo;+var->bd_base=tsk->bd_pa;+var->bd_last=tsk->bd_pa+((tsk->num_bd-1)*tsk->bd_size);+var->bd_start=tsk->bd_pa;+var->buffer_size=priv->maxbufsize;++inc->incr_bytes=-(s16)sizeof(u32);+inc->incr_dst=sizeof(u32);++/* Reset the BDs */+tsk->index=0;+tsk->outdex=0;++memset(tsk->bd,0x00,tsk->num_bd*tsk->bd_size);++/* Configure some stuff */+bcom_set_task_pragma(tsk->tasknum,BCOM_GEN_RX_BD_PRAGMA);+bcom_set_task_auto_start(tsk->tasknum,tsk->tasknum);++out_8(&bcom_eng->regs->ipr[priv->initiator],priv->ipr);+bcom_set_initiator(tsk->tasknum,priv->initiator);++out_be32(&bcom_eng->regs->IntPend,1<<tsk->tasknum);/* Clear ints */++return0;+}+EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_reset);++void+bcom_gen_bd_rx_release(structbcom_task*tsk)+{+/* Nothing special for the GenBD tasks */+bcom_task_free(tsk);+}+EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_release);+++externstructbcom_task*+bcom_gen_bd_tx_init(intqueue_len,phys_addr_tfifo,+intinitiator,intipr)+{+structbcom_task*tsk;+structbcom_gen_bd_priv*priv;++tsk=bcom_task_alloc(queue_len,sizeof(structbcom_gen_bd),+sizeof(structbcom_gen_bd_priv));+if(!tsk)+returnNULL;++tsk->flags=BCOM_FLAGS_NONE;++priv=tsk->priv;+priv->fifo=fifo;+priv->initiator=initiator;+priv->ipr=ipr;++if(bcom_gen_bd_tx_reset(tsk)){+bcom_task_free(tsk);+returnNULL;+}++returntsk;+}+EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_init);++int+bcom_gen_bd_tx_reset(structbcom_task*tsk)+{+structbcom_gen_bd_priv*priv=tsk->priv;+structbcom_gen_bd_tx_var*var;+structbcom_gen_bd_tx_inc*inc;++/* Shutdown the task */+bcom_disable_task(tsk->tasknum);++/* Reset the microcode */+var=(structbcom_gen_bd_tx_var*)bcom_task_var(tsk->tasknum);+inc=(structbcom_gen_bd_tx_inc*)bcom_task_inc(tsk->tasknum);++if(bcom_load_image(tsk->tasknum,bcom_gen_bd_tx_task))+return-1;++var->enable=bcom_eng->regs_base++offsetof(structmpc52xx_sdma,tcr[tsk->tasknum]);+var->fifo=(u32)priv->fifo;+var->bd_base=tsk->bd_pa;+var->bd_last=tsk->bd_pa+((tsk->num_bd-1)*tsk->bd_size);+var->bd_start=tsk->bd_pa;++inc->incr_bytes=-(s16)sizeof(u32);+inc->incr_src=sizeof(u32);+inc->incr_src_ma=sizeof(u8);++/* Reset the BDs */+tsk->index=0;+tsk->outdex=0;++memset(tsk->bd,0x00,tsk->num_bd*tsk->bd_size);++/* Configure some stuff */+bcom_set_task_pragma(tsk->tasknum,BCOM_GEN_TX_BD_PRAGMA);+bcom_set_task_auto_start(tsk->tasknum,tsk->tasknum);++out_8(&bcom_eng->regs->ipr[priv->initiator],priv->ipr);+bcom_set_initiator(tsk->tasknum,priv->initiator);++out_be32(&bcom_eng->regs->IntPend,1<<tsk->tasknum);/* Clear ints */++return0;+}+EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_reset);++void+bcom_gen_bd_tx_release(structbcom_task*tsk)+{+/* Nothing special for the GenBD tasks */+bcom_task_free(tsk);+}+EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_release);+++MODULE_DESCRIPTION("BestComm General Buffer Descriptor tasks driver");+MODULE_AUTHOR("Jeff Gibbons <jeff.gibbons@appspec.com>");+MODULE_LICENSE("GPL v2");+
From: Sven Luther <hidden> Date: 2007-10-14 11:51:32
On Sat, Oct 13, 2007 at 10:42:05PM -0600, Grant Likely wrote:
From: Sylvain Munaut <redacted>
This patch adds support for the core of the BestComm API
for the Freescale MPC5200(b). The BestComm engine is a
microcode-controlled / tasks-based DMA used by several
of the onchip devices.
Setting up the tasks / memory allocation and all common
low level functions are handled by this patch.
The specifics details of each tasks and their microcode
are split-out in separate patches.
This is not the official API, but a much cleaner one.
(hopefully)
Signed-off-by: Sylvain Munaut <redacted>
Signed-off-by: Grant Likely <redacted>
Hi Grant, ...
I am unsure if this is a regression with regard to Sylvain's patch, or
somethign else, but it is no more possible to build bestcomm modular :
ERROR: "bcom_enable" [drivers/net/fec_mpc52xx/fec_mpc52xx.ko] undefined!
ERROR: "bcom_disable" [drivers/net/fec_mpc52xx/fec_mpc52xx.ko] undefined!
ERROR: "bcom_task_alloc" [arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd.ko] undefined!
ERROR: "bcom_sram" [arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd.ko] undefined!
ERROR: "bcom_load_image" [arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd.ko] undefined!
ERROR: "bcom_task_free" [arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd.ko] undefined!
ERROR: "bcom_eng" [arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd.ko] undefined!
ERROR: "bcom_set_initiator" [arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd.ko] undefined!
ERROR: "bcom_task_alloc" [arch/powerpc/sysdev/bestcomm/bestcomm-fec.ko] undefined!
ERROR: "bcom_sram" [arch/powerpc/sysdev/bestcomm/bestcomm-fec.ko] undefined!
ERROR: "bcom_load_image" [arch/powerpc/sysdev/bestcomm/bestcomm-fec.ko] undefined!
ERROR: "bcom_task_free" [arch/powerpc/sysdev/bestcomm/bestcomm-fec.ko] undefined!
ERROR: "bcom_eng" [arch/powerpc/sysdev/bestcomm/bestcomm-fec.ko] undefined!
ERROR: "bcom_task_alloc" [arch/powerpc/sysdev/bestcomm/bestcomm-ata.ko] undefined!
ERROR: "bcom_sram" [arch/powerpc/sysdev/bestcomm/bestcomm-ata.ko] undefined!
ERROR: "bcom_load_image" [arch/powerpc/sysdev/bestcomm/bestcomm-ata.ko] undefined!
ERROR: "bcom_task_free" [arch/powerpc/sysdev/bestcomm/bestcomm-ata.ko] undefined!
ERROR: "bcom_eng" [arch/powerpc/sysdev/bestcomm/bestcomm-ata.ko] undefined!
ERROR: "bcom_set_initiator" [arch/powerpc/sysdev/bestcomm/bestcomm-ata.ko] undefined!
.config snipplet leading to this :
CONFIG_PPC_BESTCOMM=m
CONFIG_PPC_BESTCOMM_ATA=m
CONFIG_PPC_BESTCOMM_FEC=m
CONFIG_PPC_BESTCOMM_GEN_BD=m
CONFIG_FEC_MPC52xx=m
CONFIG_FEC_MPC52xx_MDIO=m
This is building against the 2.6.23 tree, with assorted debian patches
applied, and the latest version of this and domen's patches.
Friendly,
Sven Luther
From: Grant Likely <hidden> Date: 2007-10-14 20:22:18
On 10/14/07, Sven Luther [off-list ref] wrote:
On Sat, Oct 13, 2007 at 10:42:05PM -0600, Grant Likely wrote:
quoted
From: Sylvain Munaut <redacted>
This patch adds support for the core of the BestComm API
for the Freescale MPC5200(b). The BestComm engine is a
microcode-controlled / tasks-based DMA used by several
of the onchip devices.
Setting up the tasks / memory allocation and all common
low level functions are handled by this patch.
The specifics details of each tasks and their microcode
are split-out in separate patches.
This is not the official API, but a much cleaner one.
(hopefully)
Signed-off-by: Sylvain Munaut <redacted>
Signed-off-by: Grant Likely <redacted>
Hi Grant, ...
I am unsure if this is a regression with regard to Sylvain's patch, or
somethign else, but it is no more possible to build bestcomm modular :
Hmmm, interesting. I'll try that out here this afternoon.
g.
ERROR: "bcom_enable" [drivers/net/fec_mpc52xx/fec_mpc52xx.ko] undefined!
ERROR: "bcom_disable" [drivers/net/fec_mpc52xx/fec_mpc52xx.ko] undefined!
ERROR: "bcom_task_alloc" [arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd.ko] undefined!
ERROR: "bcom_sram" [arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd.ko] undefined!
ERROR: "bcom_load_image" [arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd.ko] undefined!
ERROR: "bcom_task_free" [arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd.ko] undefined!
ERROR: "bcom_eng" [arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd.ko] undefined!
ERROR: "bcom_set_initiator" [arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd.ko] undefined!
ERROR: "bcom_task_alloc" [arch/powerpc/sysdev/bestcomm/bestcomm-fec.ko] undefined!
ERROR: "bcom_sram" [arch/powerpc/sysdev/bestcomm/bestcomm-fec.ko] undefined!
ERROR: "bcom_load_image" [arch/powerpc/sysdev/bestcomm/bestcomm-fec.ko] undefined!
ERROR: "bcom_task_free" [arch/powerpc/sysdev/bestcomm/bestcomm-fec.ko] undefined!
ERROR: "bcom_eng" [arch/powerpc/sysdev/bestcomm/bestcomm-fec.ko] undefined!
ERROR: "bcom_task_alloc" [arch/powerpc/sysdev/bestcomm/bestcomm-ata.ko] undefined!
ERROR: "bcom_sram" [arch/powerpc/sysdev/bestcomm/bestcomm-ata.ko] undefined!
ERROR: "bcom_load_image" [arch/powerpc/sysdev/bestcomm/bestcomm-ata.ko] undefined!
ERROR: "bcom_task_free" [arch/powerpc/sysdev/bestcomm/bestcomm-ata.ko] undefined!
ERROR: "bcom_eng" [arch/powerpc/sysdev/bestcomm/bestcomm-ata.ko] undefined!
ERROR: "bcom_set_initiator" [arch/powerpc/sysdev/bestcomm/bestcomm-ata.ko] undefined!
.config snipplet leading to this :
CONFIG_PPC_BESTCOMM=m
CONFIG_PPC_BESTCOMM_ATA=m
CONFIG_PPC_BESTCOMM_FEC=m
CONFIG_PPC_BESTCOMM_GEN_BD=m
CONFIG_FEC_MPC52xx=m
CONFIG_FEC_MPC52xx_MDIO=m
This is building against the 2.6.23 tree, with assorted debian patches
applied, and the latest version of this and domen's patches.
Friendly,
Sven Luther
From: Sven Luther <hidden> Date: 2007-10-14 20:25:36
On Sun, Oct 14, 2007 at 02:22:16PM -0600, Grant Likely wrote:
On 10/14/07, Sven Luther [off-list ref] wrote:
quoted
On Sat, Oct 13, 2007 at 10:42:05PM -0600, Grant Likely wrote:
quoted
From: Sylvain Munaut <redacted>
This patch adds support for the core of the BestComm API
for the Freescale MPC5200(b). The BestComm engine is a
microcode-controlled / tasks-based DMA used by several
of the onchip devices.
Setting up the tasks / memory allocation and all common
low level functions are handled by this patch.
The specifics details of each tasks and their microcode
are split-out in separate patches.
This is not the official API, but a much cleaner one.
(hopefully)
Signed-off-by: Sylvain Munaut <redacted>
Signed-off-by: Grant Likely <redacted>
Hi Grant, ...
I am unsure if this is a regression with regard to Sylvain's patch, or
somethign else, but it is no more possible to build bestcomm modular :
Hmmm, interesting. I'll try that out here this afternoon.
Notice that domen said it was working, so it could have been a
mismanipulation on my part, or some problem with the debian patches.
The older patchset with 2.6.23-rc6 worked fine though, and making the
main bestcomm module builtin solved the error messages. I did not spot
anything obvious when looking at the code.
Friendly;
Sven Luther
From: Grant Likely <hidden> Date: 2007-10-14 21:23:23
On 10/14/07, Sven Luther [off-list ref] wrote:
On Sun, Oct 14, 2007 at 02:22:16PM -0600, Grant Likely wrote:
quoted
On 10/14/07, Sven Luther [off-list ref] wrote:
quoted
On Sat, Oct 13, 2007 at 10:42:05PM -0600, Grant Likely wrote:
quoted
From: Sylvain Munaut <redacted>
This patch adds support for the core of the BestComm API
for the Freescale MPC5200(b). The BestComm engine is a
microcode-controlled / tasks-based DMA used by several
of the onchip devices.
Setting up the tasks / memory allocation and all common
low level functions are handled by this patch.
The specifics details of each tasks and their microcode
are split-out in separate patches.
This is not the official API, but a much cleaner one.
(hopefully)
Signed-off-by: Sylvain Munaut <redacted>
Signed-off-by: Grant Likely <redacted>
Hi Grant, ...
I am unsure if this is a regression with regard to Sylvain's patch, or
somethign else, but it is no more possible to build bestcomm modular :
Hmmm, interesting. I'll try that out here this afternoon.
Notice that domen said it was working, so it could have been a
mismanipulation on my part, or some problem with the debian patches.
The older patchset with 2.6.23-rc6 worked fine though, and making the
main bestcomm module builtin solved the error messages. I did not spot
anything obvious when looking at the code.
Yes, it is a regression. There had been a change to the Makefile.
I've reverted it and it works fine now. I'll repost v3 shortly.
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
From: Sven Luther <hidden> Date: 2007-10-15 06:12:50
On Sun, Oct 14, 2007 at 03:23:21PM -0600, Grant Likely wrote:
On 10/14/07, Sven Luther [off-list ref] wrote:
quoted
On Sun, Oct 14, 2007 at 02:22:16PM -0600, Grant Likely wrote:
quoted
On 10/14/07, Sven Luther [off-list ref] wrote:
quoted
On Sat, Oct 13, 2007 at 10:42:05PM -0600, Grant Likely wrote:
quoted
From: Sylvain Munaut <redacted>
This patch adds support for the core of the BestComm API
for the Freescale MPC5200(b). The BestComm engine is a
microcode-controlled / tasks-based DMA used by several
of the onchip devices.
Setting up the tasks / memory allocation and all common
low level functions are handled by this patch.
The specifics details of each tasks and their microcode
are split-out in separate patches.
This is not the official API, but a much cleaner one.
(hopefully)
Signed-off-by: Sylvain Munaut <redacted>
Signed-off-by: Grant Likely <redacted>
Hi Grant, ...
I am unsure if this is a regression with regard to Sylvain's patch, or
somethign else, but it is no more possible to build bestcomm modular :
Hmmm, interesting. I'll try that out here this afternoon.
Notice that domen said it was working, so it could have been a
mismanipulation on my part, or some problem with the debian patches.
The older patchset with 2.6.23-rc6 worked fine though, and making the
main bestcomm module builtin solved the error messages. I did not spot
anything obvious when looking at the code.
Yes, it is a regression. There had been a change to the Makefile.
I've reverted it and it works fine now. I'll repost v3 shortly.
From: Matt Sealey <hidden> Date: 2007-10-15 11:53:07
My nits:
Grant Likely wrote:
From: Sylvain Munaut <redacted>
+static int __devinit
+bcom_engine_init(void)
Why "bcom" and not "bestcomm"?
+ /* Disable COMM Bus Prefetch, apparently it's not reliable yet */
+ /* FIXME: This should be done on 5200 and not 5200B ... */
+ out_be16(&bcom_eng->regs->PtdCntrl, in_be16(&bcom_eng->regs->PtdCntrl) | 1);
This really, really shouldn't even be here, could it be moved to a platform
init, or switched on a PVR/SVR here?
From: Kumar Gala <hidden> Date: 2007-10-15 13:42:59
On Oct 13, 2007, at 11:41 PM, Grant Likely wrote:
quoted hunk
From: Sylvain Munaut <redacted>
Instead of having in the makefile all the option that
requires rheap, we define a configuration symbol
and when needed we make sure it's selected.
Signed-off-by: Sylvain Munaut <redacted>
Signed-off-by: Grant Likely <redacted>
---
arch/powerpc/Kconfig | 4 ++++
arch/powerpc/lib/Makefile | 5 +----
arch/powerpc/platforms/Kconfig | 2 ++
arch/powerpc/platforms/Kconfig.cputype | 1 +
arch/ppc/Kconfig | 6 ++++++
5 files changed, 14 insertions(+), 4 deletions(-)
From: Grant Likely <hidden> Date: 2007-10-15 13:55:56
On 10/15/07, Kumar Gala [off-list ref] wrote:
On Oct 13, 2007, at 11:41 PM, Grant Likely wrote:
quoted
From: Sylvain Munaut <redacted>
Instead of having in the makefile all the option that
requires rheap, we define a configuration symbol
and when needed we make sure it's selected.
Signed-off-by: Sylvain Munaut <redacted>
Signed-off-by: Grant Likely <redacted>
---
+
+config PPC_LIB_RHEAP
we should really have help for this option.
This is a non-user-selectable option; none of the other
non-user-selectable options have help text.
I can add a comment; want to give me some text to squirt in there?
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
From: Kumar Gala <hidden> Date: 2007-10-15 14:02:49
On Oct 15, 2007, at 8:55 AM, Grant Likely wrote:
On 10/15/07, Kumar Gala [off-list ref] wrote:
quoted
On Oct 13, 2007, at 11:41 PM, Grant Likely wrote:
quoted
From: Sylvain Munaut <redacted>
Instead of having in the makefile all the option that
requires rheap, we define a configuration symbol
and when needed we make sure it's selected.
Signed-off-by: Sylvain Munaut <redacted>
Signed-off-by: Grant Likely <redacted>
---
+
+config PPC_LIB_RHEAP
we should really have help for this option.
This is a non-user-selectable option; none of the other
non-user-selectable options have help text.
I don't see why we can't let users select it (saying that
differently, we should let users have this ability)
I can add a comment; want to give me some text to squirt in there?
grab something out of the comment at the top of lib/rheap.c
- k
From: Grant Likely <hidden> Date: 2007-10-15 14:04:18
On 10/15/07, Matt Sealey [off-list ref] wrote:
My nits:
Grant Likely wrote:
quoted
From: Sylvain Munaut <redacted>
+static int __devinit
+bcom_engine_init(void)
Why "bcom" and not "bestcomm"?
I can type 'bcom' twice as fast. :-) bcom is a suitable shortening;
I'm not concerned about it.
quoted
+ /* Disable COMM Bus Prefetch, apparently it's not reliable yet */
+ /* FIXME: This should be done on 5200 and not 5200B ... */
+ out_be16(&bcom_eng->regs->PtdCntrl, in_be16(&bcom_eng->regs->PtdCntrl) | 1);
This really, really shouldn't even be here, could it be moved to a platform
init, or switched on a PVR/SVR here?
I think I'd like to leave it here for getting this series merged; it
may not be good to have it here; but it's not dangerous either. I'm
trying to keep churn on this series down to a minimum.
Please submit a patch to make this change once it's merged.
From: Kumar Gala <hidden> Date: 2007-10-15 14:06:04
(Comments just on SRAM code)
I think this should be made generic and be utility functionality to
rheap.
CPM, CPM2, QE, L2 SRAM, etc can all use this. I'd rather we didn't
have 3 ways to do the exact same functionality. (cpm_dpalloc,
cpm_dpfree, qe_muram_alloc, qe_muram_free)
see other comments inline.
License
+ * version 2. This program is licensed "as is" without any
warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/of.h>
+
+#include <asm/io.h>
+#include <asm/mmu.h>
+
+#include "sram.h"
+
+
+/* Struct keeping our 'state' */
+struct bcom_sram *bcom_sram = NULL;
shouldn't be global, so we can support more than one SRAM.
+EXPORT_SYMBOL_GPL(bcom_sram); /* needed for inline functions */
+
+
+/*
======================================================================
== */
+/* Public
API */
+/*
======================================================================
== */
+/* DO NOT USE in interrupts, if needed in irq handler, we should
use the
+ _irqsave version of the spin_locks */
+
+int bcom_sram_init(struct device_node *sram_node, char *owner)
+{
+ int rv;
+ const u32 *regaddr_p;
+ u64 regaddr64, size64;
+ unsigned int psize;
+
+ /* Create our state struct */
+ if (bcom_sram) {
+ printk(KERN_ERR "%s: bcom_sram_init: "
+ "Already initialiwed !\n", owner);
+ return -EBUSY;
+ }
+
+ bcom_sram = kmalloc(sizeof(struct bcom_sram), GFP_KERNEL);
License
+ * version 2. This program is licensed "as is" without any
warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __BESTCOMM_SRAM_H__
+#define __BESTCOMM_SRAM_H__
+
+#include <asm/rheap.h>
+#include <asm/mmu.h>
+#include <linux/spinlock.h>
+
+
+/* Structure used internally */
+ /* The internals are here for the inline functions
+ * sake, certainly not for the user to mess with !
+ */
+struct bcom_sram {
+ phys_addr_t base_phys;
+ void *base_virt;
From: Grant Likely <hidden> Date: 2007-10-15 14:06:12
On 10/15/07, Kumar Gala [off-list ref] wrote:
On Oct 15, 2007, at 8:55 AM, Grant Likely wrote:
quoted
On 10/15/07, Kumar Gala [off-list ref] wrote:
quoted
On Oct 13, 2007, at 11:41 PM, Grant Likely wrote:
quoted
From: Sylvain Munaut <redacted>
Instead of having in the makefile all the option that
requires rheap, we define a configuration symbol
and when needed we make sure it's selected.
Signed-off-by: Sylvain Munaut <redacted>
Signed-off-by: Grant Likely <redacted>
---
+
+config PPC_LIB_RHEAP
we should really have help for this option.
This is a non-user-selectable option; none of the other
non-user-selectable options have help text.
I don't see why we can't let users select it (saying that
differently, we should let users have this ability)
Sure; but not in this patch. This patch just changes from one fixed
method for selecting rheap to another.
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
From: Grant Likely <hidden> Date: 2007-10-15 14:20:08
On 10/15/07, Kumar Gala [off-list ref] wrote:
(Comments just on SRAM code)
I think this should be made generic and be utility functionality to
rheap.
CPM, CPM2, QE, L2 SRAM, etc can all use this. I'd rather we didn't
have 3 ways to do the exact same functionality. (cpm_dpalloc,
cpm_dpfree, qe_muram_alloc, qe_muram_free)
Fair enough; but not in this patch set. This series is working
support for bestcomm. To go to the more generic level of being used
by multiple parts should be done in a separate series.
License
+ * version 2. This program is licensed "as is" without any
warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/of.h>
+
+#include <asm/io.h>
+#include <asm/mmu.h>
+
+#include "sram.h"
+
+
+/* Struct keeping our 'state' */
+struct bcom_sram *bcom_sram = NULL;
shouldn't be global, so we can support more than one SRAM.
Again; I agree, but I'm not going to make that change in this series.
quoted
+EXPORT_SYMBOL_GPL(bcom_sram); /* needed for inline functions */
+
+
+/*
======================================================================
== */
+/* Public
API */
+/*
======================================================================
== */
+/* DO NOT USE in interrupts, if needed in irq handler, we should
use the
+ _irqsave version of the spin_locks */
+
+int bcom_sram_init(struct device_node *sram_node, char *owner)
+{
+ int rv;
+ const u32 *regaddr_p;
+ u64 regaddr64, size64;
+ unsigned int psize;
+
+ /* Create our state struct */
+ if (bcom_sram) {
+ printk(KERN_ERR "%s: bcom_sram_init: "
+ "Already initialiwed !\n", owner);
+ return -EBUSY;
+ }
+
+ bcom_sram = kmalloc(sizeof(struct bcom_sram), GFP_KERNEL);
should return this handle to the user.
To be done when this driver is changed to support multiple sram regions.
License
+ * version 2. This program is licensed "as is" without any
warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __BESTCOMM_SRAM_H__
+#define __BESTCOMM_SRAM_H__
+
+#include <asm/rheap.h>
+#include <asm/mmu.h>
+#include <linux/spinlock.h>
+
+
+/* Structure used internally */
+ /* The internals are here for the inline functions
+ * sake, certainly not for the user to mess with !
+ */
+struct bcom_sram {
+ phys_addr_t base_phys;
+ void *base_virt;
I don't think so. ->base_phys is of type phys_addr_t;
(va-bcom_sram->base_virt) is just an offset from ->base_phys.
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
From: Matt Sealey <hidden> Date: 2007-10-15 14:37:12
Grant Likely wrote:
On 10/15/07, Kumar Gala [off-list ref] wrote:
quoted
(Comments just on SRAM code)
I think this should be made generic and be utility functionality to
rheap.
CPM, CPM2, QE, L2 SRAM, etc can all use this. I'd rather we didn't
have 3 ways to do the exact same functionality. (cpm_dpalloc,
cpm_dpfree, qe_muram_alloc, qe_muram_free)
Fair enough; but not in this patch set. This series is working
support for bestcomm. To go to the more generic level of being used
by multiple parts should be done in a separate series.
I suggested this a couple months ago and a couple people here said a
generic SRAM driver would be a bad idea.. (even the tsi1xx and Marvell
chips could use a generic SRAM driver)?
Module probe order comes into play, which is why it was a bad idea; how
do you make sure that SRAM and all it's finer points (which may not be
handled by a generic rheap library - after all, the address, size,
alignment needs to be *passed* to rheap init) is there and probed before
bestcomm, qe ethernet units or cryptography, axe on the 5121e, gigabit
on the marvell, deep sleep code on the 5200b (just listing users atm)
or something or other, without turning the drivers into a hard
dependency of the sram subsystem?
--
Matt Sealey [off-list ref]
Genesi, Manager, Developer Relations
From: Grant Likely <hidden> Date: 2007-10-15 15:09:46
On 10/15/07, Timur Tabi [off-list ref] wrote:
Kumar Gala wrote:
quoted
quoted
If you turn on the QE but don't turn on RHEAP, the build will fail.
Do we want to allow that?
nope.
Is there any way to force RHEAP to be selected when it's a user-selectable option?
Yes, you just add menu text line after the "bool". Bestcomm, QE and
others still select it unconditionally.
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
From: Matt Sealey <hidden> Date: 2007-10-15 20:52:19
Grant Likely wrote:
On 10/15/07, Matt Sealey [off-list ref] wrote:
quoted
My nits:
Grant Likely wrote:
quoted
From: Sylvain Munaut <redacted>
+static int __devinit
+bcom_engine_init(void)
Why "bcom" and not "bestcomm"?
I can type 'bcom' twice as fast. :-) bcom is a suitable shortening;
I'm not concerned about it.
I hate acronyms and shortening for the sake of it.
My IDE highlights known symbols from includes and lets me tab complete them :D
After all once all these APIs are fixed and most of the drivers are implemented
(most of them are, already, anyway, and have been from TaskSomething to sdma_
to bcom_ changes and major API reworks), I wonder why we have to constantly
cut every function definition down to 4 characters rhp_bjz_ywh_moo_purr()
I'd level the same thing at bcom_eng (what's an Eng when it's at home? English?
Engraved? Surely Engine but.. come on :)
There's no real good need to shorten the names of things except when those
shortenings are also used in the documentation - after all, PSC is what Freescale
call a PSC, we wouldn't be making structures called mpc52xx_programmable_serial_controller,
that's redundant, I don't think calling it "bestcomm" (which is it's name) over
"bcom" (which isn't) works to anyone's advantage here.
quoted
quoted
+ /* Disable COMM Bus Prefetch, apparently it's not reliable yet */
+ /* FIXME: This should be done on 5200 and not 5200B ... */
+ out_be16(&bcom_eng->regs->PtdCntrl, in_be16(&bcom_eng->regs->PtdCntrl) | 1);
This really, really shouldn't even be here, could it be moved to a platform
init, or switched on a PVR/SVR here?
I think I'd like to leave it here for getting this series merged; it
may not be good to have it here; but it's not dangerous either. I'm
trying to keep churn on this series down to a minimum.
Why not just accept the churn, and remove those two lines, and someone will
submit a patch to make it work on the 5200 in the appropriate place later?
I don't think "mainlining it" is a good excuse to leave FIXME comments
and little device-specific hacks in drivers.
Please submit a patch to make this change once it's merged.
I'd rather submit a patch containing this fix somewhere else, without having
to touch this driver ever again.
My opinion is that this is a firmware thing, u-boot or openfirmware should
be configuring the system on boot so that they do not do crazy things like
enable the BTIC on a 7447, or leave comm bus prefetch turned on with a 5200 -
in the absense of good firmware, platform support should be used.
This is what Segher tells me we should be doing, but I see you guys "breaking
the rules" all the time.. it makes it hard to justify doing any Linux platform
support if we are beaten with the stick while you guys munch on the carrots..
So, I don't think "reducing churn" justifies leaving it in. Users of 5200
devices who need that fix, can patch their kernels.. users of 5200B and
5121E who do not need that fix, shouldn't be forced to.
--
Matt Sealey [off-list ref]
Genesi, Manager, Developer Relations
From: Matt Sealey <hidden> Date: 2007-10-15 20:54:17
Matt Sealey wrote:
call a PSC, we wouldn't be making structures called mpc52xx_programmable_serial_controller,
that's redundant, I don't think calling it "bestcomm" (which is it's name) over
"bcom" (which isn't) works to anyone's advantage here.
From: Grant Likely <hidden> Date: 2007-10-15 21:06:45
On 10/15/07, Matt Sealey [off-list ref] wrote:
Grant Likely wrote:
quoted
On 10/15/07, Matt Sealey [off-list ref] wrote:
quoted
My nits:
Grant Likely wrote:
quoted
From: Sylvain Munaut <redacted>
+static int __devinit
+bcom_engine_init(void)
Why "bcom" and not "bestcomm"?
I can type 'bcom' twice as fast. :-) bcom is a suitable shortening;
I'm not concerned about it.
I hate acronyms and shortening for the sake of it.
My IDE highlights known symbols from includes and lets me tab complete them :D
After all once all these APIs are fixed and most of the drivers are implemented
(most of them are, already, anyway, and have been from TaskSomething to sdma_
to bcom_ changes and major API reworks), I wonder why we have to constantly
cut every function definition down to 4 characters rhp_bjz_ywh_moo_purr()
I'd level the same thing at bcom_eng (what's an Eng when it's at home? English?
Engraved? Surely Engine but.. come on :)
There's no real good need to shorten the names of things except when those
shortenings are also used in the documentation - after all, PSC is what Freescale
call a PSC, we wouldn't be making structures called mpc52xx_programmable_serial_controller,
that's redundant, I don't think calling it "bestcomm" (which is it's name) over
"bcom" (which isn't) works to anyone's advantage here.
bcom is used consistently within this file and its use is unambiguous.
It doesn't need to be changed for this submission.
quoted
quoted
quoted
+ /* Disable COMM Bus Prefetch, apparently it's not reliable yet */
+ /* FIXME: This should be done on 5200 and not 5200B ... */
+ out_be16(&bcom_eng->regs->PtdCntrl, in_be16(&bcom_eng->regs->PtdCntrl) | 1);
This really, really shouldn't even be here, could it be moved to a platform
init, or switched on a PVR/SVR here?
I think I'd like to leave it here for getting this series merged; it
may not be good to have it here; but it's not dangerous either. I'm
trying to keep churn on this series down to a minimum.
Why not just accept the churn, and remove those two lines, and someone will
submit a patch to make it work on the 5200 in the appropriate place later?
Simple; it's not my series. I'm taking the viewpoint of only changing
what is critical to change to get the code in. Those 2 lines may be
sub-optimal; but they are not *bad* or *dangerous* and they're easily
removed later. I'm pushing this change with my maintainer hat on; not
as the device driver developer and as such only making necessary
changes. My view is that it is *safe* and *good* to merge this driver
as is so that the FEC and other drivers can finally get unblocked.
Send me a patch to change it.
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
From: Sylvain Munaut <redacted>
+static int __devinit
+bcom_engine_init(void)
Why "bcom" and not "bestcomm"?
I can type 'bcom' twice as fast. :-) bcom is a suitable shortening;
I'm not concerned about it.
I prefer bcom as well. Much shorter and there is no ambiguity.
If you use theses, you are writing a 5200 driver. In that context you
should be able to figure out what 'bcom' stands for ... (and if not, maybe
you shouldn't be using them ;)
quoted
quoted
+ /* Disable COMM Bus Prefetch, apparently it's not reliable yet
*/
quoted
+ /* FIXME: This should be done on 5200 and not 5200B ... */
+ out_be16(&bcom_eng->regs->PtdCntrl,
in_be16(&bcom_eng->regs->PtdCntrl) | 1);
This really, really shouldn't even be here, could it be moved to a
platform
init, or switched on a PVR/SVR here?
I think I'd like to leave it here for getting this series merged; it
may not be good to have it here; but it's not dangerous either. I'm
trying to keep churn on this series down to a minimum.
Please submit a patch to make this change once it's merged.
Mmmm.
I think it _does_ belong here. COMM bus prefetch _is_ a bestcomm engine
option.
But indeed as the comment says, it maybe should be enabled on 5200B.
Not a big concern for me at the moment tough.
Sylvain