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 
flexcop_sram_set_chip(struct flexcop_device * fc,flexcop_sram_type_t type)8 static 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 
flexcop_sram_init(struct flexcop_device * fc)14 int 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 
flexcop_sram_set_dest(struct flexcop_device * fc,flexcop_sram_dest_t dest,flexcop_sram_dest_target_t target)30 int 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 }
56 EXPORT_SYMBOL(flexcop_sram_set_dest);
57 
flexcop_wan_set_speed(struct flexcop_device * fc,flexcop_wan_speed_t s)58 void 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 }
62 EXPORT_SYMBOL(flexcop_wan_set_speed);
63 
flexcop_sram_ctrl(struct flexcop_device * fc,int usb_wan,int sramdma,int maximumfill)64 void 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 }
72 EXPORT_SYMBOL(flexcop_sram_ctrl);
73 
74 #if 0
75 static 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 
100 static 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 
139 static 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 
158 static 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 
176 static 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 
195 static 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 
215 static 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 
221 static 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 
237 static 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 
281 static 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 
305 static 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 
358 static void sll_detect_sram_size(struct adapter *adapter)
359 {
360 	sram_detect_for_flex2(adapter);
361 }
362 
363 #endif
364