linux/drivers/media/common/b2c2/flexcop-sram.c
<<
>>
Prefs
   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