#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm-arm/io.h>
#include <linux/list.h>
#include <linux/moduleparam.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <linux/vmalloc.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include "../../include/pci_vdd.h"
#include "proto.h"
#include "datacomm.h"
#include "../include/hi3511_pci.h"
#ifdef CONFIG_PCI_HOST
struct Hi3511_pci_slave2host_mmap_info Hi3511_slave2host_mmap_info;
extern void *host_recv_buffer;
extern unsigned long host_sharebuffer_start;
extern atomic_t host2slave_irq[HI3511_PCI_SLAVE_NUM];
#else
struct Hi3511_pci_slave_mmap_info Hi3511_slave_mmap_info;
extern unsigned long slave_sharebuffer_start;
extern void *datarelay;
extern unsigned long settings_addr_physics;
extern unsigned long hi3511_slave_interrupt_flag;
unsigned long host_fifo_stuff_physics;
//#define slave_fifo_stuff_physics (slave_sharebuffer_start + PCI_SLAVE_SHARE_MEM_DEFAULT_SIZE)
extern atomic_t slave2host_irq;
#endif
#ifdef CONFIG_PCI_TEST
unsigned long prewake;
static unsigned long afterwake;
#endif
extern void *exchange_buffer_addr;
extern struct semaphore pci_dma_sem;
extern struct hi3511_pci_data_transfer_handle_table *hi3511_pci_handle_table;
extern struct pci_vdd_info hi3511_pci_vdd_info;
extern struct hi3511_dev *hi3511_dev_head;
#define HI_PCI_DEVICE_NUMBER 5
extern struct mem_addr_couple hi3511_mem_map[HI_PCI_DEVICE_NUMBER];
extern struct task_struct *precvthread;
extern atomic_t lostpacknum;
extern atomic_t irq_num;
extern atomic_t readpack_num;
extern atomic_t threadexitflag;
/* 64 bit orderlines. for DMA */
/* 64 bit 对齐DMA*/
#define SHARE_MEMORY_128BIT_ORDERLINES 24
#define SHARE_MEMORY_64BIT_ORDERLINES 8
// lock normal pack
int hi3511_pci_locksend_normal_buffer(int target)
{
#ifdef CONFIG_PCI_HOST
struct slave2host_mmap_info *pmmapinfo = &Hi3511_slave2host_mmap_info.mmapinfo[target - 1]; // target id -1 = mmapinfo number
#else
struct slave_mmap_info *pmmapinfo = &Hi3511_slave_mmap_info.mmapinfo; // slave just have one mmapinfo
#endif
int ret;
hi3511_dbgmsg(HI3511_DBUG_LEVEL1,"hi3511_pci_locksend_normal_buffer target %d",target);
/* lock */
ret = down_interruptible(&pmmapinfo->send.normalsemaphore);
if(ret){
hi3511_dbgmsg(HI3511_DBUG_LEVEL2,"user interrupt %d",1);
return -ERESTARTSYS;
}
hi3511_dbgmsg(HI3511_DBUG_LEVEL1,"down_interruptible end %d",target);
return ret;
}
// release lock normal pack
void hi3511_pci_unlocksend_normal_buffer(int target)
{
#ifdef CONFIG_PCI_HOST
struct slave2host_mmap_info *pmmapinfo = &Hi3511_slave2host_mmap_info.mmapinfo[target - 1]; // target id -1 = mmapinfo number
#else
struct slave_mmap_info *pmmapinfo = &Hi3511_slave_mmap_info.mmapinfo; // slave just have one mmapinfo
#endif
hi3511_dbgmsg(HI3511_DBUG_LEVEL1,"hi3511_pci_unlocksend_normal_buffer target %d",target);
up(&pmmapinfo->send.normalsemaphore);
}
// lock priority pack
int hi3511_pci_locksend_priority_buffer(int target)
{
#ifdef CONFIG_PCI_HOST
struct slave2host_mmap_info *pmmapinfo = &Hi3511_slave2host_mmap_info.mmapinfo[target - 1]; // target id -1 = mmapinfo number
#else
struct slave_mmap_info *pmmapinfo = &Hi3511_slave_mmap_info.mmapinfo; // slave just have one mmapinfo
#endif
int ret = 0;
hi3511_dbgmsg(HI3511_DBUG_LEVEL1,"hi3511_pci_locksend_priority_buffer target %d",target);
/* lock */
ret = down_interruptible(&pmmapinfo->send.prisemaphore);
if(ret){
hi3511_dbgmsg(HI3511_DBUG_LEVEL2,"user interrupt %d",0);
return -ERESTARTSYS;
}
return ret;
}
// release lock priority pack
void hi3511_pci_unlocksend_priority_buffer(int target)
{
#ifdef CONFIG_PCI_HOST
struct slave2host_mmap_info *pmmapinfo = &Hi3511_slave2host_mmap_info.mmapinfo[target - 1]; // target id -1 = mmapinfo number
#else
struct slave_mmap_info *pmmapinfo = &Hi3511_slave_mmap_info.mmapinfo; // slave just have one mmapinfo
#endif
hi3511_dbgmsg(HI3511_DBUG_LEVEL1,"hi3511_pci_unlocksend_priority_buffer target %d",target);
up(&pmmapinfo->send.prisemaphore);
}
// get the readpointer of send buffer
int hi3511_pci_getsend_priority_rwpointer(int target)
{
int ret;
#ifdef CONFIG_PCI_HOST
struct slave2host_mmap_info *pmmapinfo = &Hi3511_slave2host_mmap_info.mmapinfo[target - 1];
ret = __raw_readw((char *)pmmapinfo->send.pripackageflagaddr);
#else
unsigned long int_flags;
struct slave_mmap_info *pmmapinfo = &Hi3511_slave_mmap_info.mmapinfo; // slave just have one mmapinfo
//hi3511_dbgmsg(HI3511_DBUG_LEVEL1,"hi3511_pci_getsend_priority_rwpointer target %d",target);
//local_irq_save(int_flags);
/* lock dma */
int_flags = down_interruptible(&pci_dma_sem);
if(int_flags) {
hi3511_dbgmsg(HI3511_DBUG_LEVEL2,"pci_dma_sem interrupt %d",0);
return -1;
}
hi3511_pci_dma_read(pmmapinfo->send.pripackageflagaddr, (settings_addr_physics+pci_writeable_pripackage_flag_r), 4);
#if 0
hi3511_bridge_ahb_writel(RDMA_PCI_ADDR, pmmapinfo->send.pripackageflagaddr);
hi3511_bridge_ahb_writel(RDMA_AHB_ADDR, (settings_addr_physics+pci_writeable_pripackage_flag_r));
hi3511_bridge_ahb_writel(RDMA_CONTROL, 0x00000461);
while(hi3511_bridge_ahb_readl(RDMA_CONTROL)&0x00000001);
#endif
hi3511_pci_dma_read(pmmapinfo->send.pripackageflagaddr, slave_fifo_stuff_physics,0x100);
#if 0
hi3511_bridge_ahb_writel(RDMA_PCI_ADDR, pmmapinfo->send.pripackageflagaddr);
hi3511_bridge_ahb_writel(RDMA_AHB_ADDR, slave_fifo_stuff_physics);
hi3511_bridge_ahb_writel(RDMA_CONTROL, 0x00010061);
while(hi3511_bridge_ahb_readl(RDMA_CONTROL)&0x00000001);
#endif
ret = (*(volatile unsigned long *)(datarelay+pci_writeable_pripackage_flag_r))&0xffff;
//local_irq_restore(int_flags);
up(&pci_dma_sem);
#endif
return ret;
}
int hi3511_pci_write_priorityhead(struct Hi3511_pci_data_transfer_head *head,void *mmapinfo)
{
const int headsize = sizeof(struct Hi3511_pci_data_transfer_head);
#ifdef CONFIG_PCI_HOST
struct slave2host_mmap_info *pmmapinfo = (struct slave2host_mmap_info *)mmapinfo ;
memcpy((char *)(pmmapinfo->send.pripackageaddr - headsize),head,headsize);
#else
unsigned long int_flags;
struct slave_mmap_info *pmmapinfo = (struct slave_mmap_info *)mmapinfo;
//local_irq_save(int_flags);
/* lock dma */
int_flags = down_interruptible(&pci_dma_sem);
if(int_flags) {
hi3511_dbgmsg(HI3511_DBUG_LEVEL2,"pci_dma_sem interrupt %d",0);
return -1;
}
memcpy(datarelay+write_head, head , headsize);
//pci_dma_lock_test(HI3511_PCI_VIRT_BASE + CPU_CIS_PTR); //from running ko. lock for host-slave dma resource
hi3511_pci_dma_write((pmmapinfo->send.pripackageaddr-headsize), (settings_addr_physics+write_head),headsize);
#if 0
control = (headsize<<8)| 0x71;
//printk("content of head is: \n");
hi3511_dbgmsg(HI3511_DBUG_LEVEL1,"hi3511 slave write the host address is 0x%lx \n",(unsigned long)pmmapinfo->send.pripackageflagaddr-headsize);
hi3511_bridge_ahb_writel(WDMA_PCI_ADDR, pmmapinfo->send.pripackageaddr-headsize);
hi3511_dbgmsg(HI3511_DBUG_LEVEL1,"at the same time hi3511 slave ddr address is 0x%lx \n",(unsigned long)settings_addr_physics);
hi3511_bridge_ahb_writel(WDMA_AHB_ADDR, (settings_addr_physics+write_head));
hi3511_bridge_ahb_writel(WDMA_CONTROL, control);
while(hi3511_bridge_ahb_readl(WDMA_CONTROL)&0x00000001);
#endif
hi3511_pci_dma_write(host_fifo_stuff_physics, (settings_addr_physics+write_head), 0x40);
#if 0
control = (0x40<<8)| 0x71;
hi3511_bridge_ahb_writel(WDMA_PCI_ADDR, host_fifo_stuff_physics);
hi3511_bridge_ahb_writel(WDMA_AHB_ADDR, (settings_addr_physics+write_head));
hi3511_bridge_ahb_writel(WDMA_CONTROL, control);
while(hi3511_bridge_ahb_readl(WDMA_CONTROL)&0x00000001);
#endif
//pci_dma_lock_free(HI3511_PCI_VIRT_BASE + CPU_CIS_PTR);
//local_irq_restore(int_flags);
up(&pci_dma_sem);
#endif
return 0;
}
// host and slave use it with MACRO CONFIG_PCI_HOST
int hi3511_pci_add2buffer_priority(st
评论0