Loading drivers/dma/qcom/gpi.c +38 −32 Original line number Diff line number Diff line Loading @@ -447,7 +447,8 @@ struct gpi_dev { struct dentry *dentry; }; static struct gpi_dev *gpi_dev_dbg; static struct gpi_dev *gpi_dev_dbg[5]; static int arr_idx; struct reg_info { char *name; Loading Loading @@ -581,6 +582,7 @@ struct gpii { struct gpi_reg_table dbg_reg_table; bool reg_table_dump; u32 dbg_gpi_irq_cnt; bool ieob_set; }; struct gpi_desc { Loading Loading @@ -1496,20 +1498,6 @@ static void gpi_process_imed_data_event(struct gpii_chan *gpii_chan, return; } gpi_desc = to_gpi_desc(vd); /* Event TR RP gen. don't match descriptor TR */ if (gpi_desc->wp != tre) { spin_unlock_irqrestore(&gpii_chan->vc.lock, flags); GPII_ERR(gpii, gpii_chan->chid, "EOT/EOB received for wrong TRE 0x%0llx != 0x%0llx\n", to_physical(ch_ring, gpi_desc->wp), to_physical(ch_ring, tre)); gpi_generate_cb_event(gpii_chan, MSM_GPI_QUP_EOT_DESC_MISMATCH, __LINE__); return; } list_del(&vd->node); spin_unlock_irqrestore(&gpii_chan->vc.lock, flags); Loading @@ -1525,6 +1513,9 @@ static void gpi_process_imed_data_event(struct gpii_chan *gpii_chan, /* make sure rp updates are immediately visible to all cores */ smp_wmb(); if (imed_event->code == MSM_GPI_TCE_EOT && gpii->ieob_set) return; tx_cb_param = vd->tx.callback_param; if (vd->tx.callback && tx_cb_param) { struct msm_gpi_tre *imed_tre = &tx_cb_param->imed_tre; Loading @@ -1540,7 +1531,12 @@ static void gpi_process_imed_data_event(struct gpii_chan *gpii_chan, tx_cb_param->status = imed_event->status; vd->tx.callback(tx_cb_param); } spin_lock_irqsave(&gpii_chan->vc.lock, flags); list_del(&vd->node); spin_unlock_irqrestore(&gpii_chan->vc.lock, flags); kfree(gpi_desc); gpi_desc = NULL; } /* processing transfer completion events */ Loading Loading @@ -1583,20 +1579,6 @@ static void gpi_process_xfer_compl_event(struct gpii_chan *gpii_chan, } gpi_desc = to_gpi_desc(vd); /* TRE Event generated didn't match descriptor's TRE */ if (gpi_desc->wp != ev_rp) { spin_unlock_irqrestore(&gpii_chan->vc.lock, flags); GPII_ERR(gpii, gpii_chan->chid, "EOT\EOB received for wrong TRE 0x%0llx != 0x%0llx\n", to_physical(ch_ring, gpi_desc->wp), to_physical(ch_ring, ev_rp)); gpi_generate_cb_event(gpii_chan, MSM_GPI_QUP_EOT_DESC_MISMATCH, __LINE__); return; } list_del(&vd->node); spin_unlock_irqrestore(&gpii_chan->vc.lock, flags); Loading @@ -1612,6 +1594,9 @@ static void gpi_process_xfer_compl_event(struct gpii_chan *gpii_chan, /* update must be visible to other cores */ smp_wmb(); if (compl_event->code == MSM_GPI_TCE_EOT && gpii->ieob_set) return; tx_cb_param = vd->tx.callback_param; if (vd->tx.callback && tx_cb_param) { GPII_VERB(gpii, gpii_chan->chid, Loading @@ -1623,7 +1608,13 @@ static void gpi_process_xfer_compl_event(struct gpii_chan *gpii_chan, tx_cb_param->status = compl_event->status; vd->tx.callback(tx_cb_param); } spin_lock_irqsave(&gpii_chan->vc.lock, flags); list_del(&vd->node); spin_unlock_irqrestore(&gpii_chan->vc.lock, flags); kfree(gpi_desc); gpi_desc = NULL; } /* process all events */ Loading Loading @@ -2299,6 +2290,7 @@ void gpi_desc_free(struct virt_dma_desc *vd) struct gpi_desc *gpi_desc = to_gpi_desc(vd); kfree(gpi_desc); gpi_desc = NULL; } /* copy tre into transfer ring */ Loading @@ -2319,6 +2311,7 @@ struct dma_async_tx_descriptor *gpi_prep_slave_sg(struct dma_chan *chan, void *tre, *wp = NULL; const gfp_t gfp = GFP_ATOMIC; struct gpi_desc *gpi_desc; gpii->ieob_set = false; GPII_VERB(gpii, gpii_chan->chid, "enter\n"); Loading Loading @@ -2352,10 +2345,22 @@ struct dma_async_tx_descriptor *gpi_prep_slave_sg(struct dma_chan *chan, } /* copy each tre into transfer ring */ for_each_sg(sgl, sg, sg_len, i) for (j = 0, tre = sg_virt(sg); j < sg->length; for_each_sg(sgl, sg, sg_len, i) { tre = sg_virt(sg); /* Check if last tre has ieob set */ if (i == sg_len - 1) { if ((((struct msm_gpi_tre *)tre)->dword[3] & GPI_IEOB_BMSK) >> GPI_IEOB_BMSK_SHIFT) gpii->ieob_set = true; else gpii->ieob_set = false; } for (j = 0; j < sg->length; j += ch_ring->el_size, tre += ch_ring->el_size) gpi_queue_xfer(gpii, gpii_chan, tre, &wp); } /* set up the descriptor */ gpi_desc->db = ch_ring->wp; Loading Loading @@ -2807,7 +2812,8 @@ static int gpi_probe(struct platform_device *pdev) return -ENOMEM; /* debug purpose */ gpi_dev_dbg = gpi_dev; gpi_dev_dbg[arr_idx] = gpi_dev; arr_idx++; gpi_dev->dev = &pdev->dev; gpi_dev->klog_lvl = DEFAULT_KLOG_LVL; Loading drivers/dma/qcom/msm_gpi_mmio.h +4 −0 Original line number Diff line number Diff line Loading @@ -228,3 +228,7 @@ enum CNTXT_OFFS { #define GPI_DEBUG_QSB_LOG_1 (0x5068) #define GPI_DEBUG_QSB_LOG_2 (0x506C) #define GPI_DEBUG_QSB_LOG_LAST_MISC_ID(n) (0x5070 + (0x4*n)) /* IEOB bit set */ #define GPI_IEOB_BMSK (0x100) #define GPI_IEOB_BMSK_SHIFT (8) drivers/i2c/busses/i2c-qcom-geni.c +55 −14 Original line number Diff line number Diff line Loading @@ -98,6 +98,8 @@ struct geni_i2c_dev { int clk_fld_idx; struct dma_chan *tx_c; struct dma_chan *rx_c; struct msm_gpi_tre lock_t; struct msm_gpi_tre unlock_t; struct msm_gpi_tre cfg0_t; struct msm_gpi_tre go_t; struct msm_gpi_tre tx_t; Loading Loading @@ -370,9 +372,9 @@ static void gi2c_ev_cb(struct dma_chan *ch, struct msm_gpi_cb const *cb_str, } if (cb_str->cb_event != MSM_GPI_QUP_NOTIFY) GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "GSI QN err:0x%x, status:0x%x, err:%d\n", cb_str->error_log.error_code, m_stat, cb_str->cb_event); "GSI QN err:0x%x, status:0x%x, err:%d slv_addr: 0x%x R/W: %d\n", cb_str->error_log.error_code, m_stat, cb_str->cb_event, gi2c->cur->addr, gi2c->cur->flags); } static void gi2c_gsi_cb_err(struct msm_gpi_dma_async_tx_cb_param *cb, Loading @@ -398,7 +400,9 @@ static void gi2c_gsi_tx_cb(void *ptr) struct msm_gpi_dma_async_tx_cb_param *tx_cb = ptr; struct geni_i2c_dev *gi2c = tx_cb->userdata; if (!(gi2c->cur->flags & I2C_M_RD)) { if (tx_cb->completion_code == MSM_GPI_TCE_EOB) { complete(&gi2c->xfer); } else if (!(gi2c->cur->flags & I2C_M_RD)) { gi2c_gsi_cb_err(tx_cb, "TX"); complete(&gi2c->xfer); } Loading Loading @@ -460,6 +464,23 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], } } if (gi2c->is_shared) { struct msm_gpi_tre *lock_t = &gi2c->lock_t; struct msm_gpi_tre *unlock_t = &gi2c->unlock_t; /* lock */ lock_t->dword[0] = MSM_GPI_LOCK_TRE_DWORD0; lock_t->dword[1] = MSM_GPI_LOCK_TRE_DWORD1; lock_t->dword[2] = MSM_GPI_LOCK_TRE_DWORD2; lock_t->dword[3] = MSM_GPI_LOCK_TRE_DWORD3(0, 0, 0, 0, 1); /* unlock */ unlock_t->dword[0] = MSM_GPI_UNLOCK_TRE_DWORD0; unlock_t->dword[1] = MSM_GPI_UNLOCK_TRE_DWORD1; unlock_t->dword[2] = MSM_GPI_UNLOCK_TRE_DWORD2; unlock_t->dword[3] = MSM_GPI_UNLOCK_TRE_DWORD3(0, 0, 0, 1, 0); } if (!gi2c->cfg_sent) { struct geni_i2c_clk_fld *itr = geni_i2c_clk_map + gi2c->clk_fld_idx; Loading Loading @@ -499,24 +520,34 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], } qcom_geni_i2c_calc_timeout(gi2c); if (!gi2c->cfg_sent) { if (!gi2c->cfg_sent) segs++; if (gi2c->is_shared && (i == 0 || i == num-1)) { segs++; if (num == 1) segs++; sg_init_table(gi2c->tx_sg, segs); sg_set_buf(gi2c->tx_sg, &gi2c->cfg0_t, sizeof(gi2c->cfg0_t)); gi2c->cfg_sent = 1; index++; if (i == 0) sg_set_buf(&gi2c->tx_sg[index++], &gi2c->lock_t, sizeof(gi2c->lock_t)); } else { sg_init_table(gi2c->tx_sg, segs); } if (!gi2c->cfg_sent) { sg_set_buf(&gi2c->tx_sg[index++], &gi2c->cfg0_t, sizeof(gi2c->cfg0_t)); gi2c->cfg_sent = 1; } go_t->dword[0] = MSM_GPI_I2C_GO_TRE_DWORD0((stretch << 2), msgs[i].addr, op); go_t->dword[1] = MSM_GPI_I2C_GO_TRE_DWORD1; if (msgs[i].flags & I2C_M_RD) { go_t->dword[2] = MSM_GPI_I2C_GO_TRE_DWORD2(msgs[i].len); go_t->dword[3] = MSM_GPI_I2C_GO_TRE_DWORD3(1, 0, 0, 1, go_t->dword[3] = MSM_GPI_I2C_GO_TRE_DWORD3(1, 0, 0, 0, 0); } else { go_t->dword[2] = MSM_GPI_I2C_GO_TRE_DWORD2(0); Loading Loading @@ -588,6 +619,10 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], MSM_GPI_DMA_W_BUFFER_TRE_DWORD1(gi2c->tx_ph); gi2c->tx_t.dword[2] = MSM_GPI_DMA_W_BUFFER_TRE_DWORD2(msgs[i].len); if (gi2c->is_shared && i == num-1) gi2c->tx_t.dword[3] = MSM_GPI_DMA_W_BUFFER_TRE_DWORD3(0, 0, 1, 0, 1); else gi2c->tx_t.dword[3] = MSM_GPI_DMA_W_BUFFER_TRE_DWORD3(0, 0, 1, 0, 0); Loading @@ -595,6 +630,11 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], sizeof(gi2c->tx_t)); } if (gi2c->is_shared && i == num-1) { sg_set_buf(&gi2c->tx_sg[index++], &gi2c->unlock_t, sizeof(gi2c->unlock_t)); } gi2c->tx_desc = dmaengine_prep_slave_sg(gi2c->tx_c, gi2c->tx_sg, segs, DMA_MEM_TO_DEV, (DMA_PREP_INTERRUPT | Loading @@ -616,8 +656,9 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], gi2c->xfer_timeout); if (!timeout) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "GSI Txn timed out: %u len: %d\n", gi2c->xfer_timeout, gi2c->cur->len); "GSI Txn timed out: %u len: %d slv:addr: 0x%x R/W: %d\n", gi2c->xfer_timeout, gi2c->cur->len, gi2c->cur->addr, gi2c->cur->flags); geni_se_dump_dbg_regs(&gi2c->i2c_rsc, gi2c->base, gi2c->ipcl); gi2c->err = -ETIMEDOUT; Loading Loading @@ -1001,7 +1042,7 @@ static int geni_i2c_runtime_resume(struct device *dev) if (!gi2c->ipcl) { char ipc_name[I2C_NAME_SIZE]; snprintf(ipc_name, I2C_NAME_SIZE, "i2c-%d", gi2c->adap.nr); snprintf(ipc_name, I2C_NAME_SIZE, "%s", dev_name(gi2c->dev)); gi2c->ipcl = ipc_log_context_create(2, ipc_name, 0); } Loading drivers/spi/spi-geni-qcom.c +1 −1 Original line number Diff line number Diff line Loading @@ -397,7 +397,7 @@ static struct msm_gpi_tre *setup_go_tre(int cmd, int cs, int rx_len, int flags, if (cmd == SPI_RX_ONLY) { eot = 0; chain = 0; eob = 1; eob = 0; } else { eot = 0; chain = 1; Loading include/linux/msm_gpi.h +16 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,22 @@ enum msm_gpi_tre_type { #define MSM_GPI_TRE_TYPE(tre) ((tre->dword[3] >> 16) & 0xFF) /* Lock TRE */ #define MSM_GPI_LOCK_TRE_DWORD0 (0) #define MSM_GPI_LOCK_TRE_DWORD1 (0) #define MSM_GPI_LOCK_TRE_DWORD2 (0) #define MSM_GPI_LOCK_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) \ ((0x3 << 20) | (0x0 << 16) | (link_rx << 11) | (bei << 10) | \ (ieot << 9) | (ieob << 8) | ch) /* Unlock TRE */ #define MSM_GPI_UNLOCK_TRE_DWORD0 (0) #define MSM_GPI_UNLOCK_TRE_DWORD1 (0) #define MSM_GPI_UNLOCK_TRE_DWORD2 (0) #define MSM_GPI_UNLOCK_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) \ ((0x3 << 20) | (0x1 << 16) | (link_rx << 11) | (bei << 10) | \ (ieot << 9) | (ieob << 8) | ch) /* DMA w. Buffer TRE */ #ifdef CONFIG_ARM64 #define MSM_GPI_DMA_W_BUFFER_TRE_DWORD0(ptr) ((u32)ptr) Loading Loading
drivers/dma/qcom/gpi.c +38 −32 Original line number Diff line number Diff line Loading @@ -447,7 +447,8 @@ struct gpi_dev { struct dentry *dentry; }; static struct gpi_dev *gpi_dev_dbg; static struct gpi_dev *gpi_dev_dbg[5]; static int arr_idx; struct reg_info { char *name; Loading Loading @@ -581,6 +582,7 @@ struct gpii { struct gpi_reg_table dbg_reg_table; bool reg_table_dump; u32 dbg_gpi_irq_cnt; bool ieob_set; }; struct gpi_desc { Loading Loading @@ -1496,20 +1498,6 @@ static void gpi_process_imed_data_event(struct gpii_chan *gpii_chan, return; } gpi_desc = to_gpi_desc(vd); /* Event TR RP gen. don't match descriptor TR */ if (gpi_desc->wp != tre) { spin_unlock_irqrestore(&gpii_chan->vc.lock, flags); GPII_ERR(gpii, gpii_chan->chid, "EOT/EOB received for wrong TRE 0x%0llx != 0x%0llx\n", to_physical(ch_ring, gpi_desc->wp), to_physical(ch_ring, tre)); gpi_generate_cb_event(gpii_chan, MSM_GPI_QUP_EOT_DESC_MISMATCH, __LINE__); return; } list_del(&vd->node); spin_unlock_irqrestore(&gpii_chan->vc.lock, flags); Loading @@ -1525,6 +1513,9 @@ static void gpi_process_imed_data_event(struct gpii_chan *gpii_chan, /* make sure rp updates are immediately visible to all cores */ smp_wmb(); if (imed_event->code == MSM_GPI_TCE_EOT && gpii->ieob_set) return; tx_cb_param = vd->tx.callback_param; if (vd->tx.callback && tx_cb_param) { struct msm_gpi_tre *imed_tre = &tx_cb_param->imed_tre; Loading @@ -1540,7 +1531,12 @@ static void gpi_process_imed_data_event(struct gpii_chan *gpii_chan, tx_cb_param->status = imed_event->status; vd->tx.callback(tx_cb_param); } spin_lock_irqsave(&gpii_chan->vc.lock, flags); list_del(&vd->node); spin_unlock_irqrestore(&gpii_chan->vc.lock, flags); kfree(gpi_desc); gpi_desc = NULL; } /* processing transfer completion events */ Loading Loading @@ -1583,20 +1579,6 @@ static void gpi_process_xfer_compl_event(struct gpii_chan *gpii_chan, } gpi_desc = to_gpi_desc(vd); /* TRE Event generated didn't match descriptor's TRE */ if (gpi_desc->wp != ev_rp) { spin_unlock_irqrestore(&gpii_chan->vc.lock, flags); GPII_ERR(gpii, gpii_chan->chid, "EOT\EOB received for wrong TRE 0x%0llx != 0x%0llx\n", to_physical(ch_ring, gpi_desc->wp), to_physical(ch_ring, ev_rp)); gpi_generate_cb_event(gpii_chan, MSM_GPI_QUP_EOT_DESC_MISMATCH, __LINE__); return; } list_del(&vd->node); spin_unlock_irqrestore(&gpii_chan->vc.lock, flags); Loading @@ -1612,6 +1594,9 @@ static void gpi_process_xfer_compl_event(struct gpii_chan *gpii_chan, /* update must be visible to other cores */ smp_wmb(); if (compl_event->code == MSM_GPI_TCE_EOT && gpii->ieob_set) return; tx_cb_param = vd->tx.callback_param; if (vd->tx.callback && tx_cb_param) { GPII_VERB(gpii, gpii_chan->chid, Loading @@ -1623,7 +1608,13 @@ static void gpi_process_xfer_compl_event(struct gpii_chan *gpii_chan, tx_cb_param->status = compl_event->status; vd->tx.callback(tx_cb_param); } spin_lock_irqsave(&gpii_chan->vc.lock, flags); list_del(&vd->node); spin_unlock_irqrestore(&gpii_chan->vc.lock, flags); kfree(gpi_desc); gpi_desc = NULL; } /* process all events */ Loading Loading @@ -2299,6 +2290,7 @@ void gpi_desc_free(struct virt_dma_desc *vd) struct gpi_desc *gpi_desc = to_gpi_desc(vd); kfree(gpi_desc); gpi_desc = NULL; } /* copy tre into transfer ring */ Loading @@ -2319,6 +2311,7 @@ struct dma_async_tx_descriptor *gpi_prep_slave_sg(struct dma_chan *chan, void *tre, *wp = NULL; const gfp_t gfp = GFP_ATOMIC; struct gpi_desc *gpi_desc; gpii->ieob_set = false; GPII_VERB(gpii, gpii_chan->chid, "enter\n"); Loading Loading @@ -2352,10 +2345,22 @@ struct dma_async_tx_descriptor *gpi_prep_slave_sg(struct dma_chan *chan, } /* copy each tre into transfer ring */ for_each_sg(sgl, sg, sg_len, i) for (j = 0, tre = sg_virt(sg); j < sg->length; for_each_sg(sgl, sg, sg_len, i) { tre = sg_virt(sg); /* Check if last tre has ieob set */ if (i == sg_len - 1) { if ((((struct msm_gpi_tre *)tre)->dword[3] & GPI_IEOB_BMSK) >> GPI_IEOB_BMSK_SHIFT) gpii->ieob_set = true; else gpii->ieob_set = false; } for (j = 0; j < sg->length; j += ch_ring->el_size, tre += ch_ring->el_size) gpi_queue_xfer(gpii, gpii_chan, tre, &wp); } /* set up the descriptor */ gpi_desc->db = ch_ring->wp; Loading Loading @@ -2807,7 +2812,8 @@ static int gpi_probe(struct platform_device *pdev) return -ENOMEM; /* debug purpose */ gpi_dev_dbg = gpi_dev; gpi_dev_dbg[arr_idx] = gpi_dev; arr_idx++; gpi_dev->dev = &pdev->dev; gpi_dev->klog_lvl = DEFAULT_KLOG_LVL; Loading
drivers/dma/qcom/msm_gpi_mmio.h +4 −0 Original line number Diff line number Diff line Loading @@ -228,3 +228,7 @@ enum CNTXT_OFFS { #define GPI_DEBUG_QSB_LOG_1 (0x5068) #define GPI_DEBUG_QSB_LOG_2 (0x506C) #define GPI_DEBUG_QSB_LOG_LAST_MISC_ID(n) (0x5070 + (0x4*n)) /* IEOB bit set */ #define GPI_IEOB_BMSK (0x100) #define GPI_IEOB_BMSK_SHIFT (8)
drivers/i2c/busses/i2c-qcom-geni.c +55 −14 Original line number Diff line number Diff line Loading @@ -98,6 +98,8 @@ struct geni_i2c_dev { int clk_fld_idx; struct dma_chan *tx_c; struct dma_chan *rx_c; struct msm_gpi_tre lock_t; struct msm_gpi_tre unlock_t; struct msm_gpi_tre cfg0_t; struct msm_gpi_tre go_t; struct msm_gpi_tre tx_t; Loading Loading @@ -370,9 +372,9 @@ static void gi2c_ev_cb(struct dma_chan *ch, struct msm_gpi_cb const *cb_str, } if (cb_str->cb_event != MSM_GPI_QUP_NOTIFY) GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "GSI QN err:0x%x, status:0x%x, err:%d\n", cb_str->error_log.error_code, m_stat, cb_str->cb_event); "GSI QN err:0x%x, status:0x%x, err:%d slv_addr: 0x%x R/W: %d\n", cb_str->error_log.error_code, m_stat, cb_str->cb_event, gi2c->cur->addr, gi2c->cur->flags); } static void gi2c_gsi_cb_err(struct msm_gpi_dma_async_tx_cb_param *cb, Loading @@ -398,7 +400,9 @@ static void gi2c_gsi_tx_cb(void *ptr) struct msm_gpi_dma_async_tx_cb_param *tx_cb = ptr; struct geni_i2c_dev *gi2c = tx_cb->userdata; if (!(gi2c->cur->flags & I2C_M_RD)) { if (tx_cb->completion_code == MSM_GPI_TCE_EOB) { complete(&gi2c->xfer); } else if (!(gi2c->cur->flags & I2C_M_RD)) { gi2c_gsi_cb_err(tx_cb, "TX"); complete(&gi2c->xfer); } Loading Loading @@ -460,6 +464,23 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], } } if (gi2c->is_shared) { struct msm_gpi_tre *lock_t = &gi2c->lock_t; struct msm_gpi_tre *unlock_t = &gi2c->unlock_t; /* lock */ lock_t->dword[0] = MSM_GPI_LOCK_TRE_DWORD0; lock_t->dword[1] = MSM_GPI_LOCK_TRE_DWORD1; lock_t->dword[2] = MSM_GPI_LOCK_TRE_DWORD2; lock_t->dword[3] = MSM_GPI_LOCK_TRE_DWORD3(0, 0, 0, 0, 1); /* unlock */ unlock_t->dword[0] = MSM_GPI_UNLOCK_TRE_DWORD0; unlock_t->dword[1] = MSM_GPI_UNLOCK_TRE_DWORD1; unlock_t->dword[2] = MSM_GPI_UNLOCK_TRE_DWORD2; unlock_t->dword[3] = MSM_GPI_UNLOCK_TRE_DWORD3(0, 0, 0, 1, 0); } if (!gi2c->cfg_sent) { struct geni_i2c_clk_fld *itr = geni_i2c_clk_map + gi2c->clk_fld_idx; Loading Loading @@ -499,24 +520,34 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], } qcom_geni_i2c_calc_timeout(gi2c); if (!gi2c->cfg_sent) { if (!gi2c->cfg_sent) segs++; if (gi2c->is_shared && (i == 0 || i == num-1)) { segs++; if (num == 1) segs++; sg_init_table(gi2c->tx_sg, segs); sg_set_buf(gi2c->tx_sg, &gi2c->cfg0_t, sizeof(gi2c->cfg0_t)); gi2c->cfg_sent = 1; index++; if (i == 0) sg_set_buf(&gi2c->tx_sg[index++], &gi2c->lock_t, sizeof(gi2c->lock_t)); } else { sg_init_table(gi2c->tx_sg, segs); } if (!gi2c->cfg_sent) { sg_set_buf(&gi2c->tx_sg[index++], &gi2c->cfg0_t, sizeof(gi2c->cfg0_t)); gi2c->cfg_sent = 1; } go_t->dword[0] = MSM_GPI_I2C_GO_TRE_DWORD0((stretch << 2), msgs[i].addr, op); go_t->dword[1] = MSM_GPI_I2C_GO_TRE_DWORD1; if (msgs[i].flags & I2C_M_RD) { go_t->dword[2] = MSM_GPI_I2C_GO_TRE_DWORD2(msgs[i].len); go_t->dword[3] = MSM_GPI_I2C_GO_TRE_DWORD3(1, 0, 0, 1, go_t->dword[3] = MSM_GPI_I2C_GO_TRE_DWORD3(1, 0, 0, 0, 0); } else { go_t->dword[2] = MSM_GPI_I2C_GO_TRE_DWORD2(0); Loading Loading @@ -588,6 +619,10 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], MSM_GPI_DMA_W_BUFFER_TRE_DWORD1(gi2c->tx_ph); gi2c->tx_t.dword[2] = MSM_GPI_DMA_W_BUFFER_TRE_DWORD2(msgs[i].len); if (gi2c->is_shared && i == num-1) gi2c->tx_t.dword[3] = MSM_GPI_DMA_W_BUFFER_TRE_DWORD3(0, 0, 1, 0, 1); else gi2c->tx_t.dword[3] = MSM_GPI_DMA_W_BUFFER_TRE_DWORD3(0, 0, 1, 0, 0); Loading @@ -595,6 +630,11 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], sizeof(gi2c->tx_t)); } if (gi2c->is_shared && i == num-1) { sg_set_buf(&gi2c->tx_sg[index++], &gi2c->unlock_t, sizeof(gi2c->unlock_t)); } gi2c->tx_desc = dmaengine_prep_slave_sg(gi2c->tx_c, gi2c->tx_sg, segs, DMA_MEM_TO_DEV, (DMA_PREP_INTERRUPT | Loading @@ -616,8 +656,9 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], gi2c->xfer_timeout); if (!timeout) { GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "GSI Txn timed out: %u len: %d\n", gi2c->xfer_timeout, gi2c->cur->len); "GSI Txn timed out: %u len: %d slv:addr: 0x%x R/W: %d\n", gi2c->xfer_timeout, gi2c->cur->len, gi2c->cur->addr, gi2c->cur->flags); geni_se_dump_dbg_regs(&gi2c->i2c_rsc, gi2c->base, gi2c->ipcl); gi2c->err = -ETIMEDOUT; Loading Loading @@ -1001,7 +1042,7 @@ static int geni_i2c_runtime_resume(struct device *dev) if (!gi2c->ipcl) { char ipc_name[I2C_NAME_SIZE]; snprintf(ipc_name, I2C_NAME_SIZE, "i2c-%d", gi2c->adap.nr); snprintf(ipc_name, I2C_NAME_SIZE, "%s", dev_name(gi2c->dev)); gi2c->ipcl = ipc_log_context_create(2, ipc_name, 0); } Loading
drivers/spi/spi-geni-qcom.c +1 −1 Original line number Diff line number Diff line Loading @@ -397,7 +397,7 @@ static struct msm_gpi_tre *setup_go_tre(int cmd, int cs, int rx_len, int flags, if (cmd == SPI_RX_ONLY) { eot = 0; chain = 0; eob = 1; eob = 0; } else { eot = 0; chain = 1; Loading
include/linux/msm_gpi.h +16 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,22 @@ enum msm_gpi_tre_type { #define MSM_GPI_TRE_TYPE(tre) ((tre->dword[3] >> 16) & 0xFF) /* Lock TRE */ #define MSM_GPI_LOCK_TRE_DWORD0 (0) #define MSM_GPI_LOCK_TRE_DWORD1 (0) #define MSM_GPI_LOCK_TRE_DWORD2 (0) #define MSM_GPI_LOCK_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) \ ((0x3 << 20) | (0x0 << 16) | (link_rx << 11) | (bei << 10) | \ (ieot << 9) | (ieob << 8) | ch) /* Unlock TRE */ #define MSM_GPI_UNLOCK_TRE_DWORD0 (0) #define MSM_GPI_UNLOCK_TRE_DWORD1 (0) #define MSM_GPI_UNLOCK_TRE_DWORD2 (0) #define MSM_GPI_UNLOCK_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) \ ((0x3 << 20) | (0x1 << 16) | (link_rx << 11) | (bei << 10) | \ (ieot << 9) | (ieob << 8) | ch) /* DMA w. Buffer TRE */ #ifdef CONFIG_ARM64 #define MSM_GPI_DMA_W_BUFFER_TRE_DWORD0(ptr) ((u32)ptr) Loading