228 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 Mantis PCI bridge driver4 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 30static 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 47static 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 77int 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 105int 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 134int 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 164int 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 192int 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 216void 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