Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 889c1d74 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "spi: spi-geni-qcom: Modify bus bw vote and DMA buffer mapping"

parents 6e9e533a 5f9df631
Loading
Loading
Loading
Loading
+3 −24
Original line number Diff line number Diff line
@@ -191,13 +191,6 @@ static inline void qcom_geni_i2c_conf(struct geni_i2c_dev *gi2c, int dfs)

static void geni_i2c_err(struct geni_i2c_dev *gi2c, int err)
{
	u32 m_cmd = readl_relaxed(gi2c->base + SE_GENI_M_CMD0);
	u32 m_stat = readl_relaxed(gi2c->base + SE_GENI_M_IRQ_STATUS);
	u32 geni_s = readl_relaxed(gi2c->base + SE_GENI_STATUS);
	u32 geni_ios = readl_relaxed(gi2c->base + SE_GENI_IOS);
	u32 dma = readl_relaxed(gi2c->base + SE_GENI_DMA_MODE_EN);
	u32 rx_st, tx_st;

	if (gi2c->cur)
		GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev,
			    "len:%d, slv-addr:0x%x, RD/WR:%d\n", gi2c->cur->len,
@@ -211,23 +204,9 @@ static void geni_i2c_err(struct geni_i2c_dev *gi2c, int err)
		GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "%s\n",
			     gi2c_log[err].msg);
	}
	if (gi2c->se_mode == GSI_ONLY)
		goto err_out;

	if (dma) {
		rx_st = readl_relaxed(gi2c->base + SE_DMA_RX_IRQ_STAT);
		tx_st = readl_relaxed(gi2c->base + SE_DMA_TX_IRQ_STAT);
	} else {
		rx_st = readl_relaxed(gi2c->base + SE_GENI_RX_FIFO_STATUS);
		tx_st = readl_relaxed(gi2c->base + SE_GENI_TX_FIFO_STATUS);
	}
	GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev,
		     "DMA:%d tx_stat:0x%x, rx_stat:0x%x, irq-stat:0x%x\n",
		     dma, tx_st, rx_st, m_stat);
err_out:
	GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev,
			     "m_cmd:0x%x, geni_status:0x%x, geni_ios:0x%x\n",
			     m_cmd, geni_s, geni_ios);
	GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s: se-mode:%d\n", __func__,
							gi2c->se_mode);
	geni_se_dump_dbg_regs(&gi2c->i2c_rsc, gi2c->base, gi2c->ipcl);
err_ret:
	gi2c->err = gi2c_log[err].err;
}
+73 −0
Original line number Diff line number Diff line
@@ -1247,6 +1247,79 @@ int geni_se_iommu_free_buf(struct device *wrapper_dev, dma_addr_t *iova,
}
EXPORT_SYMBOL(geni_se_iommu_free_buf);

/**
 * geni_se_dump_dbg_regs() - Print relevant registers that capture most
 *			accurately the state of an SE.
 * @_dev:		Pointer to the SE's device.
 * @iomem:		Base address of the SE's register space.
 * @ipc:		IPC log context handle.
 *
 * This function is used to print out all the registers that capture the state
 * of an SE to help debug any errors.
 *
 * Return:	None
 */
void geni_se_dump_dbg_regs(struct se_geni_rsc *rsc, void __iomem *base,
				void *ipc)
{
	u32 m_cmd0 = 0;
	u32 m_irq_status = 0;
	u32 geni_status = 0;
	u32 geni_ios = 0;
	u32 dma_rx_irq = 0;
	u32 dma_tx_irq = 0;
	u32 rx_fifo_status = 0;
	u32 tx_fifo_status = 0;
	u32 se_dma_dbg = 0;
	u32 m_cmd_ctrl = 0;
	u32 se_dma_rx_len = 0;
	u32 se_dma_rx_len_in = 0;
	u32 se_dma_tx_len = 0;
	u32 se_dma_tx_len_in = 0;
	struct geni_se_device *geni_se_dev;

	if (!ipc)
		return;

	geni_se_dev = dev_get_drvdata(rsc->wrapper_dev);
	if (unlikely(!geni_se_dev || !geni_se_dev->bus_bw))
		return;
	mutex_lock(&geni_se_dev->ab_ib_lock);
	if (unlikely(list_empty(&rsc->ab_list) || list_empty(&rsc->ib_list))) {
		GENI_SE_DBG(ipc, false, NULL, "%s: Clocks not on\n", __func__);
		goto exit_geni_se_dump_dbg_regs;
	}
	m_cmd0 = geni_read_reg(base, SE_GENI_M_CMD0);
	m_irq_status = geni_read_reg(base, SE_GENI_M_IRQ_STATUS);
	geni_status = geni_read_reg(base, SE_GENI_STATUS);
	geni_ios = geni_read_reg(base, SE_GENI_IOS);
	dma_rx_irq = geni_read_reg(base, SE_DMA_TX_IRQ_STAT);
	dma_tx_irq = geni_read_reg(base, SE_DMA_RX_IRQ_STAT);
	rx_fifo_status = geni_read_reg(base, SE_GENI_RX_FIFO_STATUS);
	tx_fifo_status = geni_read_reg(base, SE_GENI_TX_FIFO_STATUS);
	se_dma_dbg = geni_read_reg(base, SE_DMA_DEBUG_REG0);
	m_cmd_ctrl = geni_read_reg(base, SE_GENI_M_CMD_CTRL_REG);
	se_dma_rx_len = geni_read_reg(base, SE_DMA_RX_LEN);
	se_dma_rx_len_in = geni_read_reg(base, SE_DMA_RX_LEN_IN);
	se_dma_tx_len = geni_read_reg(base, SE_DMA_TX_LEN);
	se_dma_tx_len_in = geni_read_reg(base, SE_DMA_TX_LEN_IN);

	GENI_SE_DBG(ipc, false, NULL,
	"%s: m_cmd0:0x%x, m_irq_status:0x%x, geni_status:0x%x, geni_ios:0x%x\n",
	__func__, m_cmd0, m_irq_status, geni_status, geni_ios);
	GENI_SE_DBG(ipc, false, NULL,
	"dma_rx_irq:0x%x, dma_tx_irq:0x%x, rx_fifo_sts:0x%x, tx_fifo_sts:0x%x\n"
	, dma_rx_irq, dma_tx_irq, rx_fifo_status, tx_fifo_status);
	GENI_SE_DBG(ipc, false, NULL,
	"se_dma_dbg:0x%x, m_cmd_ctrl:0x%x, dma_rxlen:0x%x, dma_rxlen_in:0x%x\n",
	se_dma_dbg, m_cmd_ctrl, se_dma_rx_len, se_dma_rx_len_in);
	GENI_SE_DBG(ipc, false, NULL,
	"dma_txlen:0x%x, dma_txlen_in:0x%x\n", se_dma_tx_len, se_dma_tx_len_in);
exit_geni_se_dump_dbg_regs:
	mutex_unlock(&geni_se_dev->ab_ib_lock);
}
EXPORT_SYMBOL(geni_se_dump_dbg_regs);

static const struct of_device_id geni_se_dt_match[] = {
	{ .compatible = "qcom,qupv3-geni-se", },
	{ .compatible = "qcom,qupv3-geni-se-cb", },
+25 −17
Original line number Diff line number Diff line
@@ -298,7 +298,7 @@ static int select_xfer_mode(struct spi_master *spi,
	 */
	if (fifo_disable && !dma_chan_valid)
		mode = -EINVAL;
	else if (fifo_disable)
	else if (dma_chan_valid)
		mode = GSI_DMA;
	else
		mode = FIFO_MODE;
@@ -617,30 +617,32 @@ static int spi_geni_map_buf(struct spi_geni_master *mas,
				struct spi_message *msg)
{
	struct spi_transfer *xfer;
	struct device *gsi_dev = mas->dev;
	int ret = 0;

	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
		if (xfer->rx_buf) {
			xfer->rx_dma = dma_map_single(gsi_dev, xfer->rx_buf,
			ret = geni_se_iommu_map_buf(mas->wrapper_dev,
						&xfer->rx_dma, xfer->rx_buf,
						xfer->len, DMA_FROM_DEVICE);
			if (dma_mapping_error(mas->dev, xfer->rx_dma)) {
				dev_err(mas->dev, "Err mapping buf\n");
				return -ENOMEM;
			if (ret) {
				GENI_SE_ERR(mas->ipc, true, mas->dev,
				"%s: Mapping Rx buffer %d\n", __func__, ret);
				return ret;
			}
		}

		if (xfer->tx_buf) {
			xfer->tx_dma = dma_map_single(gsi_dev,
				(void *)xfer->tx_buf, xfer->len, DMA_TO_DEVICE);
			if (dma_mapping_error(gsi_dev, xfer->tx_dma)) {
				dev_err(mas->dev, "Err mapping buf\n");
				dma_unmap_single(gsi_dev, xfer->rx_dma,
						xfer->len, DMA_FROM_DEVICE);
				return -ENOMEM;
			ret = geni_se_iommu_map_buf(mas->wrapper_dev,
						&xfer->tx_dma,
						(void *)xfer->tx_buf,
						xfer->len, DMA_TO_DEVICE);
			if (ret) {
				GENI_SE_ERR(mas->ipc, true, mas->dev,
				"%s: Mapping Tx buffer %d\n", __func__, ret);
				return ret;
			}
		}
	};

	return 0;
}

@@ -648,14 +650,13 @@ static void spi_geni_unmap_buf(struct spi_geni_master *mas,
				struct spi_message *msg)
{
	struct spi_transfer *xfer;
	struct device *gsi_dev = mas->dev;

	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
		if (xfer->rx_buf)
			dma_unmap_single(gsi_dev, xfer->rx_dma,
			geni_se_iommu_unmap_buf(mas->wrapper_dev, &xfer->rx_dma,
						xfer->len, DMA_FROM_DEVICE);
		if (xfer->tx_buf)
			dma_unmap_single(gsi_dev, xfer->tx_dma,
			geni_se_iommu_unmap_buf(mas->wrapper_dev, &xfer->tx_dma,
						xfer->len, DMA_TO_DEVICE);
	};
}
@@ -709,7 +710,12 @@ static int spi_geni_prepare_transfer_hardware(struct spi_master *spi)
{
	struct spi_geni_master *mas = spi_master_get_devdata(spi);
	int ret = 0;
	u32 max_speed = spi->cur_msg->spi->max_speed_hz;
	struct se_geni_rsc *rsc = &mas->spi_rsc;

	/* Adjust the AB/IB based on the max speed of the slave.*/
	rsc->ib = max_speed * DEFAULT_BUS_WIDTH;
	rsc->ab = max_speed * DEFAULT_BUS_WIDTH;
	ret = pm_runtime_get_sync(mas->dev);
	if (ret < 0) {
		dev_err(mas->dev, "Error enabling SE resources\n");
@@ -900,6 +906,7 @@ static void handle_fifo_timeout(struct spi_geni_master *mas)
{
	unsigned long timeout;

	geni_se_dump_dbg_regs(&mas->spi_rsc, mas->base, mas->ipc);
	reinit_completion(&mas->xfer_done);
	geni_cancel_m_cmd(mas->base);
	geni_write_reg(0, mas->base, SE_GENI_TX_WATERMARK_REG);
@@ -986,6 +993,7 @@ static int spi_geni_transfer_one(struct spi_master *spi,
	}
	return ret;
err_gsi_geni_transfer_one:
	geni_se_dump_dbg_regs(&mas->spi_rsc, mas->base, mas->ipc);
	dmaengine_terminate_all(mas->tx);
	return ret;
err_fifo_geni_transfer_one:
+22 −0
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ struct se_geni_rsc {
#define SE_HW_PARAM_0			(0xE24)
#define SE_HW_PARAM_1			(0xE28)
#define SE_DMA_GENERAL_CFG		(0xE30)
#define SE_DMA_DEBUG_REG0		(0xE40)

/* GENI_OUTPUT_CTRL fields */
#define DEFAULT_IO_OUTPUT_CTRL_MSK	(GENMASK(6, 0))
@@ -736,6 +737,22 @@ int geni_se_iommu_unmap_buf(struct device *wrapper_dev, dma_addr_t *iova,
int geni_se_iommu_free_buf(struct device *wrapper_dev, dma_addr_t *iova,
			   void *buf, size_t size);


/**
 * geni_se_dump_dbg_regs() - Print relevant registers that capture most
 *			accurately the state of an SE; meant to be called
 *			in case of errors to help debug.
 * @_dev:		Pointer to the SE's device.
 * @iomem:		Base address of the SE's register space.
 * @ipc:		IPC log context handle.
 *
 * This function is used to print out all the registers that capture the state
 * of an SE to help debug any errors.
 *
 * Return:	None
 */
void geni_se_dump_dbg_regs(struct se_geni_rsc *rsc, void __iomem *base,
				void *ipc);
#else
static inline unsigned int geni_read_reg_nolog(void __iomem *base, int offset)
{
@@ -907,5 +924,10 @@ static inline int geni_se_iommu_free_buf(struct device *wrapper_dev,
	return -ENXIO;
}

void geni_se_dump_dbg_regs(struct se_geni_rsc *rsc, void __iomem *base,
				void *ipc)
{
}

#endif
#endif