spi: spi_qsd: Reduce latency for non-shared cores

Resource aqquistion on a per transfer level incures
a noticable latency penalty.  This change removes
this latency by doing resource aqquisition as part
of runtime-pm on non-shared cores.

Change-Id: I112c10f52342ca7143b2286c72bba49ba7c8e49f
Signed-off-by: Dan Sneddon <dsneddon@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
This commit is contained in:
Dan Sneddon
2015-06-08 03:45:59 -07:00
committed by Gerrit - the friendly Code Review server
parent 8b78a4609a
commit 1bfc937a04
3 changed files with 106 additions and 23 deletions
@@ -36,6 +36,7 @@ Optional properties:
- qcom,rt-priority : whether spi message queue is set to run as a realtime task.
With this spi transaction message pump with high (realtime) priority to reduce
the transfer latency on the bus by minimising the delay between a transfer request
- qcom,shared : whether this qup is shared with other ee's
Optional properties which are required for support of BAM-mode:
- qcom,ver-reg-exists : Boolean. When present, allows driver to verify if HW
+49 -23
View File
@@ -1,4 +1,4 @@
/* Copyright (c) 2008-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -41,11 +41,11 @@
#include <linux/mutex.h>
#include <linux/atomic.h>
#include <linux/pm_runtime.h>
#include <mach/msm_spi.h>
#include <mach/sps.h>
#include <mach/dma.h>
#include <mach/msm_bus.h>
#include <mach/msm_bus_board.h>
#include <linux/qcom-spi.h>
#include "spi_qsd.h"
static int msm_spi_pm_resume_runtime(struct device *device);
@@ -2244,15 +2244,19 @@ static int msm_spi_transfer_one_message(struct spi_master *master,
* get local resources for each transfer to ensure we're in a good
* state and not interfering with other EE's using this device
*/
if (get_local_resources(dd))
return -EINVAL;
if (dd->pdata->is_shared) {
if (get_local_resources(dd)) {
mutex_unlock(&dd->core_lock);
return -EINVAL;
}
reset_core(dd);
if (dd->use_dma) {
msm_spi_bam_pipe_connect(dd, &dd->bam.prod,
&dd->bam.prod.config);
msm_spi_bam_pipe_connect(dd, &dd->bam.cons,
&dd->bam.cons.config);
reset_core(dd);
if (dd->use_dma) {
msm_spi_bam_pipe_connect(dd, &dd->bam.prod,
&dd->bam.prod.config);
msm_spi_bam_pipe_connect(dd, &dd->bam.cons,
&dd->bam.cons.config);
}
}
if (dd->suspended || !msm_spi_is_valid_state(dd)) {
@@ -2292,12 +2296,17 @@ static int msm_spi_transfer_one_message(struct spi_master *master,
* different context since we're running in the spi kthread here) to
* prevent race conditions between us and any other EE's using this hw.
*/
put_local_resources(dd);
if (dd->use_dma) {
msm_spi_bam_pipe_disconnect(dd, &dd->bam.prod);
msm_spi_bam_pipe_disconnect(dd, &dd->bam.cons);
if (dd->pdata->is_shared) {
if (dd->use_dma) {
msm_spi_bam_pipe_disconnect(dd, &dd->bam.prod);
msm_spi_bam_pipe_disconnect(dd, &dd->bam.cons);
}
put_local_resources(dd);
}
dd->cur_msg->status = status_error;
mutex_unlock(&dd->core_lock);
if (dd->suspended)
wake_up_interruptible(&dd->continue_suspend);
status_error = dd->cur_msg->status;
spi_finalize_current_message(master);
return 0;
}
@@ -2356,8 +2365,11 @@ static int msm_spi_setup(struct spi_device *spi)
return -EBUSY;
}
if (dd->use_rlock)
remote_mutex_lock(&dd->r_lock);
if (dd->pdata->is_shared) {
rc = get_local_resources(dd);
if (rc)
goto no_resources;
}
spi_ioc = readl_relaxed(dd->base + SPI_IO_CONTROL);
mask = SPI_IO_C_CS_N_POLARITY_0 << spi->chip_select;
@@ -2376,13 +2388,12 @@ static int msm_spi_setup(struct spi_device *spi)
/* Ensure previous write completed before disabling the clocks */
mb();
if (dd->use_rlock)
remote_mutex_unlock(&dd->r_lock);
if (dd->pdata->is_shared)
put_local_resources(dd);
/* Counter-part of system-resume when runtime-pm is not enabled. */
if (!pm_runtime_enabled(dd->dev))
msm_spi_pm_suspend_runtime(dd->dev);
no_resources:
mutex_unlock(&dd->core_lock);
@@ -2963,6 +2974,8 @@ struct msm_spi_platform_data * __init msm_spi_dt_to_pdata(
&dd->cs_gpios[3].gpio_num, DT_OPT, DT_GPIO, -1},
{"qcom,rt-priority",
&pdata->rt_priority, DT_OPT, DT_BOOL, 0},
{"qcom,shared",
&pdata->is_shared, DT_OPT, DT_BOOL, 0},
{NULL, NULL, 0, 0, 0},
};
@@ -3375,9 +3388,14 @@ static int msm_spi_pm_suspend_runtime(struct device *device)
wait_event_interruptible(dd->continue_suspend,
!dd->transfer_pending);
if (dd->pdata && !dd->pdata->is_shared && dd->use_dma) {
msm_spi_bam_pipe_disconnect(dd, &dd->bam.prod);
msm_spi_bam_pipe_disconnect(dd, &dd->bam.cons);
}
if (dd->pdata && !dd->pdata->active_only)
msm_spi_clk_path_unvote(dd);
if (dd->pdata && !dd->pdata->is_shared)
put_local_resources(dd);
suspend_exit:
return 0;
}
@@ -3397,10 +3415,18 @@ static int msm_spi_pm_resume_runtime(struct device *device)
if (!dd->suspended)
return 0;
if (!dd->pdata->is_shared)
get_local_resources(dd);
msm_spi_clk_path_init(dd);
if (!dd->pdata->active_only)
msm_spi_clk_path_vote(dd);
if (!dd->pdata->is_shared && dd->use_dma) {
msm_spi_bam_pipe_connect(dd, &dd->bam.prod,
&dd->bam.prod.config);
msm_spi_bam_pipe_connect(dd, &dd->bam.cons,
&dd->bam.cons.config);
}
dd->suspended = 0;
resume_exit:
+56
View File
@@ -0,0 +1,56 @@
/* Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/*
* SPI driver for Qualcomm MSM platforms.
*/
/**
* msm_spi_platform_data: msm spi-controller's configuration data
*
* @max_clock_speed max spi clock speed
* @active_only when set, votes when system active and removes the vote when
* system goes idle (optimises for performance). When unset, voting using
* runtime pm (optimizes for power).
* @master_id master id number of the controller's wrapper (BLSP or GSBI).
* When zero, clock path voting is disabled.
* @gpio_config pointer to function for configuring gpio
* @gpio_release pointer to function for releasing gpio pins
* @dma_config function poniter for configuring dma engine
* @pm_lat power management latency
* @infinite_mode use FIFO mode in infinite mode
* @ver_reg_exists if the version register exists
* @use_beam true if BAM is available
* @bam_consumer_pipe_index BAM conusmer pipe
* @bam_producer_pipe_index BAM producer pipe
* @rt_priority true if RT thread
* @use_pinctrl true if pinctrl library is used
* @is_shared true when qup is shared between ee's
*/
struct msm_spi_platform_data {
u32 max_clock_speed;
bool active_only;
u32 master_id;
int (*gpio_config)(void);
void (*gpio_release)(void);
int (*dma_config)(void);
const char *rsl_id;
u32 pm_lat;
u32 infinite_mode;
bool ver_reg_exists;
bool use_bam;
u32 bam_consumer_pipe_index;
u32 bam_producer_pipe_index;
bool rt_priority;
bool use_pinctrl;
bool is_shared;
};