static inline void log_dpram_status(struct dpram_link_device *dpld) { pr_info("mif: %s: FMT T{I:%u O:%u} R{I:%u O:%u}, " "RAW T{I:%u O:%u} R{I:%u O:%u}\n", dpld->ld.name, get_tx_head(dpld, IPC_FMT), get_tx_tail(dpld, IPC_FMT), get_rx_head(dpld, IPC_FMT), get_rx_tail(dpld, IPC_FMT), get_tx_head(dpld, IPC_RAW), get_tx_tail(dpld, IPC_RAW), get_rx_head(dpld, IPC_RAW), get_rx_tail(dpld, IPC_RAW)); }
/* ** Functions for debugging */ static inline void log_dpram_status(struct dpram_link_device *dpld) { pr_info("mif: %s: {M:0x%X A:%d} {FMT TI:%u TO:%u RI:%u RO:%u} " "{RAW TI:%u TO:%u RI:%u RO:%u} {INT:0x%X}\n", dpld->ld.mc->name, get_magic(dpld), get_access(dpld), get_tx_head(dpld, IPC_FMT), get_tx_tail(dpld, IPC_FMT), get_rx_head(dpld, IPC_FMT), get_rx_tail(dpld, IPC_FMT), get_tx_head(dpld, IPC_RAW), get_tx_tail(dpld, IPC_RAW), get_rx_head(dpld, IPC_RAW), get_rx_tail(dpld, IPC_RAW), recv_intr(dpld)); }
static void set_dpram_map(struct dpram_link_device *dpld, struct mif_irq_map *map) { map->magic = get_magic(dpld); map->access = get_access(dpld); map->fmt_tx_in = get_tx_head(dpld, IPC_FMT); map->fmt_tx_out = get_tx_tail(dpld, IPC_FMT); map->fmt_rx_in = get_rx_head(dpld, IPC_FMT); map->fmt_rx_out = get_rx_tail(dpld, IPC_FMT); map->raw_tx_in = get_tx_head(dpld, IPC_RAW); map->raw_tx_out = get_tx_tail(dpld, IPC_RAW); map->raw_rx_in = get_rx_head(dpld, IPC_RAW); map->raw_rx_out = get_rx_tail(dpld, IPC_RAW); map->cp2ap = recv_intr(dpld); }
/* ret < 0 : error ret == 0 : no data ret > 0 : valid data */ static int dpram_ipc_recv_data(struct dpram_link_device *dpld, int dev) { struct link_device *ld = &dpld->ld; struct dpram_rxb *rxb; u8 __iomem *src = get_rx_buff(dpld, dev); u32 qsize = get_rx_buff_size(dpld, dev); u32 in = get_rx_head(dpld, dev); u32 out = get_rx_tail(dpld, dev); u32 rcvd = 0; struct mif_irq_map map; if (in == out) return 0; if (dev == IPC_FMT) { set_dpram_map(dpld, &map); mif_irq_log(ld->mc->msd, map, "ipc_recv", sizeof("ipc_recv")); } /* Get data length in DPRAM*/ rcvd = (in > out) ? (in - out) : (qsize - out + in); mif_debug("%s: %s qsize[%u] in[%u] out[%u] rcvd[%u]\n", ld->name, get_dev_name(dev), qsize, in, out, rcvd); /* Check each queue */ if (!dpram_circ_valid(qsize, in, out)) { mif_err("%s: ERR! %s_RXQ invalid (size:%d in:%d out:%d)\n", ld->name, get_dev_name(dev), qsize, in, out); #if 0 set_rx_head(dpld, dev, 0); set_rx_tail(dpld, dev, 0); #else dpram_trigger_force_cp_crash(dpld); #endif return -EINVAL; } /* Allocate an rxb */ rxb = rxbq_get_free_rxb(&dpld->rxbq[dev]); if (!rxb) { mif_info("%s: ERR! %s rxbq_get_free_rxb fail\n", ld->name, get_dev_name(dev)); return -ENOMEM; } /* Read data from each DPRAM buffer */ dpram_ipc_read(dpld, dev, rxb_put(rxb, rcvd), src, out, rcvd, qsize); /* Calculate and set new out */ out += rcvd; if (out >= qsize) out -= qsize; set_rx_tail(dpld, dev, out); return rcvd; }
/* Get data size in the RXQ as well as in & out pointers */ static inline int dpram_get_rxq_rcvd(struct dpram_link_device *dpld, int dev, u32 qsize, u32 *in, u32 *out) { struct link_device *ld = &dpld->ld; int cnt = 3; u32 head; u32 tail; u32 rcvd; do { head = get_rx_head(dpld, dev); tail = get_rx_tail(dpld, dev); if (head == tail) { *in = head; *out = tail; return 0; } rcvd = (head > tail) ? (head - tail) : (qsize - tail + head); mif_debug("%s: %s_RXQ qsize[%u] in[%u] out[%u] rcvd[%u]\n", ld->name, get_dev_name(dev), qsize, head, tail, rcvd); if (dpram_circ_valid(qsize, head, tail)) { *in = head; *out = tail; return rcvd; } mif_info("%s: CAUTION! <%pf> " "%s_RXQ invalid (size:%d in:%d out:%d)\n", ld->name, __builtin_return_address(0), get_dev_name(dev), qsize, head, tail); udelay(100); } while (cnt--); *in = 0; *out = 0; return -EINVAL; }