Commit bc970067 authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

Merge branch 'master' of https://github.com/Elphel/linux-elphel

parents 9088aca2 5494dcc7
......@@ -168,5 +168,6 @@ obj-$(CONFIG_ANDROID) += android/
obj-$(CONFIG_ELPHEL393) += elphel/
obj-$(CONFIG_ELPHELDRVONMICROZED) += elphel/
obj-$(CONFIG_ELPHEL393_EXTERNAL) += elphel/
obj-y += net/
......@@ -23,9 +23,16 @@
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/sysfs.h>
#include "ahci.h"
#define DRV_NAME "elphel-ahci"
/*
* FPGA bitstream control address and bit mask. These are used to check whether
* bitstream is loaded or not.
*/
#define BITSTREAM_CTRL_ADDR 0xf800700c
#define BITSTREAM_CTRL_BIT 0x4
/* Property names from device tree, these are specific for the controller */
#define PROP_NAME_CLB_OFFS "clb_offs"
......@@ -35,6 +42,9 @@ static struct ata_port_operations ahci_elphel_ops;
static const struct ata_port_info ahci_elphel_port_info;
static struct scsi_host_template ahci_platform_sht;
static const struct of_device_id ahci_elphel_of_match[];
static const struct attribute_group dev_attr_root_group;
static bool load_driver = false;
struct elphel_ahci_priv {
u32 clb_offs;
......@@ -42,6 +52,48 @@ struct elphel_ahci_priv {
u32 base_addr;
};
static ssize_t set_load_flag(struct device *dev, struct device_attribute *attr,
const char *buff, size_t buff_sz)
{
load_driver = true;
return buff_sz;
}
static int bitstream_loaded(u32 *ptr)
{
u32 val = ioread32(ptr);
if (val & BITSTREAM_CTRL_BIT)
return 1;
else
return 0;
}
static void elphel_defer_load(struct device *dev)
{
bool check_flag = true;
u32 *ctrl_ptr = ioremap_nocache(BITSTREAM_CTRL_ADDR, 4);
dev_info(dev, "AHCI driver loading is deferred. Load bitstream and write 1 into "
"/sys/devices/soc0/amba@0/80000000.elphel-ahci/load_module to continue\n");
while (check_flag) {
if (load_driver) {
if (bitstream_loaded(ctrl_ptr)) {
check_flag = false;
} else {
dev_err(dev, "FPGA bitstream is not loaded or bitstream "
"does not contain AHCI controller\n");
load_driver = false;
}
} else {
msleep(1000);
}
}
load_driver = false;
iounmap(ctrl_ptr);
}
// What about port_stop and freeing/unmapping ?
// Or at least check if it is re-started and memory is already allocated/mapped
static int elphel_port_start(struct ata_port *ap)
......@@ -132,6 +184,13 @@ static int elphel_drv_probe(struct platform_device *pdev)
const struct of_device_id *match;
unsigned int reg_val;
if (&dev->kobj) {
ret = sysfs_create_group(&dev->kobj, &dev_attr_root_group);
if (ret < 0)
return ret;
}
elphel_defer_load(dev);
dev_info(&pdev->dev, "probing Elphel AHCI driver");
dpriv = devm_kzalloc(dev, sizeof(struct elphel_ahci_priv), GFP_KERNEL);
......@@ -166,6 +225,7 @@ static int elphel_drv_probe(struct platform_device *pdev)
static int elphel_drv_remove(struct platform_device *pdev)
{
dev_info(&pdev->dev, "removing Elphel AHCI driver");
sysfs_remove_group(&pdev->dev.kobj, &dev_attr_root_group);
ata_platform_remove_one(pdev);
return 0;
......@@ -231,6 +291,16 @@ static void elphel_qc_prep(struct ata_queued_cmd *qc)
AHCI_CMD_TBL_AR_SZ, DMA_TO_DEVICE);
}
static DEVICE_ATTR(load_module, S_IWUSR | S_IWGRP, NULL, set_load_flag);
static struct attribute *root_dev_attrs[] = {
&dev_attr_load_module.attr,
NULL
};
static const struct attribute_group dev_attr_root_group = {
.attrs = root_dev_attrs,
.name = NULL,
};
static struct ata_port_operations ahci_elphel_ops = {
.inherits = &ahci_ops,
.port_start = elphel_port_start,
......
......@@ -20,4 +20,11 @@ config ELPHEL393_INIT
default y
help
If unsure, say Y.
config ELPHEL393_EXTERNAL
tristate "Compile some Elphel drivers as external modules"
default m
help
If unsure, say Y.
endmenu
......@@ -6,3 +6,6 @@ obj-$(CONFIG_ELPHEL393) += elphel393-pwr.o
obj-$(CONFIG_ELPHEL393) += elphel393-mem.o
obj-$(CONFIG_ELPHELDRVONMICROZED) += elphel393-mem.o
obj-$(CONFIG_ELPHEL393_INIT) += elphel393-init.o
fpgajtag-y := fpgajtag353.o x393.o
obj-$(CONFIG_ELPHEL393_EXTERNAL) += fpgajtag.o
\ No newline at end of file
This diff is collapsed.
/// driver_numbers.h
/// see packages/devices/elphel/Makefile - major numbers should match
//#define CMOSCAM_MAJOR 126
#define X3X3_EXIF_MAJOR 125
#define ELPHEL_MAJOR 126
#define STREAM_MAJOR 127
#define FPGA_MAJOR 129
#define FPGA_JTAG_MAJOR 132
#define FPGA_CLOCK_MAJOR 133
#define X3X3_I2C_MAJOR 134
#define CIRCBUF_MAJOR 135
//#define FRAMEPARS_MAJOR 136
#define FRAMEPARS_MAJOR 130
#define GAMMAS_MAJOR 137
#define HISTOGRAMS_MAJOR 138
//#define IMAGERAW_MAJOR 139
#define IMAGERAW_MAJOR 131
#define IMAGEACQ_MAJOR 140
#define IMU_MAJOR 141
/// MINORS
#define IMU_MINOR 1
#define IMU_CTL_MINOR 2
#define IMAGERAW_MINOR_FRAME 1
#define IMAGERAW_MINOR_FPN 2
#define IMAGERAW_MINOR_UNLOCK 3
#define CMOSCAM_MINOR_RWTABLES 9
#define CMOSCAM_MINOR_CIRCBUF 11
#define CMOSCAM_MINOR_HISTOGRAM 12
#define CMOSCAM_MINOR_JPEAGHEAD 13
#define CMOSCAM_MINOR_GAMMA 14
#define CMOSCAM_MINOR_FRAMEPARS 16
#define CMOSCAM_MINOR_GAMMAS 17
#define CMOSCAM_MINOR_HISTOGRAMS 18
#define CMOSCAM_MINOR_IMAGEACQ 19
#define CMOSCAM_MINOR_HUFFMAN 20
#define FPGACONF_MINOR_IORW 3 /* direct R/W FPGA registers */
#define FPGACONF_MINOR_SDRAM 4 /* read/write SDRAM through PIO */
#define FPGACONF_MINOR_TABLES 6 /// Write FPGA tables directly
#define FPGA_CLOCK_MINOR 2
#define FPGA_CLOCK_MINOR_I2C 2
#define FPGA_CLOCK_MINOR_CLOCKS 3
#define FPGA_JTAG_RESET_MINOR 0 // just close open files
#define FPGA_JTAG_RAW_MINOR 0 // just close open files
#define FPGA_JTAG_MINOR 1
#define FPGA_SJTAG_MINOR 2
#define FPGA_AJTAG_MINOR 3
#define FPGA_JTAG_BOUNDARY_MINOR 5 // read/write boundary pins of the main FPGA
#define FPGA_SJTAG_BOUNDARY_MINOR 6 // read/write boundary pins of the sensor board FPGA
#define FPGA_AJTAG_BOUNDARY_MINOR 7 // read/write boundary pins of the aux board FPGA
#define X3X3_EXIF_EXIF 0 // read encoded Exif data (SEEK_END,
#define X3X3_EXIF_META 1 // write metadata, concurently opened files. All writes atomic
// control/setup devices
#define X3X3_EXIF_TEMPLATE 2 // write Exif template
#define X3X3_EXIF_METADIR 3 // write metadata to Exif header translation (dir_table[MAX_EXIF_FIELDS])
// those 2 files will disable exif_enable and exif_valid, truncate file size to file pointer on release.
#define X3X3_EXIF_TIME 4 // write today/tomorrow date (YYYY:MM:DD) and number of seconds at today/tomorrow
// midnight (00:00:00) in seconds from epoch (long, startting from LSB)
/*
os/linux-2.6/include/asm-cris/elphel/fpgaconfa.h
*/
#ifndef _ASM_FPGACONF_H
#define _ASM_FPGACONF_H
// most defines are from cmoscama.h ...
/* _IOC_TYPE, bits 8 to 15 in ioctl cmd */
#define FPGACONF_IOCTYPE 129
#define FPGACONF_READREG 140 // read 32-bit register (through CSP0)
#define FPGACONF_WRITEREG 141 // write 32-bit register (through CSP0)
#define FPGACONF_READREG_L 142 // read lower 16 bits (through CSP0)
#define FPGACONF_READREG_H 143 // read upper 16 bits (through CSP0)
#define FPGACONF_READREG4 144 // read 32-bit register (through CSP4)
#define FPGACONF_WRITEREG4 145 // write 32-bit register (through CSP4)
#define FPGACONF_READREG_L4 146 // read lower 16 bits (through CSP4)
#define FPGACONF_READREG_H4 147 // read upper 16 bits (through CSP4)
#define FPGACONF_GETSTATE 148 // read FPGA/clock state (minor FPGACONF_MINOR_IORW)
#define FPGACONF_RD_WAITSTATES 150 // read R_WAITSTATES
#define FPGACONF_WR_WAITSTATES 151 // write R_WAITSTATES
#define FPGACONF_START_CAPTURE 152 // start capturing I/O pins to memory (IRQ off!). argument time 1=1ms (actually - longer)
#define FPGACONF_READ_CAPTURE 153 // read captured I/O pins. 1-st time (after FPGACONF_START_CAPTURE) - length, after that - data
#define FPGACONF_CANON_IOBYTE 154 // write/read byte to CANON lens interface
#define FPGACONF_EXT_BOARD_PRESENT 156 // return status of the IO extension board pin
#define FPGA_STATE_LOADED 0x0000FFFF //
#define FPGA_STATE_CLOCKS 0x000F0000 //
#define FPGA_STATE_INITIALIZED 0x00F00000 //
#define FPGA_STATE_SDRAM_INIT 0x00100000 //
#define FPGACONF_CONTROL_REG 155 // modify FPGA control register (0x10)
#define FPGACONF_CR_MODIFY 0x0e //(bit number)<<2 | op; op= 0 - nop, 1 - set, 2 - reset, 3 - toggle)
#define FPGACONF_CR_SHADOW 0x0f
#define FPGACONF_CR_SHADOW1 0x10
/* supported ioctl _IOC_NR's */
#ifndef I2C_WRITEARG
#define I2C_WRITEARG(bus, slave, reg, value) (((bus) << 24) | ((slave) << 16) | ((reg) << 8) | (value))
#define I2C_READARG(bus, slave, reg) (((bus) << 24) | ((slave) << 16) | ((reg) << 8))
#define I2C_ARGBUS(arg) (((arg) >> 24) & 0x1)
#define I2C_ARGSLAVE(arg) (((arg) >> 16) & 0xff)
#define I2C_ARGREG(arg) (((arg) >> 8) & 0xff)
#define I2C_ARGVALUE(arg) ((arg) & 0xff)
#define I2C_WRITEREG 0x1 /* write to an i2c register */
#define I2C_READREG 0x2 /* read from an i2c register */
#endif
#define FPGA_PGM 0x3 /* set FPGA pgm pin */
#define FPGA_STAT 0x4 /* read FPGA pins status (bit 0 - INIT, bit 1 - DOME) */
#define FPGA_JTAG 0x5 /* shift byte to FPGA JTAG */
#define FPGA_PA_RD 0x6 /* write data to port A and shadow */
#define FPGA_PA_WR 0x7 /* write data to port A and shadow */
#ifndef PGA_JTAG_ARG
#define FPGA_JTAG_ARG(tms, len, d) (((tms) << 11) | ((len) << 8) | ((d) & 0xff))
#define FPGA_JTAG_TMS(arg) ((arg >> 11) & 1)
#define FPGA_JTAG_LEN(arg) ((arg >> 8) & 7)
#define FPGA_JTAG_DW(arg) ( arg & 0xff)
#endif
#define _FCCMD(x,y) (_IO(FPGACONF_IOCTYPE, (x << 6) | (y & 0x3f)))
/* i2c errors */
#ifndef ERR_I2C_SCL_ST0
#define ERR_I2C_SCL_ST0 1
#define ERR_I2C_SDA_ST0 2
#define ERR_I2C_SCL_ST1 4
#define ERR_I2C_SDA_ST1 8
#define ERR_I2C_SCL_NOPULLUP 16
#define ERR_I2C_SDA_NOPULLUP 32
/* i2c_diagnose called by i2c_start (?) could not find any problems. Try again start */
#define ERR_I2C_NOTDETECTED 64
#define ERR_I2C_SHORT 128
#define ERR_I2C_BSY 256
#define ERR_I2C_NACK 512
#endif
/* direct register r/w*/
#define IO_CSP0R0 0x10 /* read and return CSP0+0 port data */
#define IO_CSP0W0 0x20 /* write data to port CSP0+0 */
#define IO_CSP0R(a) (IO_CSP0R0 + a)
#define IO_CSP0W(a) (IO_CSP0W0 + a)
#define IO_CSP0_R 1
#define IO_CSP0_W 2
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment