gpmc fpga communication

/*gpmc_fpga driver*/


#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/ioctl.h>
#include <plat/gpmc.h>
/* GPMC register offsets */
#define GPMC_REVISION 0x00
#define GPMC_SYSCONFIG 0x10
#define GPMC_SYSSTATUS 0x14
#define GPMC_IRQSTATUS 0x18
#define GPMC_IRQENABLE 0x1c
#define GPMC_TIMEOUT_CONTROL 0x40
#define GPMC_ERR_ADDRESS 0x44
#define GPMC_ERR_TYPE 0x48
#define GPMC_CONFIG 0x50
#define GPMC_STATUS 0x54
#define GPMC_PREFETCH_CONFIG1 0x1e0
#define GPMC_PREFETCH_CONFIG2 0x1e4
#define GPMC_PREFETCH_CONTROL 0x1ec
#define GPMC_PREFETCH_STATUS 0x1f0
#define GPMC_ECC_CONFIG 0x1f4
#define GPMC_ECC_CONTROL 0x1f8
#define GPMC_ECC_SIZE_CONFIG 0x1fc
#define GPMC_ECC1_RESULT 0x200
#define GPMC_ECC_BCH_RESULT_0 0x240


#define GPMC_BASE_ADDR 0x50000000
#define GPMC_CS 1
#define GPMC_CS0 0x60
#define GPMC_CS_SIZE 0x30
#if 1
#define STNAND_GPMC_CONFIG1 0x00000800
#define STNAND_GPMC_CONFIG2 0x00141400 //20-16:CSWROFFTIME,12-8:CSRDOFFTIME,3-0:CSONTIME
#define STNAND_GPMC_CONFIG3 0x00141400
#define STNAND_GPMC_CONFIG4 0x0F010F01 //28-24:WEOFFTIME,19-16:WEONTIME,12-8:OEOFFTIME,3-0:OEONTIME
#define STNAND_GPMC_CONFIG5 0x010C1414 //20-16:RDACCESSTIME means Delay between start cycle time and first data valid  12-8:WRCYCLETIME,4-0:RDCYCLETIME
#define STNAND_GPMC_CONFIG6 0x1F0F0A80 //28-24:WRACCESSTIME
#define STNAND_GPMC_CONFIG7 0x00000F1F //28-24:WRACCESSTIME
#else
1
#define STNAND_GPMC_CONFIG1 (0x00000000 | (0x3<<23) | (0x3<<18) |(0x3<<16))
#define STNAND_GPMC_CONFIG2 0x00011001 //20-16:CSWROFFTIME,12-8:CSRDOFFTIME,3-0:CSONTIME
#define STNAND_GPMC_CONFIG3 0x00020201
//#define STNAND_GPMC_CONFIG4 0x08031003
#define STNAND_GPMC_CONFIG4 0x08031003 //28-24:WEOFFTIME,19-16:WEONTIME,12-8:OEOFFTIME,3-0:OEONTIME
//#define STNAND_GPMC_CONFIG5 0x000f1111 //20-16:RDACCESSTIME means Delay between start cycle time and first data valid
//12-8:WRCYCLETIME,4-0:RDCYCLETIME
#define STNAND_GPMC_CONFIG5 0x00101f1f
#define STNAND_GPMC_CONFIG6 0x0f030080 //28-24:WRACCESSTIME
#endif
static const u32 gpmc_nand[8] = {
   STNAND_GPMC_CONFIG1,
   STNAND_GPMC_CONFIG2,
   STNAND_GPMC_CONFIG3,
   STNAND_GPMC_CONFIG4,
   STNAND_GPMC_CONFIG5,
   STNAND_GPMC_CONFIG6, 
   STNAND_GPMC_CONFIG7, 
   0
};


#define CONTROL_BASE 0x44e10000


unsigned long GPMC_config1;
unsigned long GPMC_config7;
unsigned long bank_addr_start;
static void __iomem *gpmc_base;
static void __iomem *fpga_base;
static void __iomem *control_base;
unsigned long mem_base;


//---------
struct semaphore sem;
unsigned int read_way=1;


#define USER_BUFF_SIZE 128


//------------------------
static void register_configuration(void)
{
   control_base = ioremap(CONTROL_BASE,0x89C);
   iowrite32(0x30,(control_base+0x800)); //configure ad0
   iowrite32(0x30,(control_base+0x804)); //configure ad1
   iowrite32(0x30,(control_base+0x808)); //configure ad2
   iowrite32(0x30,(control_base+0x80C)); //configure ad3
   iowrite32(0x30,(control_base+0x810)); //configure ad4
   iowrite32(0x30,(control_base+0x814)); //configure ad5
   iowrite32(0x30,(control_base+0x818)); //configure ad6
   iowrite32(0x30,(control_base+0x81C)); //configure ad7
   iowrite32(0x08,(control_base+0x870)); //configure wait0
   iowrite32(0x08,(control_base+0x874)); //configure wpn
   iowrite32(0x08,(control_base+0x880)); //configure csn1
   iowrite32(0x08,(control_base+0x890)); //configure advn ale
   iowrite32(0x08,(control_base+0x894)); //configure oen ren
   iowrite32(0x08,(control_base+0x898)); //configure we
   iowrite32(0x08,(control_base+0x89C)); //configure ben0 cle
}




static void gpmc_write_cs_reg(int cs, int idx, u32 val)
{
void __iomem *reg_addr;
reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx;
//__raw_writel(val, reg_addr);
iowrite32(val,reg_addr);
}
u32 gpmc_read_cs_reg(int cs, int idx)
{
void __iomem *reg_addr;
reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx;
//return __raw_readl(reg_addr);
return ioread32(reg_addr);
}
static void show_gpmc_reg(int cs)
{
u32 val;
int i=0;
for(i=0; i<7; i++)
{
val = gpmc_read_cs_reg(cs, GPMC_CS_CONFIG1 + i*4);
printk(KERN_INFO"gpmc cs%d  GPMC_CS_CONFIG%d reg: 0x%08x\n",cs, i+1, val);
}
/*gpmc_cs_get_memconf(cs);
printk(KERN_INFO"\n");*/
}
static void gpmc_write_reg(int idx, u32 val)
{
//writel(val, gpmc_base + idx);
iowrite32(val, gpmc_base + idx);
}
static u32 gpmc_read_reg(int idx)
{
//return readl(gpmc_base + idx);
return ioread32(gpmc_base + idx);
}






static int am335_setup(void)
{
u32 val;


register_configuration();
sema_init(&sem,1);


gpmc_base = ioremap(GPMC_BASE_ADDR,SZ_4K);


    printk("Getting Chip Select\n");
    val = gpmc_read_reg(GPMC_REVISION);
    printk("GPMC revision %d.%d\n", (val >> 4) & 0x0f, val & 0x0f);


gpmc_write_reg(GPMC_IRQENABLE, 0);
gpmc_write_reg(GPMC_TIMEOUT_CONTROL, 0);


gpmc_write_cs_reg(GPMC_CS, GPMC_CS_CONFIG1, gpmc_nand[0]);
gpmc_write_cs_reg(GPMC_CS, GPMC_CS_CONFIG2, gpmc_nand[1]);
gpmc_write_cs_reg(GPMC_CS, GPMC_CS_CONFIG3, gpmc_nand[2]);
gpmc_write_cs_reg(GPMC_CS, GPMC_CS_CONFIG4, gpmc_nand[3]);
gpmc_write_cs_reg(GPMC_CS, GPMC_CS_CONFIG5, gpmc_nand[4]);
gpmc_write_cs_reg(GPMC_CS, GPMC_CS_CONFIG6, gpmc_nand[5]);
// gpmc_write_cs_reg(GPMC_CS, GPMC_CS_CONFIG7, gpmc_nand[6]);


    
    show_gpmc_reg(GPMC_CS);


if (gpmc_cs_request(GPMC_CS, SZ_2K, (unsigned long *)&mem_base) < 0)
{
      printk(KERN_ERR "Failed request for GPMC mem for usrp_e\n");
    return -1;
}
printk("Got CS1, address = %lx\n", mem_base);


if (!request_mem_region(mem_base, SZ_2K, "mem_fpga")) 
{
       printk(KERN_ERR "Request_mem_region failed.\n");
   gpmc_cs_free(GPMC_CS);
   return -1;
}


fpga_base = ioremap(mem_base, SZ_2K);
return 1;
}


static void fpga_relash(void)
{
release_mem_region(mem_base,SZ_2K);
//iounmap((void*)GPMC_BASE_ADDR);
gpmc_cs_free(GPMC_CS);
iounmap(fpga_base);
}
//---------------------------------
static long fpga_wrrd(struct file *filp,unsigned int cmd,unsigned long arg)

    if(down_interruptible(&sem))
       return -ERESTARTSYS;
if(cmd==255)
{
   read_way=255;

else 
{
read_way=cmd;
}
    up(&sem);
    return 1;
}
//------------------------//
static ssize_t fpga_write(struct file *filp,const char __user *buff,size_t count,loff_t *f_pos)
{
    ssize_t status;
    unsigned int data_usr[2];
    if(count==0)
       return 0;
    //printk("the buff[0] is %d,and the buff[1] is %d count is %d\n",buff[0],buff[1],count);


    if(down_interruptible(&sem))
      return -ERESTARTSYS;
    //printk("write is in\n");
    if(copy_from_user(data_usr,buff,count))
{
       status=-EFAULT;
       goto fpga_write_done;
    }
    printk("the data_usr[0] is %d,and the data_usr[1] is %d\n",data_usr[0],data_usr[1]);
    //printk("fpga_write start\n");


    iowrite8(data_usr[1],fpga_base+data_usr[0]);


fpga_write_done:
    up(&sem);
    //printk("write finished\n");
    return status;
}
static ssize_t fpga_read(struct file *filp,char __user *buff,size_t count,loff_t *offp)
{
    unsigned int data_from_fpga[256];
    unsigned int data_from_bit[2];
    unsigned int data_fpga;
    unsigned int hex_data[127];
    int i;


    if(down_interruptible(&sem))
    return -ERESTARTSYS;
    if(read_way==255)
{
        for(i=0;i<256;i++)
{
           data_from_fpga[i]=ioread8(fpga_base+i);
        }


        for(i=0;i<127;i++)
        {
           hex_data[i]=data_from_fpga[i*2+1]<<8 | data_from_fpga[i*2+0];
        }


        if(copy_to_user(buff,hex_data,sizeof(hex_data)))
{
            return 1;
            goto fpga_read_done;
        }
    }
    else if(read_way != 255)
    {
        for(i=0;i<2;i++)
{
            data_from_bit[i]=ioread8(fpga_base+i+read_way*2);
        }
        data_fpga=data_from_bit[1]<<8 | data_from_bit[0];
        if(copy_to_user(buff,&data_fpga,sizeof(data_fpga)))
{
            return 1;
            goto fpga_read_done;
        }
    }
fpga_read_done:
    up(&sem);
    return 1;
}






//--------------------------
static const struct file_operations dev_fops =
{
  .owner = THIS_MODULE,
  .unlocked_ioctl = fpga_wrrd,
  .write=fpga_write,
  .read=fpga_read,
};


static struct miscdevice misc = 
{
  .minor = MISC_DYNAMIC_MINOR,
  .name = "fpga",
  .fops = &dev_fops,
};


/*\C9豸\C7\FD\B6\AFģ\BF\E9\BC\D3\D4غ\AF\CA\FD*/
static int __init dev_init(void)
{
  int ret;


  am335_setup();
  ret = misc_register(&misc);


  printk("am335x initialized minor=%d\n",misc.minor);
  
  
  return ret;
}


/*ģ\BF\E9ж\D4غ\AF\CA\FD*/ 
static void __exit dev_exit(void)
{
   fpga_relash();
   misc_deregister(&misc);
}


module_init(dev_init);
module_exit(dev_exit);
MODULE_AUTHOR("<tq_rd@embedsky.net>");
MODULE_DESCRIPTION("module Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("0.1");


/* test app*/

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>


#define FPGA_DEV "/dev/fpga"
#define PAGE_SIZE 2




int main(void)
{
   int fd,i,res;
   //unsigned char buf[PAGE_SIZE];
unsigned int data_in[2];
   printf("GPMC Test version 1.0-BeagleBone Build on %s %s\n\r",__DATE__,__TIME__); 
   fd=open(FPGA_DEV,O_RDWR);
   if(fd<0)
   {
       printf("Can't Open %s !!!\n\r",FPGA_DEV);
       return -1;
   }
for(i=0;i<30;i++){
data_in[0]=i+4; // the address
data_in[1]=i+1; //the data
write(fd,data_in,sizeof(data_in));
}
/*
data_in[0]=2;
data_in[1]=199;
write(fd,data_in,sizeof(data_in));
data_in[0]=3;
data_in[1]=0;
write(fd,data_in,sizeof(data_in));*/
close(fd);
return 0;




}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GPMC即组策略管理控制台,与windows 2000/2003 Server上传统的组策略编辑器截然不同,由一个全新的MMC管理单元及一整套脚本化的接口组成,提供了集中的组策略管理方案,可以大大减少不正确的组策略可能导致的网络问题并简化组策略相关的安全问题,解决组策略部署中的难点,   减轻了IT管理员们在实施组策略时所承担的沉重包袱。   组策略概述   相信"组策略"(Group Policy)这个名词已经为广大的Windows用户所知晓。微软在Windows NT 4.0中早就有了基于策略的管理--策略编辑器--一个深受NT管理员欢迎的实用程序,但它个并不为大多数用户所掌握并加以应用。为此,微软在 Windows 2000中不但彻底更新了目录服务,而且推出了与这个目录完全集成的策略管理--组策略对象(GPO)。随着Windows 2000的深入应用,组策略的应用也随之遍地开花,影响力远远超过了它的前身。可以说,组策略配置的正确与否将与您整个网络息息相关--虽然您可以完全放弃它,然而,作为一种手段,组策略的成功应用将起到事半功倍的效果。   GPMC的起源   当然,并不是每个人都成功了。随着组策略的深入应用,对这些组策略的管理成了用户最大的负担,而部分用户根本无法预料他所配置的组策略会产生什么样的后果,很多时候结果大大出乎他们的意料。在微软新闻组里,恐怕最著名的组策略问题就是"本地策略不允许您交互式登录"。GPMC(Group Policy Management Console,组策略管理控制台)就是微软在汲取遍布全球的合作伙伴及大量客户反馈的基础上酝酿而成的。   GPMC由一个全新MMC管理单元及一整套脚本化的接口组成,提供了集中的组策略管理方案,可以大大减少不正确的组策略可能导致的网络问题并简化组策略相关的安全问题,解决组策略部署中的难点,减轻了IT管理员们在实施组策略时所承担的沉重包袱
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值