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