aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common/b2c2/flexcop-sram.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/common/b2c2/flexcop-sram.c')
-rw-r--r--drivers/media/common/b2c2/flexcop-sram.c363
1 files changed, 363 insertions, 0 deletions
diff --git a/drivers/media/common/b2c2/flexcop-sram.c b/drivers/media/common/b2c2/flexcop-sram.c
new file mode 100644
index 00000000000..f2199e43e80
--- /dev/null
+++ b/drivers/media/common/b2c2/flexcop-sram.c
@@ -0,0 +1,363 @@
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