From d34f57e9ca096796009095f74b86b8eb2f27dda8 Mon Sep 17 00:00:00 2001 From: Dan Sneddon <dsneddon@codeaurora.org> Date: Thu, 18 Dec 2014 10:07:14 -0700 Subject: [PATCH] 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> --- .../devicetree/bindings/spi/spi_qsd.txt | 1 + drivers/spi/spi_qsd.c | 62 +++++++++++++------ include/linux/qcom-spi.h | 19 ++++-- 3 files changed, 58 insertions(+), 24 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/spi_qsd.txt b/Documentation/devicetree/bindings/spi/spi_qsd.txt index 64fcafe0b05f..1bfb120c39f4 100644 --- a/Documentation/devicetree/bindings/spi/spi_qsd.txt +++ b/Documentation/devicetree/bindings/spi/spi_qsd.txt @@ -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 diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c index 3614f7ee1434..e167ca74d9f3 100644 --- a/drivers/spi/spi_qsd.c +++ b/drivers/spi/spi_qsd.c @@ -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 @@ -1855,17 +1855,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)) { - mutex_unlock(&dd->core_lock); - 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)) { @@ -1892,11 +1894,13 @@ 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. */ - 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); } - put_local_resources(dd); mutex_unlock(&dd->core_lock); if (dd->suspended) wake_up_interruptible(&dd->continue_suspend); @@ -1986,9 +1990,11 @@ static int msm_spi_setup(struct spi_device *spi) goto err_setup_exit; } - rc = get_local_resources(dd); - if (rc) - goto no_resources; + 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; @@ -2007,7 +2013,8 @@ static int msm_spi_setup(struct spi_device *spi) /* Ensure previous write completed before disabling the clocks */ mb(); - put_local_resources(dd); + 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); @@ -2422,6 +2429,8 @@ struct msm_spi_platform_data *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}, }; @@ -2801,9 +2810,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; } @@ -2831,9 +2845,17 @@ static int msm_spi_pm_resume_runtime(struct device *device) else dd->is_init_complete = true; } + 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: diff --git a/include/linux/qcom-spi.h b/include/linux/qcom-spi.h index bc7bc6f12e96..0382c008c89e 100644 --- a/include/linux/qcom-spi.h +++ b/include/linux/qcom-spi.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014 The Linux Foundation. All rights reserved. +/* 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 @@ -17,14 +17,24 @@ /** * 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. - * @rt when set, spi will pump transaction messages with high (realtime) - * priority to reduce the transfer latency on the bus by minimising - * the delay between a transfer request. + * @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; @@ -42,4 +52,5 @@ struct msm_spi_platform_data { u32 bam_producer_pipe_index; bool rt_priority; bool use_pinctrl; + bool is_shared; }; -- GitLab