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