1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-sram.c - functions for controlling the SRAM
4 * see flexcop.c for copyright information
5 */
6#include "flexcop.h"
7
8static void flexcop_sram_set_chip(struct flexcop_device *fc,
9		flexcop_sram_type_t type)
10{
11	flexcop_set_ibi_value(wan_ctrl_reg_71c, sram_chip, type);
12}
13
14int flexcop_sram_init(struct flexcop_device *fc)
15{
16	switch (fc->rev) {
17	case FLEXCOP_II:
18	case FLEXCOP_IIB:
19		flexcop_sram_set_chip(fc, FC_SRAM_1_32KB);
20		break;
21	case FLEXCOP_III:
22		flexcop_sram_set_chip(fc, FC_SRAM_1_48KB);
23		break;
24	default:
25		return -EINVAL;
26	}
27	return 0;
28}
29
30int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
31		 flexcop_sram_dest_target_t target)
32{
33	flexcop_ibi_value v;
34	v = fc->read_ibi_reg(fc, sram_dest_reg_714);
35
36	if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) {
37		err("SRAM destination target to available on FlexCopII(b)\n");
38		return -EINVAL;
39	}
40	deb_sram("sram dest: %x target: %x\n", dest, target);
41
42	if (dest & FC_SRAM_DEST_NET)
43		v.sram_dest_reg_714.NET_Dest = target;
44	if (dest & FC_SRAM_DEST_CAI)
45		v.sram_dest_reg_714.CAI_Dest = target;
46	if (dest & FC_SRAM_DEST_CAO)
47		v.sram_dest_reg_714.CAO_Dest = target;
48	if (dest & FC_SRAM_DEST_MEDIA)
49		v.sram_dest_reg_714.MEDIA_Dest = target;
50
51	fc->write_ibi_reg(fc,sram_dest_reg_714,v);
52	udelay(1000); /* TODO delay really necessary */
53
54	return 0;
55}
56EXPORT_SYMBOL(flexcop_sram_set_dest);
57
58void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s)
59{
60	flexcop_set_ibi_value(wan_ctrl_reg_71c,wan_speed_sig,s);
61}
62EXPORT_SYMBOL(flexcop_wan_set_speed);
63
64void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill)
65{
66	flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714);
67	v.sram_dest_reg_714.ctrl_usb_wan = usb_wan;
68	v.sram_dest_reg_714.ctrl_sramdma = sramdma;
69	v.sram_dest_reg_714.ctrl_maximumfill = maximumfill;
70	fc->write_ibi_reg(fc,sram_dest_reg_714,v);
71}
72EXPORT_SYMBOL(flexcop_sram_ctrl);
73
74#if 0
75static void flexcop_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
76{
77	int i, retries;
78	u32 command;
79
80	for (i = 0; i < len; i++) {
81		command = bank | addr | 0x04000000 | (*buf << 0x10);
82
83		retries = 2;
84
85		while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
86			mdelay(1);
87			retries--;
88		}
89
90		if (retries == 0)
91			printk("%s: SRAM timeout\n", __func__);
92
93		write_reg_dw(adapter, 0x700, command);
94
95		buf++;
96		addr++;
97	}
98}
99
100static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
101{
102	int i, retries;
103	u32 command, value;
104
105	for (i = 0; i < len; i++) {
106		command = bank | addr | 0x04008000;
107
108		retries = 10000;
109
110		while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
111			mdelay(1);
112			retries--;
113		}
114
115		if (retries == 0)
116			printk("%s: SRAM timeout\n", __func__);
117
118		write_reg_dw(adapter, 0x700, command);
119
120		retries = 10000;
121
122		while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
123			mdelay(1);
124			retries--;
125		}
126
127		if (retries == 0)
128			printk("%s: SRAM timeout\n", __func__);
129
130		value = read_reg_dw(adapter, 0x700) >> 0x10;
131
132		*buf = (value & 0xff);
133
134		addr++;
135		buf++;
136	}
137}
138
139static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
140{
141	u32 bank;
142
143	bank = 0;
144
145	if (adapter->dw_sram_type == 0x20000) {
146		bank = (addr & 0x18000) << 0x0d;
147	}
148
149	if (adapter->dw_sram_type == 0x00000) {
150		if ((addr >> 0x0f) == 0)
151			bank = 0x20000000;
152		else
153			bank = 0x10000000;
154	}
155	flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
156}
157
158static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
159{
160	u32 bank;
161	bank = 0;
162
163	if (adapter->dw_sram_type == 0x20000) {
164		bank = (addr & 0x18000) << 0x0d;
165	}
166
167	if (adapter->dw_sram_type == 0x00000) {
168		if ((addr >> 0x0f) == 0)
169			bank = 0x20000000;
170		else
171			bank = 0x10000000;
172	}
173	flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
174}
175
176static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
177{
178	u32 length;
179	while (len != 0) {
180		length = len;
181		/* check if the address range belongs to the same
182		 * 32K memory chip. If not, the data is read
183		 * from one chip at a time */
184		if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
185			length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
186		}
187
188		sram_read_chunk(adapter, addr, buf, length);
189		addr = addr + length;
190		buf = buf + length;
191		len = len - length;
192	}
193}
194
195static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
196{
197	u32 length;
198	while (len != 0) {
199		length = len;
200
201		/* check if the address range belongs to the same
202		 * 32K memory chip. If not, the data is
203		 * written to one chip at a time */
204		if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
205			length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
206		}
207
208		sram_write_chunk(adapter, addr, buf, length);
209		addr = addr + length;
210		buf = buf + length;
211		len = len - length;
212	}
213}
214
215static void sram_set_size(struct adapter *adapter, u32 mask)
216{
217	write_reg_dw(adapter, 0x71c,
218			(mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
219}
220
221static void sram_init(struct adapter *adapter)
222{
223	u32 tmp;
224	tmp = read_reg_dw(adapter, 0x71c);
225	write_reg_dw(adapter, 0x71c, 1);
226
227	if (read_reg_dw(adapter, 0x71c) != 0) {
228		write_reg_dw(adapter, 0x71c, tmp);
229		adapter->dw_sram_type = tmp & 0x30000;
230		ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
231	} else {
232		adapter->dw_sram_type = 0x10000;
233		ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
234	}
235}
236
237static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
238{
239	u8 tmp1, tmp2;
240	dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr);
241
242	sram_set_size(adapter, mask);
243	sram_init(adapter);
244
245	tmp2 = 0xa5;
246	tmp1 = 0x4f;
247
248	sram_write(adapter, addr, &tmp2, 1);
249	sram_write(adapter, addr + 4, &tmp1, 1);
250
251	tmp2 = 0;
252	mdelay(20);
253
254	sram_read(adapter, addr, &tmp2, 1);
255	sram_read(adapter, addr, &tmp2, 1);
256
257	dprintk("%s: wrote 0xa5, read 0x%2x\n", __func__, tmp2);
258
259	if (tmp2 != 0xa5)
260		return 0;
261
262	tmp2 = 0x5a;
263	tmp1 = 0xf4;
264
265	sram_write(adapter, addr, &tmp2, 1);
266	sram_write(adapter, addr + 4, &tmp1, 1);
267
268	tmp2 = 0;
269	mdelay(20);
270
271	sram_read(adapter, addr, &tmp2, 1);
272	sram_read(adapter, addr, &tmp2, 1);
273
274	dprintk("%s: wrote 0x5a, read 0x%2x\n", __func__, tmp2);
275
276	if (tmp2 != 0x5a)
277		return 0;
278	return 1;
279}
280
281static u32 sram_length(struct adapter *adapter)
282{
283	if (adapter->dw_sram_type == 0x10000)
284		return 32768; /* 32K */
285	if (adapter->dw_sram_type == 0x00000)
286		return 65536; /* 64K */
287	if (adapter->dw_sram_type == 0x20000)
288		return 131072; /* 128K */
289	return 32768; /* 32K */
290}
291
292/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
293   - for 128K there are 4x32K chips at bank 0,1,2,3.
294   - for  64K there are 2x32K chips at bank 1,2.
295   - for  32K there is one 32K chip at bank 0.
296
297   FlexCop works only with one bank at a time. The bank is selected
298   by bits 28-29 of the 0x700 register.
299
300   bank 0 covers addresses 0x00000-0x07fff
301   bank 1 covers addresses 0x08000-0x0ffff
302   bank 2 covers addresses 0x10000-0x17fff
303   bank 3 covers addresses 0x18000-0x1ffff */
304
305static int flexcop_sram_detect(struct flexcop_device *fc)
306{
307	flexcop_ibi_value r208, r71c_0, vr71c_1;
308	r208 = fc->read_ibi_reg(fc, ctrl_208);
309	fc->write_ibi_reg(fc, ctrl_208, ibi_zero);
310
311	r71c_0 = fc->read_ibi_reg(fc, wan_ctrl_reg_71c);
312	write_reg_dw(adapter, 0x71c, 1);
313	tmp3 = read_reg_dw(adapter, 0x71c);
314	dprintk("%s: tmp3 = %x\n", __func__, tmp3);
315	write_reg_dw(adapter, 0x71c, tmp2);
316
317	// check for internal SRAM ???
318	tmp3--;
319	if (tmp3 != 0) {
320		sram_set_size(adapter, 0x10000);
321		sram_init(adapter);
322		write_reg_dw(adapter, 0x208, tmp);
323		dprintk("%s: sram size = 32K\n", __func__);
324		return 32;
325	}
326
327	if (sram_test_location(adapter, 0x20000, 0x18000) != 0) {
328		sram_set_size(adapter, 0x20000);
329		sram_init(adapter);
330		write_reg_dw(adapter, 0x208, tmp);
331		dprintk("%s: sram size = 128K\n", __func__);
332		return 128;
333	}
334
335	if (sram_test_location(adapter, 0x00000, 0x10000) != 0) {
336		sram_set_size(adapter, 0x00000);
337		sram_init(adapter);
338		write_reg_dw(adapter, 0x208, tmp);
339		dprintk("%s: sram size = 64K\n", __func__);
340		return 64;
341	}
342
343	if (sram_test_location(adapter, 0x10000, 0x00000) != 0) {
344		sram_set_size(adapter, 0x10000);
345		sram_init(adapter);
346		write_reg_dw(adapter, 0x208, tmp);
347		dprintk("%s: sram size = 32K\n", __func__);
348		return 32;
349	}
350
351	sram_set_size(adapter, 0x10000);
352	sram_init(adapter);
353	write_reg_dw(adapter, 0x208, tmp);
354	dprintk("%s: SRAM detection failed. Set to 32K \n", __func__);
355	return 0;
356}
357
358static void sll_detect_sram_size(struct adapter *adapter)
359{
360	sram_detect_for_flex2(adapter);
361}
362
363#endif
364