You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
5.7 KiB
223 lines
5.7 KiB
/*
|
|
* Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0
|
|
*/
|
|
|
|
#ifndef _SFC_H
|
|
#define _SFC_H
|
|
|
|
#define SFC_VER_3 0x3
|
|
#define SFC_VER_4 0x4
|
|
#define SFC_VER_5 0x5
|
|
|
|
#define SFC_EN_INT (0) /* enable interrupt */
|
|
#define SFC_EN_DMA (1) /* enable dma */
|
|
#define SFC_FIFO_DEPTH (0x10) /* 16 words */
|
|
|
|
/* FIFO watermark */
|
|
#define SFC_RX_WMARK (SFC_FIFO_DEPTH) /* RX watermark level */
|
|
#define SFC_TX_WMARK (SFC_FIFO_DEPTH) /* TX watermark level */
|
|
#define SFC_RX_WMARK_SHIFT (8)
|
|
#define SFC_TX_WMARK_SHIFT (0)
|
|
|
|
/* return value */
|
|
#define SFC_OK (0)
|
|
#define SFC_ERROR (-1)
|
|
#define SFC_PARAM_ERR (-2)
|
|
#define SFC_TX_TIMEOUT (-3)
|
|
#define SFC_RX_TIMEOUT (-4)
|
|
#define SFC_WAIT_TIMEOUT (-5)
|
|
#define SFC_BUSY_TIMEOUT (-6)
|
|
#define SFC_ECC_FAIL (-7)
|
|
#define SFC_PROG_FAIL (-8)
|
|
#define SFC_ERASE_FAIL (-9)
|
|
|
|
/* SFC_CMD Register */
|
|
#define SFC_ADDR_0BITS (0)
|
|
#define SFC_ADDR_24BITS (1)
|
|
#define SFC_ADDR_32BITS (2)
|
|
#define SFC_ADDR_XBITS (3)
|
|
|
|
#define SFC_WRITE (1)
|
|
#define SFC_READ (0)
|
|
|
|
/* SFC_CTRL Register */
|
|
#define SFC_1BITS_LINE (0)
|
|
#define SFC_2BITS_LINE (1)
|
|
#define SFC_4BITS_LINE (2)
|
|
|
|
#define SFC_ENABLE_DMA BIT(14)
|
|
#define sfc_delay(us) udelay(us)
|
|
|
|
#define DMA_INT BIT(7) /* dma interrupt */
|
|
#define NSPIERR_INT BIT(6) /* Nspi error interrupt */
|
|
#define AHBERR_INT BIT(5) /* Ahb bus error interrupt */
|
|
#define FINISH_INT BIT(4) /* Transfer finish interrupt */
|
|
#define TXEMPTY_INT BIT(3) /* Tx fifo empty interrupt */
|
|
#define TXOF_INT BIT(2) /* Tx fifo overflow interrupt */
|
|
#define RXUF_INT BIT(1) /* Rx fifo underflow interrupt */
|
|
#define RXFULL_INT BIT(0) /* Rx fifo full interrupt */
|
|
|
|
/* SFC_FSR Register*/
|
|
#define SFC_RXFULL BIT(3) /* rx fifo full */
|
|
#define SFC_RXEMPTY BIT(2) /* rx fifo empty */
|
|
#define SFC_TXEMPTY BIT(1) /* tx fifo empty */
|
|
#define SFC_TXFULL BIT(0) /* tx fifo full */
|
|
|
|
/* SFC_RCVR Register */
|
|
#define SFC_RESET BIT(0) /* controller reset */
|
|
|
|
/* SFC_DLL_CTRL Register */
|
|
#define SCLK_SMP_SEL_EN BIT(15) /* SCLK Sampling Selection */
|
|
#define SCLK_SMP_SEL_MAX_V4 0xFF /* SCLK Sampling Selection */
|
|
#define SCLK_SMP_SEL_MAX_V5 0x1FF /* SCLK Sampling Selection */
|
|
|
|
/* SFC_SR Register */
|
|
/* sfc busy flag. When busy, don't try to set the control register */
|
|
#define SFC_BUSY BIT(0)
|
|
|
|
/* SFC_DMA_TRIGGER Register */
|
|
/* Dma start trigger signal. Auto cleared after write */
|
|
#define SFC_DMA_START BIT(0)
|
|
|
|
#define SFC_CTRL 0x00
|
|
#define SFC_IMR 0x04
|
|
#define SFC_ICLR 0x08
|
|
#define SFC_FTLR 0x0C
|
|
#define SFC_RCVR 0x10
|
|
#define SFC_AX 0x14
|
|
#define SFC_ABIT 0x18
|
|
#define SFC_MASKISR 0x1C
|
|
#define SFC_FSR 0x20
|
|
#define SFC_SR 0x24
|
|
#define SFC_RAWISR 0x28
|
|
#define SFC_VER 0x2C
|
|
#define SFC_QOP 0x30
|
|
#define SFC_DLL_CTRL0 0x3C
|
|
#define SFC_DMA_TRIGGER 0x80
|
|
#define SFC_DMA_ADDR 0x84
|
|
#define SFC_LEN_CTRL 0x88
|
|
#define SFC_LEN_EXT 0x8C
|
|
#define SFC_CMD 0x100
|
|
#define SFC_ADDR 0x104
|
|
#define SFC_DATA 0x108
|
|
|
|
union SFCFSR_DATA {
|
|
u32 d32;
|
|
struct {
|
|
unsigned txempty : 1;
|
|
unsigned txfull : 1;
|
|
unsigned rxempty : 1;
|
|
unsigned rxfull : 1;
|
|
unsigned reserved7_4 : 4;
|
|
unsigned txlevel : 5;
|
|
unsigned reserved15_13 : 3;
|
|
unsigned rxlevel : 5;
|
|
unsigned reserved31_21 : 11;
|
|
} b;
|
|
};
|
|
|
|
/* Manufactory ID */
|
|
#define MID_WINBOND 0xEF
|
|
#define MID_GIGADEV 0xC8
|
|
#define MID_MICRON 0x2C
|
|
#define MID_MACRONIX 0xC2
|
|
#define MID_SPANSION 0x01
|
|
#define MID_EON 0x1C
|
|
#define MID_ST 0x20
|
|
#define MID_XTX 0x0B
|
|
#define MID_PUYA 0x85
|
|
#define MID_XMC 0x20
|
|
#define MID_DOSILICON 0xF8
|
|
#define MID_ZBIT 0x5E
|
|
|
|
/*------------------------------ Global Typedefs -----------------------------*/
|
|
enum SFC_DATA_LINES {
|
|
DATA_LINES_X1 = 0,
|
|
DATA_LINES_X2,
|
|
DATA_LINES_X4
|
|
};
|
|
|
|
union SFCCTRL_DATA {
|
|
/* raw register data */
|
|
u32 d32;
|
|
/* register bits */
|
|
struct {
|
|
/* spi mode select */
|
|
unsigned mode : 1;
|
|
/*
|
|
* Shift in phase selection
|
|
* 0: shift in the flash data at posedge sclk_out
|
|
* 1: shift in the flash data at negedge sclk_out
|
|
*/
|
|
unsigned sps : 1;
|
|
unsigned reserved3_2 : 2;
|
|
/* sclk_idle_level_cycles */
|
|
unsigned scic : 4;
|
|
/* Cmd bits number */
|
|
unsigned cmdlines : 2;
|
|
/* Address bits number */
|
|
unsigned addrlines : 2;
|
|
/* Data bits number */
|
|
unsigned datalines : 2;
|
|
/* this bit is not exit in regiseter, just use for code param */
|
|
unsigned enbledma : 1;
|
|
unsigned reserved15 : 1;
|
|
unsigned addrbits : 5;
|
|
unsigned reserved31_21 : 11;
|
|
} b;
|
|
};
|
|
|
|
union SFCCMD_DATA {
|
|
/* raw register data */
|
|
u32 d32;
|
|
/* register bits */
|
|
struct {
|
|
/* Command that will send to Serial Flash */
|
|
unsigned cmd : 8;
|
|
/* Dummy bits number */
|
|
unsigned dummybits : 4;
|
|
/* 0: read, 1: write */
|
|
unsigned rw : 1;
|
|
/* Continuous read mode */
|
|
unsigned readmode : 1;
|
|
/* Address bits number */
|
|
unsigned addrbits : 2;
|
|
/* Transferred bytes number */
|
|
unsigned datasize : 14;
|
|
/* Chip select */
|
|
unsigned cs : 2;
|
|
} b;
|
|
};
|
|
|
|
struct rk_sfc_op {
|
|
union SFCCMD_DATA sfcmd;
|
|
union SFCCTRL_DATA sfctrl;
|
|
};
|
|
|
|
#define IDB_BLOCK_TAG_ID 0xFCDC8C3B
|
|
|
|
struct id_block_tag {
|
|
u32 id;
|
|
u32 version;
|
|
u32 flags;
|
|
u16 boot_img_offset;
|
|
u8 reserved1[10];
|
|
u32 dev_param[8];
|
|
u8 reserved2[506 - 56];
|
|
u16 data_img_len;
|
|
u16 boot_img_len;
|
|
u8 reserved3[512 - 510];
|
|
} __packed;
|
|
|
|
int sfc_init(void __iomem *reg_addr);
|
|
int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size);
|
|
u16 sfc_get_version(void);
|
|
void sfc_clean_irq(void);
|
|
u32 sfc_get_max_iosize(void);
|
|
void sfc_set_delay_lines(u16 cells);
|
|
void sfc_disable_delay_lines(void);
|
|
int rksfc_get_reg_addr(unsigned long *p_sfc_addr);
|
|
|
|
#endif
|
|
|