Wei Huang e41856b515 raw/ifpga/base: enhance driver reliability in multi-process
Current hardware protection is based on pthread mutex which
work just for situation of multi-thread in one process. In
multi-process environment, hardware state machine would be
corrupted by concurrent access, that means original pthread
mutex mechanism need be enhanced.

The major modifications in this patch are list below:
1. Create a mutex for adapter in shared memory named
   "mutex.IFPGA:domain:bus:dev.func" when device is probed.
2. Create a shared memory named "IFPGA:domain:bus:dev.func" during opae
   adapter is initializing. There is a reference count in shared memory.
   Shared memory will be destroyed once reference count turned to zero.
3. Two mutexs are created in shared memory and initialized with flag
   PTHREAD_PROCESS_SHARED. One for SPI and the other for I2C. They will
   be passed to SPI and I2C driver subsequently.
4. DTB data in flash will be cached in shared memory. Then MAX10 driver
   can read DTB from shared memory instead of flash. This avoid
   confliction of concurrent flash access between hardware and software.

Signed-off-by: Wei Huang <wei.huang@intel.com>
Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
Acked-by: Rosen Xu <rosen.xu@intel.com>
2020-11-03 23:34:29 +01:00

133 lines
4.3 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2019 Intel Corporation
*/
#ifndef _OPAE_I2C_H
#define _OPAE_I2C_H
#include "opae_osdep.h"
#define ALTERA_I2C_TFR_CMD 0x00 /* Transfer Command register */
#define ALTERA_I2C_TFR_CMD_STA BIT(9) /* send START before byte */
#define ALTERA_I2C_TFR_CMD_STO BIT(8) /* send STOP after byte */
#define ALTERA_I2C_TFR_CMD_RW_D BIT(0) /* Direction of transfer */
#define ALTERA_I2C_RX_DATA 0x04 /* RX data FIFO register */
#define ALTERA_I2C_CTRL 0x8 /* Control register */
#define ALTERA_I2C_CTRL_RXT_SHFT 4 /* RX FIFO Threshold */
#define ALTERA_I2C_CTRL_TCT_SHFT 2 /* TFER CMD FIFO Threshold */
#define ALTERA_I2C_CTRL_BSPEED BIT(1) /* Bus Speed */
#define ALTERA_I2C_CTRL_EN BIT(0) /* Enable Core */
#define ALTERA_I2C_ISER 0xc /* Interrupt Status Enable register */
#define ALTERA_I2C_ISER_RXOF_EN BIT(4) /* Enable RX OVERFLOW IRQ */
#define ALTERA_I2C_ISER_ARB_EN BIT(3) /* Enable ARB LOST IRQ */
#define ALTERA_I2C_ISER_NACK_EN BIT(2) /* Enable NACK DET IRQ */
#define ALTERA_I2C_ISER_RXRDY_EN BIT(1) /* Enable RX Ready IRQ */
#define ALTERA_I2C_ISER_TXRDY_EN BIT(0) /* Enable TX Ready IRQ */
#define ALTERA_I2C_ISR 0x10 /* Interrupt Status register */
#define ALTERA_I2C_ISR_RXOF BIT(4) /* RX OVERFLOW */
#define ALTERA_I2C_ISR_ARB BIT(3) /* ARB LOST */
#define ALTERA_I2C_ISR_NACK BIT(2) /* NACK DET */
#define ALTERA_I2C_ISR_RXRDY BIT(1) /* RX Ready */
#define ALTERA_I2C_ISR_TXRDY BIT(0) /* TX Ready */
#define ALTERA_I2C_STATUS 0x14 /* Status register */
#define ALTERA_I2C_STAT_CORE BIT(0) /* Core Status */
#define ALTERA_I2C_TC_FIFO_LVL 0x18 /* Transfer FIFO LVL register */
#define ALTERA_I2C_RX_FIFO_LVL 0x1c /* Receive FIFO LVL register */
#define ALTERA_I2C_SCL_LOW 0x20 /* SCL low count register */
#define ALTERA_I2C_SCL_HIGH 0x24 /* SCL high count register */
#define ALTERA_I2C_SDA_HOLD 0x28 /* SDA hold count register */
#define ALTERA_I2C_ALL_IRQ (ALTERA_I2C_ISR_RXOF | ALTERA_I2C_ISR_ARB | \
ALTERA_I2C_ISR_NACK | ALTERA_I2C_ISR_RXRDY | \
ALTERA_I2C_ISR_TXRDY)
#define ALTERA_I2C_THRESHOLD 0
#define ALTERA_I2C_DFLT_FIFO_SZ 8
#define ALTERA_I2C_TIMEOUT_US 250000 /* 250ms */
#define I2C_PARAM 0x8
#define I2C_CTRL 0x10
#define I2C_CTRL_R BIT_ULL(9)
#define I2C_CTRL_W BIT_ULL(8)
#define I2C_CTRL_ADDR_MASK GENMASK_ULL(3, 0)
#define I2C_READ 0x18
#define I2C_READ_DATA_VALID BIT_ULL(32)
#define I2C_READ_DATA_MASK GENMASK_ULL(31, 0)
#define I2C_WRITE 0x20
#define I2C_WRITE_DATA_MASK GENMASK_ULL(31, 0)
#define ALTERA_I2C_100KHZ 0
#define ALTERA_I2C_400KHZ 1
/* i2c slave using 16bit address */
#define I2C_FLAG_ADDR16 1
#define I2C_XFER_RETRY 10
struct i2c_core_param {
union {
u64 info;
struct {
u16 fifo_depth:9;
u8 interface:1;
/*reference clock of I2C core in MHz*/
u32 ref_clk:10;
/*Max I2C interface freq*/
u8 max_req:4;
u64 devid:32;
/* number of MAC address*/
u8 nu_macs:8;
};
};
};
struct altera_i2c_dev {
u8 *base;
struct i2c_core_param i2c_param;
u32 fifo_size;
u32 bus_clk_rate; /* i2c bus clock */
u32 i2c_clk; /* i2c input clock */
struct i2c_msg *msg;
size_t msg_len;
int msg_err;
u32 isr_mask;
u8 *buf;
int (*xfer)(struct altera_i2c_dev *dev, struct i2c_msg *msg, int num);
pthread_mutex_t lock;
pthread_mutex_t *mutex; /* multi-process mutex from adapter */
};
/**
* struct i2c_msg: an I2C message
*/
struct i2c_msg {
unsigned int addr;
unsigned int flags;
unsigned int len;
u8 *buf;
};
#define I2C_MAX_OFFSET_LEN 4
enum i2c_msg_flags {
I2C_M_TEN = 0x0010, /*ten-bit chip address*/
I2C_M_RD = 0x0001, /*read data*/
I2C_M_STOP = 0x8000, /*send stop after this message*/
};
struct altera_i2c_dev *altera_i2c_probe(void *base);
void altera_i2c_remove(struct altera_i2c_dev *dev);
int i2c_read(struct altera_i2c_dev *dev, int flags, unsigned int slave_addr,
u32 offset, u8 *buf, u32 count);
int i2c_write(struct altera_i2c_dev *dev, int flags, unsigned int slave_addr,
u32 offset, u8 *buffer, int len);
int i2c_read8(struct altera_i2c_dev *dev, unsigned int slave_addr, u32 offset,
u8 *buf, u32 count);
int i2c_read16(struct altera_i2c_dev *dev, unsigned int slave_addr, u32 offset,
u8 *buf, u32 count);
int i2c_write8(struct altera_i2c_dev *dev, unsigned int slave_addr, u32 offset,
u8 *buf, u32 count);
int i2c_write16(struct altera_i2c_dev *dev, unsigned int slave_addr, u32 offset,
u8 *buf, u32 count);
#endif