Skip to content

Commit 2124331

Browse files
diandersandersson
authored andcommitted
spi: spi-qcom-qspi: Avoid clock setting if not needed
As per recent changes to the spi-qcom-qspi, now when we set the clock we'll call into the interconnect framework and also call the OPP API. Those are expensive operations. Let's avoid calling them if possible. This has a big impact on getting transfer rates back up to where they were (or maybe slightly better) before those patches landed. Fixes: cff8064 ("spi: spi-qcom-qspi: Add interconnect support") Signed-off-by: Douglas Anderson <[email protected]> Acked-by: Mark Brown <[email protected]> Reviewed-by: Rajendra Nayak <[email protected]> Tested-by: Rajendra Nayak <[email protected]> Reviewed-by: Mukesh Kumar Savaliya <[email protected]> Reviewed-by: Akash Asthana <[email protected]> Link: https://lore.kernel.org/r/20200709075113.v2.1.Ia7cb4f41ce93d37d0a764b47c8a453ce9e9c70ef@changeid Signed-off-by: Bjorn Andersson <[email protected]>
1 parent f79a158 commit 2124331

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

drivers/spi/spi-qcom-qspi.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ struct qcom_qspi {
144144
struct icc_path *icc_path_cpu_to_qspi;
145145
struct opp_table *opp_table;
146146
bool has_opp_table;
147+
unsigned long last_speed;
147148
/* Lock to protect data accessed by IRQs */
148149
spinlock_t lock;
149150
};
@@ -226,19 +227,13 @@ static void qcom_qspi_handle_err(struct spi_master *master,
226227
spin_unlock_irqrestore(&ctrl->lock, flags);
227228
}
228229

229-
static int qcom_qspi_transfer_one(struct spi_master *master,
230-
struct spi_device *slv,
231-
struct spi_transfer *xfer)
230+
static int qcom_qspi_set_speed(struct qcom_qspi *ctrl, unsigned long speed_hz)
232231
{
233-
struct qcom_qspi *ctrl = spi_master_get_devdata(master);
234232
int ret;
235-
unsigned long speed_hz;
236-
unsigned long flags;
237233
unsigned int avg_bw_cpu;
238234

239-
speed_hz = slv->max_speed_hz;
240-
if (xfer->speed_hz)
241-
speed_hz = xfer->speed_hz;
235+
if (speed_hz == ctrl->last_speed)
236+
return 0;
242237

243238
/* In regular operation (SBL_EN=1) core must be 4x transfer clock */
244239
ret = dev_pm_opp_set_rate(ctrl->dev, speed_hz * 4);
@@ -259,6 +254,28 @@ static int qcom_qspi_transfer_one(struct spi_master *master,
259254
return ret;
260255
}
261256

257+
ctrl->last_speed = speed_hz;
258+
259+
return 0;
260+
}
261+
262+
static int qcom_qspi_transfer_one(struct spi_master *master,
263+
struct spi_device *slv,
264+
struct spi_transfer *xfer)
265+
{
266+
struct qcom_qspi *ctrl = spi_master_get_devdata(master);
267+
int ret;
268+
unsigned long speed_hz;
269+
unsigned long flags;
270+
271+
speed_hz = slv->max_speed_hz;
272+
if (xfer->speed_hz)
273+
speed_hz = xfer->speed_hz;
274+
275+
ret = qcom_qspi_set_speed(ctrl, speed_hz);
276+
if (ret)
277+
return ret;
278+
262279
spin_lock_irqsave(&ctrl->lock, flags);
263280

264281
/* We are half duplex, so either rx or tx will be set */
@@ -602,7 +619,11 @@ static int __maybe_unused qcom_qspi_runtime_resume(struct device *dev)
602619
return ret;
603620
}
604621

605-
return clk_bulk_prepare_enable(QSPI_NUM_CLKS, ctrl->clks);
622+
ret = clk_bulk_prepare_enable(QSPI_NUM_CLKS, ctrl->clks);
623+
if (ret)
624+
return ret;
625+
626+
return dev_pm_opp_set_rate(dev, ctrl->last_speed * 4);
606627
}
607628

608629
static int __maybe_unused qcom_qspi_suspend(struct device *dev)

0 commit comments

Comments
 (0)