aboutsummaryrefslogtreecommitdiff
path: root/drivers/mtd/devices/hs_sfc/hisfc350.h
blob: bbfb692f90b1373ec125cced51dd0479874a8fcf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/******************************************************************************
 *    Copyright (c) 2009-2010 by Hisi.
 *    All rights reserved.
 * ***
 *    Create by CCCC. 2010-12-16
 *
 ******************************************************************************/

#ifndef HISFC350H
#define HISFC350H
/******************************************************************************/
#include "flash_info.h"

#define CONFIG_HISFC350_CHIP_NUM	(2)
/*****************************************************************************/
#define HISFC350_MAX_READY_WAIT_JIFFIES	(40 * HZ)

/*****************************************************************************/
#define HISFC350_DMA_ALIGN_SIZE		(256)
#define HISFC350_DMA_ALIGN_MASK		(HISFC350_DMA_ALIGN_SIZE - 1)

#define HISFC350_DMA_MAX_SIZE		(4096)
#define HISFC350_DMA_MAX_MASK		(HISFC350_DMA_MAX_SIZE - 1)

/*****************************************************************************/
#define HISFC350_GLOBAL_CONFIG			0x0100
#define HISFC350_GLOBAL_CONFIG_READ_DELAY(n)	(((n) & 0x03) << 3)
#define HISFC350_GLOBAL_CONFIG_ADDR_MODE_4B	(1 << 2)
#define HISFC350_GLOBAL_CONFIG_WRITE_PROTECT	(1 << 1)
#define HISFC350_GLOBAL_CONFIG_SPI_MODE3	(1 << 0)

#define HISFC350_TIMING				0x0110
#define HISFC350_TIMING_TSHSL(n)		((n) & 0xF)
#define HISFC350_TIMING_TCSS(n)			(((n) & 0x7) << 8)
#define HISFC350_TIMING_TCSH(n)			(((n) & 0x7) << 12)

#define HISFC350_INT_RAW_STATUS			0x0120
#define HISFC350_INT_RAW_STATUS_DMA_DONE	(1 << 1)
#define HISFC350_INT_STATUS			0x0124
#define HISFC350_INT_MASK			0x0128
#define HISFC350_INT_CLEAR			0x012C
#define HISFC350_INT_CLEAR_DMA_DONE		(1 << 1)

#define HISFC350_BUS_CONFIG1			0x0200
#define HISFC350_BUS_CONFIG1_READ_EN		(1 << 31)
#define HISFC350_BUS_CONFIG1_WRITE_EN		(1 << 30)
#define HISFC350_BUS_CONFIG1_WRITE_INS(n)	((n & 0xFF) << 22)
#define HISFC350_BUS_CONFIG1_WRITE_DUMMY_CNT(n)	((n & 0x7) << 19)
#define HISFC350_BUS_CONFIG1_WRITE_IF_TYPE(n)	((n & 0x7) << 16)
#define HISFC350_BUS_CONFIG1_READ_INS(n)	((n & 0xFF) << 8)
#define HISFC350_BUS_CONFIG1_READ_PREF_CNT(n)	((n & 0x3) << 6)
#define HISFC350_BUS_CONFIG1_READ_DUMMY_CNT(n)	((n & 0x7) << 3)
#define HISFC350_BUS_CONFIG1_READ_IF_TYPE(n)	(n & 0x7)

#define HISFC350_BUS_FLASH_SIZE			0x0210
#define HISFC350_BUS_FLASH_SIZE_CS0_MASK	0x0F
#define HISFC350_BUS_FLASH_SIZE_CS1_MASK	(0x0F << 8)
#define HISFC350_BUS_BASE_ADDR_CS0		0x0214
#define HISFC350_BUS_BASE_ADDR_CS1		0x0218
#define HISFC350_BUS_ALIAS_ADDR			0x021C
#define HISFC350_BUS_ALIAS_CS			0x0220
#define HISFC350_BUS_DMA_CTRL			0x0240
#define HISFC350_BUS_DMA_CTRL_START		(1 << 0)
#define HISFC350_BUS_DMA_CTRL_RW(_rw)		((_rw) << 1)
#define HISFC350_BUS_DMA_CTRL_CS(_cs)		(((_cs) & 0x01) << 4)

#define HISFC350_BUS_DMA_MEM_SADDR		0x0244
#define HISFC350_BUS_DMA_FLASH_SADDR		0x0248
#define HISFC350_BUS_DMA_LEN			0x024C
#define HISFC350_BUS_DMA_LEN_DATA_CNT(n)	((n - 1) & 0x0FFFFFFF)
#define HISFC350_BUS_DMA_AHB_CTRL		0x0250
#define HISFC350_BUS_DMA_AHB_CTRL_INCR4_EN	(1 << 0)
#define HISFC350_BUS_DMA_AHB_CTRL_INCR8_EN	(1 << 1)
#define HISFC350_BUS_DMA_AHB_CTRL_INCR16_EN	(1 << 2)

#define HISFC350_CMD_CONFIG			0x0300
#define HISFC350_CMD_CONFIG_MEM_IF_TYPE(n)     (((n) & 0x07) << 17)
#define HISFC350_CMD_CONFIG_DATA_CNT(n)        (((n - 1) & 0x3F)  <<  9)
#define HISFC350_CMD_CONFIG_RW_READ            (1 << 8)
#define HISFC350_CMD_CONFIG_DATA_EN            (1 << 7)
#define HISFC350_CMD_CONFIG_DUMMY_CNT(n)       (((n) & 0x07)  <<  4)
#define HISFC350_CMD_CONFIG_ADDR_EN            (1  <<  3)
#define HISFC350_CMD_CONFIG_SEL_CS(_cs)        (((_cs) & 0x01)  <<  1)
#define HISFC350_CMD_CONFIG_START              (1 << 0)

#define HISFC350_CMD_INS                       0x0308
#define HISFC350_CMD_ADDR                      0x030C
#define HISFC350_CMD_ADDR_MASK                 0x3FFFFFFF
#define HISFC350_CMD_DATABUF0                  0x0400
#define HISFC350_CMD_DATABUF15                 0x043C

/* hw iftype definition */
#define HISFC350_IF_HW_STD			0
#define HISFC350_IF_HW_DUAL			1
#define HISFC350_IF_HW_DUAL_ADDR		2
#define HISFC350_IF_HW_DUAL_CMD			3
#define HISFC350_IF_HW_QUAD			5
#define HISFC350_IF_HW_QUAD_ADDR		6
#define HISFC350_IF_HW_QUAD_CMD			7

#define HISFC350_REG_BUF_SIZE \
	(HISFC350_CMD_DATABUF15 - HISFC350_CMD_DATABUF0 + 0x04)

#undef  READ
#define READ           1

#undef  WRITE
#define WRITE          0

#undef  FALSE
#define FALSE          0

#undef  TRUE
#define TRUE           1

/*****************************************************************************/
#define HISFC350_VERSION                                         (0x01F8)

enum {
	addr_mode_3byte		= 0,
	addr_mode_4byte		= 1,
};

struct hisfc_flash_device {
	struct mtd_info		mtd;
	int			cs;
	int			addr_mode;

	void			*priv; /* host */
	struct flash_info	info;
};

struct hisfc_host {
	void __iomem	*io_base;
	int		version;/* version reg */

	struct clk	*clk;
	struct device	*dev;

	struct mutex	lock;
	int		cs;/* current selected cs */
	int		addr_mode;/* current host work_mode */

	char		*buffer;
	dma_addr_t	dma_buffer;/* dma addr of buffer */

	struct hisfc_flash_device *flash[CONFIG_HISFC350_CHIP_NUM];
};

/*****************************************************************************/
#define hisfc_read(reg)		readl(host->io_base + reg)

#define hisfc_write(reg, val)	writel(val, host->io_base + reg)

#define HISFC350_CMD_WAIT_CPU_FINISH(_host) do {\
	unsigned int timeout = 0x10000000; \
	while (((hisfc_read(HISFC350_CMD_CONFIG) \
				& HISFC350_CMD_CONFIG_START)) && timeout)\
		--timeout; \
	if (!timeout) \
		DBG_BUG("cmd wait cpu finish timeout\n"); \
} while (0)

#define HISFC350_DMA_WAIT_CPU_FINISH(_host) do {\
	unsigned int timeout = 0x10000000; \
	while (((hisfc_read(HISFC350_BUS_DMA_CTRL) \
				& HISFC350_BUS_DMA_CTRL_START)) && timeout) {\
		--timeout; cond_resched(); } \
	if (!timeout) \
		DBG_BUG("dma wait cpu finish timeout\n");\
} while (0)

/*****************************************************************************/
#if 0
#  define DBG_MSG(_fmt, arg...)
#else
#  define DBG_MSG(_fmt, arg...) \
	pr_info("%s(%d): " _fmt, __FILE__, __LINE__, ##arg);
#endif

#define DBG_WARN(_fmt, arg...) \
	pr_info("%s(%d): " _fmt, __FILE__, __LINE__, ##arg);

#define DBG_BUG(fmt, args...) do {\
	pr_err("%s(%d): BUG: " fmt, __FILE__, __LINE__, ##args); \
	while (1)\
		;\
} while (0)

/******************************************************************************/
#endif /* HISFC350H */