1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 Mantis PCI bridge driver 4 5 Copyright (C) Manu Abraham (abraham.manu@gmail.com) 6 7 */ 8 9 #include <linux/kernel.h> 10 #include <linux/signal.h> 11 #include <linux/sched.h> 12 13 #include <linux/interrupt.h> 14 #include <asm/io.h> 15 16 #include <media/dmxdev.h> 17 #include <media/dvbdev.h> 18 #include <media/dvb_demux.h> 19 #include <media/dvb_frontend.h> 20 #include <media/dvb_net.h> 21 22 #include "mantis_common.h" 23 24 #include "mantis_hif.h" 25 #include "mantis_link.h" /* temporary due to physical layer stuff */ 26 27 #include "mantis_reg.h" 28 29 30 static int mantis_hif_sbuf_opdone_wait(struct mantis_ca *ca) 31 { 32 struct mantis_pci *mantis = ca->ca_priv; 33 int rc = 0; 34 35 if (wait_event_timeout(ca->hif_opdone_wq, 36 ca->hif_event & MANTIS_SBUF_OPDONE, 37 msecs_to_jiffies(500)) == -ERESTARTSYS) { 38 39 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Smart buffer operation timeout !", mantis->num); 40 rc = -EREMOTEIO; 41 } 42 dprintk(MANTIS_DEBUG, 1, "Smart Buffer Operation complete"); 43 ca->hif_event &= ~MANTIS_SBUF_OPDONE; 44 return rc; 45 } 46 47 static int mantis_hif_write_wait(struct mantis_ca *ca) 48 { 49 struct mantis_pci *mantis = ca->ca_priv; 50 u32 opdone = 0, timeout = 0; 51 int rc = 0; 52 53 if (wait_event_timeout(ca->hif_write_wq, 54 mantis->gpif_status & MANTIS_GPIF_WRACK, 55 msecs_to_jiffies(500)) == -ERESTARTSYS) { 56 57 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write ACK timed out !", mantis->num); 58 rc = -EREMOTEIO; 59 } 60 dprintk(MANTIS_DEBUG, 1, "Write Acknowledged"); 61 mantis->gpif_status &= ~MANTIS_GPIF_WRACK; 62 while (!opdone) { 63 opdone = (mmread(MANTIS_GPIF_STATUS) & MANTIS_SBUF_OPDONE); 64 udelay(500); 65 timeout++; 66 if (timeout > 100) { 67 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write operation timed out!", mantis->num); 68 rc = -ETIMEDOUT; 69 break; 70 } 71 } 72 dprintk(MANTIS_DEBUG, 1, "HIF Write success"); 73 return rc; 74 } 75 76 77 int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr) 78 { 79 struct mantis_pci *mantis = ca->ca_priv; 80 u32 hif_addr = 0, data, count = 4; 81 82 dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Read", mantis->num); 83 mutex_lock(&ca->ca_lock); 84 hif_addr &= ~MANTIS_GPIF_PCMCIAREG; 85 hif_addr &= ~MANTIS_GPIF_PCMCIAIOM; 86 hif_addr |= MANTIS_HIF_STATUS; 87 hif_addr |= addr; 88 89 mmwrite(hif_addr, MANTIS_GPIF_BRADDR); 90 mmwrite(count, MANTIS_GPIF_BRBYTES); 91 udelay(20); 92 mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); 93 94 if (mantis_hif_sbuf_opdone_wait(ca) != 0) { 95 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): GPIF Smart Buffer operation failed", mantis->num); 96 mutex_unlock(&ca->ca_lock); 97 return -EREMOTEIO; 98 } 99 data = mmread(MANTIS_GPIF_DIN); 100 mutex_unlock(&ca->ca_lock); 101 dprintk(MANTIS_DEBUG, 1, "Mem Read: 0x%02x", data); 102 return (data >> 24) & 0xff; 103 } 104 105 int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data) 106 { 107 struct mantis_slot *slot = ca->slot; 108 struct mantis_pci *mantis = ca->ca_priv; 109 u32 hif_addr = 0; 110 111 dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Write", mantis->num); 112 mutex_lock(&ca->ca_lock); 113 hif_addr &= ~MANTIS_GPIF_HIFRDWRN; 114 hif_addr &= ~MANTIS_GPIF_PCMCIAREG; 115 hif_addr &= ~MANTIS_GPIF_PCMCIAIOM; 116 hif_addr |= MANTIS_HIF_STATUS; 117 hif_addr |= addr; 118 119 mmwrite(slot->slave_cfg, MANTIS_GPIF_CFGSLA); /* Slot0 alone for now */ 120 mmwrite(hif_addr, MANTIS_GPIF_ADDR); 121 mmwrite(data, MANTIS_GPIF_DOUT); 122 123 if (mantis_hif_write_wait(ca) != 0) { 124 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); 125 mutex_unlock(&ca->ca_lock); 126 return -EREMOTEIO; 127 } 128 dprintk(MANTIS_DEBUG, 1, "Mem Write: (0x%02x to 0x%02x)", data, addr); 129 mutex_unlock(&ca->ca_lock); 130 131 return 0; 132 } 133 134 int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr) 135 { 136 struct mantis_pci *mantis = ca->ca_priv; 137 u32 data, hif_addr = 0; 138 139 dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Read", mantis->num); 140 mutex_lock(&ca->ca_lock); 141 hif_addr &= ~MANTIS_GPIF_PCMCIAREG; 142 hif_addr |= MANTIS_GPIF_PCMCIAIOM; 143 hif_addr |= MANTIS_HIF_STATUS; 144 hif_addr |= addr; 145 146 mmwrite(hif_addr, MANTIS_GPIF_BRADDR); 147 mmwrite(1, MANTIS_GPIF_BRBYTES); 148 udelay(20); 149 mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); 150 151 if (mantis_hif_sbuf_opdone_wait(ca) != 0) { 152 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); 153 mutex_unlock(&ca->ca_lock); 154 return -EREMOTEIO; 155 } 156 data = mmread(MANTIS_GPIF_DIN); 157 dprintk(MANTIS_DEBUG, 1, "I/O Read: 0x%02x", data); 158 udelay(50); 159 mutex_unlock(&ca->ca_lock); 160 161 return (u8) data; 162 } 163 164 int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data) 165 { 166 struct mantis_pci *mantis = ca->ca_priv; 167 u32 hif_addr = 0; 168 169 dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Write", mantis->num); 170 mutex_lock(&ca->ca_lock); 171 hif_addr &= ~MANTIS_GPIF_PCMCIAREG; 172 hif_addr &= ~MANTIS_GPIF_HIFRDWRN; 173 hif_addr |= MANTIS_GPIF_PCMCIAIOM; 174 hif_addr |= MANTIS_HIF_STATUS; 175 hif_addr |= addr; 176 177 mmwrite(hif_addr, MANTIS_GPIF_ADDR); 178 mmwrite(data, MANTIS_GPIF_DOUT); 179 180 if (mantis_hif_write_wait(ca) != 0) { 181 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); 182 mutex_unlock(&ca->ca_lock); 183 return -EREMOTEIO; 184 } 185 dprintk(MANTIS_DEBUG, 1, "I/O Write: (0x%02x to 0x%02x)", data, addr); 186 mutex_unlock(&ca->ca_lock); 187 udelay(50); 188 189 return 0; 190 } 191 192 int mantis_hif_init(struct mantis_ca *ca) 193 { 194 struct mantis_slot *slot = ca->slot; 195 struct mantis_pci *mantis = ca->ca_priv; 196 u32 irqcfg; 197 198 slot[0].slave_cfg = 0x70773028; 199 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Initializing Mantis Host Interface", mantis->num); 200 201 mutex_lock(&ca->ca_lock); 202 irqcfg = mmread(MANTIS_GPIF_IRQCFG); 203 irqcfg = MANTIS_MASK_BRRDY | 204 MANTIS_MASK_WRACK | 205 MANTIS_MASK_EXTIRQ | 206 MANTIS_MASK_WSTO | 207 MANTIS_MASK_OTHERR | 208 MANTIS_MASK_OVFLW; 209 210 mmwrite(irqcfg, MANTIS_GPIF_IRQCFG); 211 mutex_unlock(&ca->ca_lock); 212 213 return 0; 214 } 215 216 void mantis_hif_exit(struct mantis_ca *ca) 217 { 218 struct mantis_pci *mantis = ca->ca_priv; 219 u32 irqcfg; 220 221 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Exiting Mantis Host Interface", mantis->num); 222 mutex_lock(&ca->ca_lock); 223 irqcfg = mmread(MANTIS_GPIF_IRQCFG); 224 irqcfg &= ~MANTIS_MASK_BRRDY; 225 mmwrite(irqcfg, MANTIS_GPIF_IRQCFG); 226 mutex_unlock(&ca->ca_lock); 227 } 228