Other Parts Discussed in Thread: SYSCONFIG
Hello,
I have connected FPGA on GPMC interface using multiplexed IO mode. I have modifiled pin mux in u-boot as per attached mux_data.h file. Also I have done modification in gpmc_init function of u-boot as below:
#else
const u32 gpmc_regs[GPMC_MAX_REG] = { 0x1A00, //GPMC Config 1
M_NAND_GPMC_CONFIG2,
M_NAND_GPMC_CONFIG3,
M_NAND_GPMC_CONFIG4,
M_NAND_GPMC_CONFIG5,
M_NAND_GPMC_CONFIG6,
0
};
// u32 base = CONFIG_SYS_NAND_BASE;
u32 base = 0x18000000;
u32 size = GPMC_SIZE_16M;
#if 0
const u32 gpmc_regs[GPMC_MAX_REG] = { 0, 0, 0, 0, 0, 0, 0 };
u32 size = 0;
u32 base = 0;
#endif
#endif
Below is the device tree modification
&gpmc{
status = "okay";
};
After this much of modification I am trying to access FPGA registers, but I am not able to read any register. When I have probed GPMC signals I have found that there is no any transactions on signals. Even I can not see the clock also.
Here I have attached my fpga driver. Please note that I am using CS3 to access FPGA.
Could anyone please suggest me if I am missing anything?8171.mux_data.h
/*
* copyright (c)2016 eInfochips - All rights reserved.
*
* This software is authored by eInfochips and is eInfochips'
* intelletual property,including the copyrights in all countries in the world.
* This software is provided under a license to use only with all other rights,
* including ownership rights, being retained by eInfochips.
*
* This file may not be distributed, copied or reproduced in any manner,
* electronic or otherwise, without the written consent of eInfochips.
*/
#include <linux/module.h>
#include <linux/slab.h> /* for kmalloc() and kfree() */
#include <linux/major.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/gpio.h>
#include <linux/firmware.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h> /* For put_user and get_user */
#include <linux/moduleparam.h> /* for module parameter */
#include <linux/omap-gpmc.h>
#include <misc/zeiss_fpga.h>
#if 0
#define ZEISS_FPGA_MAJOR (233)
#define ZEISS_FPGA_MINOR (0)
//#define FPGA_INITIAL_REG_SKIP (256)
#define FPGA_INITIAL_REG_SKIP (0)
#define REG_BIT(x) (0x1 << x)
#define FPGA_IOC_MAGIC ('r') /* define all ioctls */
#define FPGA_IOC_MAXNR (28)
#define FPGA_RW_CTRL _IOWR(FPGA_IOC_MAGIC, 1, fpga_ctrl_t)
typedef enum _fpga_reg_t {
VIC_FPGA_INFO = 0,
FPGA_CONFIG_REG_COUNT=0x016F,
} fpga_reg_t;
typedef struct _fpga_ctrl_t {
char rw; /* 0 = write else read */
unsigned char reg;
unsigned short val;
} fpga_ctrl_t;
#endif
static unsigned long fpga_base;
static struct class *fw_class;
static int fpga_device_open = 0;
static void __iomem *base_reg;
void __iomem *fpga_reg[FPGA_CONFIG_REG_COUNT];
EXPORT_SYMBOL(fpga_reg);
int zeiss_fpga_fw_open (struct inode *inode,struct file *file)
{
if (fpga_device_open){
return -EBUSY;
}
fpga_device_open++;
return 0;
}
int zeiss_fpga_fw_close (struct inode *inode,struct file *file)
{
fpga_device_open--;
return 0;
}
static void zeiss_fpga_reg_write(unsigned short val, void __iomem *reg_addr)
{
__raw_writew(val, reg_addr);
}
static unsigned short zeiss_fpga_reg_read(void __iomem *reg_addr)
{
return(__raw_readw(reg_addr));
}
long zeiss_fpga_fw_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int err = 0;
fpga_ctrl_t fpga;
if (_IOC_TYPE(cmd) != FPGA_IOC_MAGIC){
printk("error in ioctl magic no, FPGA_IOC_MAGIC should"
" be \'%c\'\n", _IOC_TYPE(cmd));
return -EINVAL;
}
if (_IOC_NR(cmd) > FPGA_IOC_MAXNR){
printk("error in FPGA_IOC_MAXNR \n");
return -ENOTTY;
}
if (_IOC_DIR(cmd) & _IOC_READ)
err = !access_ok(VERIFY_WRITE, (void __user *)arg,
_IOC_SIZE(cmd));
else if (_IOC_DIR(cmd) & _IOC_WRITE)
err = !access_ok(VERIFY_READ, (void __user *)arg,
_IOC_SIZE(cmd));
if (err){
printk("error in _IOC_READ or _IOC_WRITE \n");
return -EFAULT;
}
/* Get data from user space */
if (copy_from_user(&fpga, (fpga_ctrl_t *) arg,
sizeof(fpga_ctrl_t))) {
err = -EFAULT;
return err;
}
if(cmd == FPGA_RW_CTRL) {
if(true == fpga.rw) {
fpga.val = zeiss_fpga_reg_read(fpga_reg[fpga.reg]);
}
else {
zeiss_fpga_reg_write(fpga.val, fpga_reg[fpga.reg]);
}
/* Set data from user space */
if(copy_to_user((fpga_ctrl_t *)arg, &fpga, sizeof(fpga_ctrl_t)))
err = -EFAULT;
}
else
err = -EINVAL;
return err;
}
static const struct file_operations zeiss_fpga_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = zeiss_fpga_fw_ioctl,
.open = zeiss_fpga_fw_open,
.release = zeiss_fpga_fw_close
};
static int zeiss_fpga_gpmc_mem_map(void)
{
int count;
/* Map FPGA registers into driver memory to access it later on */
/* Increment FPGA_CONFIG_REG_COUNT by 1 if you add configuration reg. */
for(count = 0; count < FPGA_CONFIG_REG_COUNT; count++)
{
fpga_reg[count] = ioremap((fpga_base + FPGA_INITIAL_REG_SKIP + count*2), 0x2);
}
return 0;
}
static int zeiss_fpga_gpmc_mem_unmap(void)
{
int count;
/* Un-mapped FPGA registers */
for(count = 0; count < FPGA_CONFIG_REG_COUNT; count++)
iounmap((void *)fpga_reg[count]);
return 0;
}
static int zeiss_fpga_gpmc_init(void)
{
int err;
err = gpmc_cs_request(3, SZ_16M - 1,(unsigned long*)&fpga_base);
printk("\n$$$$$$$$$ fpga_base = %x $$$$$$$$$$\n", fpga_base);
return err;
}
static void zeiss_fpga_gpmc_clean(void)
{
gpmc_cs_free(1);
}
static int __init zeiss_fpga_init(void)
{
int err = 0;
printk("\n$$$$$$$$$ zeiss_fpga_init $$$$$$$$$$\n");
/* Register the driver */
if(register_chrdev(ZEISS_FPGA_MAJOR, "zeiss_fpga_fw", &zeiss_fpga_fops)) {
printk("zeiss_fpga driver: Unable to register driver\n");
return (-ENODEV);
}
/* Create device class */
fw_class = class_create(THIS_MODULE, "zeiss_fpga_fw");
if (IS_ERR(fw_class)) {
err = PTR_ERR(fw_class);
goto out_chrdev;
}
/* Initilize GPMCMap FPGA configuration register memory to GPMC CS1 memory */
if(zeiss_fpga_gpmc_init() < 0) {
printk("zeiss_fpga driver: unable to initialize gpmc\n");
err = -1;
}
/* Map FPGA configuration register memory to GPMC CS1 progrramed memory */
zeiss_fpga_gpmc_mem_map();
/* Create the device entry of the driver */
device_create(fw_class, NULL, MKDEV(ZEISS_FPGA_MAJOR, ZEISS_FPGA_MINOR), NULL,
"zeiss_fpga_fw");
return err;
out_chrdev:
/* Unregister the driver */
unregister_chrdev(ZEISS_FPGA_MAJOR, "zeiss_fpga_fw");
return err;
}
static void __exit zeiss_fpga_exit(void)
{
/* Remove the device entry of the driver */
device_destroy(fw_class, MKDEV(ZEISS_FPGA_MAJOR, ZEISS_FPGA_MINOR));
class_destroy(fw_class);
zeiss_fpga_gpmc_mem_unmap();
zeiss_fpga_gpmc_clean();
/* Unregister the driver */
unregister_chrdev(ZEISS_FPGA_MAJOR, "zeiss_fpga_fw");
}
module_init(zeiss_fpga_init);
module_exit(zeiss_fpga_exit);
MODULE_AUTHOR("eInfochips");
MODULE_DESCRIPTION("FPGA register access driver");
MODULE_LICENSE("GPL");
