From 9712a5825e5ed7ca0978f0b52b23765e12da96c7 Mon Sep 17 00:00:00 2001 From: "Sravan Kumar D.V.N" Date: Tue, 3 May 2016 18:38:47 +0530 Subject: [PATCH 01/73] msm: mdss: Move PP programming after mdp wait for ping pong done To ensure PP registers are not programming in the middle of the frame transfer moving PP programming to after wait4pingpong for command mode panel devices Change-Id: Ie639a26543e2f20b61d6dfc73b3bcbd6a43b24be Signed-off-by: Sravan Kumar D.V.N Signed-off-by: Gopikrishnaiah Anandan --- drivers/video/fbdev/msm/mdss_mdp_ctl.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index 1d61653b76bb..5c471af850ff 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -5696,7 +5696,7 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, mdss_mdp_ctl_split_display_enable(split_lm_valid, ctl, sctl); ATRACE_BEGIN("postproc_programming"); - if (ctl->mfd && ctl->mfd->dcm_state != DTM_ENTER) + if (ctl->is_video_mode && ctl->mfd && ctl->mfd->dcm_state != DTM_ENTER) /* postprocessing setup, including dspp */ mdss_mdp_pp_setup_locked(ctl); @@ -5742,6 +5742,24 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, if (ctl->ops.wait_pingpong && !mdata->serialize_wait4pp) mdss_mdp_display_wait4pingpong(ctl, false); + /* Moved pp programming to post ping pong */ + if (!ctl->is_video_mode && ctl->mfd && + ctl->mfd->dcm_state != DTM_ENTER) { + /* postprocessing setup, including dspp */ + mutex_lock(&ctl->flush_lock); + mdss_mdp_pp_setup_locked(ctl); + if (sctl) { + if (ctl->split_flush_en) { + ctl->flush_bits |= sctl->flush_bits; + sctl->flush_bits = 0; + sctl_flush_bits = 0; + } else { + sctl_flush_bits = sctl->flush_bits; + } + } + ctl_flush_bits = ctl->flush_bits; + mutex_unlock(&ctl->flush_lock); + } /* * if serialize_wait4pp is false then roi_bkup used in wait4pingpong * will be of previous frame as expected. From b16b650f964c3faeb2d51dbc439d8a2b3fc0fbfe Mon Sep 17 00:00:00 2001 From: Sureshnaidu Laveti Date: Wed, 23 Nov 2016 07:08:56 -0800 Subject: [PATCH 02/73] msm: sensor: correcting return value for get actuator info Correcting the return value for getting the actuator information IOCTL. CRs-Fixed: 1084177 Change-Id: I2bbe7be3daedef45a5990c23168df5185e72e82f Signed-off-by: Sureshnaidu Laveti --- .../media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c index a700f836061c..b3623d9258f7 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c +++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c @@ -1418,6 +1418,7 @@ static int32_t msm_actuator_config(struct msm_actuator_ctrl_t *a_ctrl, case CFG_GET_ACTUATOR_INFO: cdata->is_af_supported = 1; cdata->cfg.cam_name = a_ctrl->cam_name; + rc = 0; break; case CFG_SET_ACTUATOR_INFO: From 25a64e34bbec7b14887cbfe8266ccf6f27113bab Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Wed, 7 Dec 2016 16:35:07 -0800 Subject: [PATCH 03/73] drivers: soc: qcom: Add error handling in function avtimer_ioctl Error handling is added to prevent garbage value being passed to user space by the uninitialized local variable avtimer_tick. CRs-Fixed: 1097878 Change-Id: I3f895deaae3acf329088cf8135859cc41e781763 Signed-off-by: Xiaoyu Ye --- drivers/soc/qcom/avtimer.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/avtimer.c b/drivers/soc/qcom/avtimer.c index 2bded5e83cce..4331af8890c0 100644 --- a/drivers/soc/qcom/avtimer.c +++ b/drivers/soc/qcom/avtimer.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 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 @@ -331,9 +331,17 @@ static long avtimer_ioctl(struct file *file, unsigned int ioctl_num, switch (ioctl_num) { case IOCTL_GET_AVTIMER_TICK: { - uint64_t avtimer_tick; + uint64_t avtimer_tick = 0; + int rc; + + rc = avcs_core_query_timer(&avtimer_tick); + + if (rc) { + pr_err("%s: Error: Invalid AV Timer tick, rc = %d\n", + __func__, rc); + return rc; + } - avcs_core_query_timer(&avtimer_tick); pr_debug_ratelimited("%s: AV Timer tick: time %llx\n", __func__, avtimer_tick); if (copy_to_user((void *) ioctl_param, &avtimer_tick, From f60739b341fcc3486ffde130ed4f805e2b5cc562 Mon Sep 17 00:00:00 2001 From: Phani Kumar Uppalapati Date: Tue, 6 Dec 2016 16:08:24 -0800 Subject: [PATCH 04/73] ASoC: wcd934x: Update class-H parameters based on headphone impedance Update Class-H parameters based on the measured headphone impedance values for wcd934x codec. CRs-Fixed: 1098041 Change-Id: I8cc22af138a343cd387f4400cff487faa66b3da0 Signed-off-by: Phani Kumar Uppalapati --- sound/soc/codecs/wcd934x/wcd934x-mbhc.c | 23 +++++++++++++++++++++++ sound/soc/codecs/wcd934x/wcd934x-mbhc.h | 2 ++ sound/soc/codecs/wcd934x/wcd934x.c | 19 +++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c b/sound/soc/codecs/wcd934x/wcd934x-mbhc.c index 5dbdb9a2df00..0e0c26dc72cd 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c +++ b/sound/soc/codecs/wcd934x/wcd934x-mbhc.c @@ -905,6 +905,29 @@ static const struct snd_kcontrol_new impedance_detect_controls[] = { tavil_hph_impedance_get, NULL), }; +/* + * tavil_mbhc_get_impedance: get impedance of headphone left and right channels + * @wcd934x_mbhc: handle to struct wcd934x_mbhc * + * @zl: handle to left-ch impedance + * @zr: handle to right-ch impedance + * return 0 for success or error code in case of failure + */ +int tavil_mbhc_get_impedance(struct wcd934x_mbhc *wcd934x_mbhc, + uint32_t *zl, uint32_t *zr) +{ + if (!wcd934x_mbhc) { + pr_err("%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + if (!zl || !zr) { + pr_err("%s: zl or zr null!\n", __func__); + return -EINVAL; + } + + return wcd_mbhc_get_impedance(&wcd934x_mbhc->wcd_mbhc, zl, zr); +} +EXPORT_SYMBOL(tavil_mbhc_get_impedance); + /* * tavil_mbhc_hs_detect: starts mbhc insertion/removal functionality * @codec: handle to snd_soc_codec * diff --git a/sound/soc/codecs/wcd934x/wcd934x-mbhc.h b/sound/soc/codecs/wcd934x/wcd934x-mbhc.h index 3c88a12194af..0b27f3f62b02 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-mbhc.h +++ b/sound/soc/codecs/wcd934x/wcd934x-mbhc.h @@ -44,6 +44,8 @@ extern int tavil_mbhc_hs_detect(struct snd_soc_codec *codec, extern void tavil_mbhc_deinit(struct snd_soc_codec *codec); extern int tavil_mbhc_post_ssr_init(struct wcd934x_mbhc *mbhc, struct snd_soc_codec *codec); +extern int tavil_mbhc_get_impedance(struct wcd934x_mbhc *wcd934x_mbhc, + uint32_t *zl, uint32_t *zr); #endif /* __WCD934X_MBHC_H__ */ diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c index 1fdf81a3a45f..321c7befd08f 100644 --- a/sound/soc/codecs/wcd934x/wcd934x.c +++ b/sound/soc/codecs/wcd934x/wcd934x.c @@ -175,6 +175,7 @@ enum { VI_SENSE_2, AUDIO_NOMINAL, HPH_PA_DELAY, + CLSH_Z_CONFIG, }; enum { @@ -2241,6 +2242,7 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, u8 dem_inp; int ret = 0; struct tavil_dsd_config *dsd_conf = tavil->dsd_config; + uint32_t impedl = 0, impedr = 0; dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, w->name, event, hph_mode); @@ -2277,6 +2279,18 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHL, hph_mode); + + ret = tavil_mbhc_get_impedance(tavil->mbhc, + &impedl, &impedr); + if (!ret) { + wcd_clsh_imped_config(codec, impedl, false); + set_bit(CLSH_Z_CONFIG, &tavil->status_mask); + } else { + dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n", + __func__, ret); + ret = 0; + } + break; case SND_SOC_DAPM_POST_PMD: /* 1000us required as per HW requirement */ @@ -2295,6 +2309,11 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, 0xF0, 0x0); + + if (test_bit(CLSH_Z_CONFIG, &tavil->status_mask)) { + wcd_clsh_imped_config(codec, impedl, true); + clear_bit(CLSH_Z_CONFIG, &tavil->status_mask); + } break; default: break; From 33c3372a82653d8bc7dc563b951d3eb5efb55da7 Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Tue, 13 Dec 2016 18:03:26 -0800 Subject: [PATCH 05/73] defconfig: msmcortex: Enable EHSET Test Fixture device driver Enable required EHSET Test fixture driver to perform the high speed electrical testing procedure for USB-IF compliance. Change-Id: I88f2748f0c8cf96fe7f6ab9ebaa82d51ec97f4fd Signed-off-by: Jack Pham --- arch/arm/configs/msmcortex_defconfig | 1 + arch/arm64/configs/msmcortex-perf_defconfig | 1 + arch/arm64/configs/msmcortex_defconfig | 1 + 3 files changed, 3 insertions(+) diff --git a/arch/arm/configs/msmcortex_defconfig b/arch/arm/configs/msmcortex_defconfig index 9eaa449d4df6..5e9afadeb7ae 100644 --- a/arch/arm/configs/msmcortex_defconfig +++ b/arch/arm/configs/msmcortex_defconfig @@ -353,6 +353,7 @@ CONFIG_USB_STORAGE=y CONFIG_USB_DWC3=y CONFIG_USB_ISP1760=y CONFIG_USB_ISP1760_HOST_ROLE=y +CONFIG_USB_EHSET_TEST_FIXTURE=y CONFIG_USB_OTG_WAKELOCK=y CONFIG_NOP_USB_XCEIV=y CONFIG_USB_MSM_SSPHY_QMP=y diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig index 60bb033be6df..f53843fdd813 100644 --- a/arch/arm64/configs/msmcortex-perf_defconfig +++ b/arch/arm64/configs/msmcortex-perf_defconfig @@ -429,6 +429,7 @@ CONFIG_USB_ISP1760=y CONFIG_USB_ISP1760_HOST_ROLE=y CONFIG_USB_PD_POLICY=y CONFIG_QPNP_USB_PDPHY=y +CONFIG_USB_EHSET_TEST_FIXTURE=y CONFIG_USB_OTG_WAKELOCK=y CONFIG_NOP_USB_XCEIV=y CONFIG_USB_MSM_SSPHY_QMP=y diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index 1ef2d90f13de..d4caf92667b1 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -431,6 +431,7 @@ CONFIG_USB_ISP1760=y CONFIG_USB_ISP1760_HOST_ROLE=y CONFIG_USB_PD_POLICY=y CONFIG_QPNP_USB_PDPHY=y +CONFIG_USB_EHSET_TEST_FIXTURE=y CONFIG_USB_OTG_WAKELOCK=y CONFIG_NOP_USB_XCEIV=y CONFIG_USB_MSM_SSPHY_QMP=y From b978a16710e7db7c9269aa6bb2172c4ea8e76b54 Mon Sep 17 00:00:00 2001 From: Mayank Rana Date: Thu, 9 Jul 2015 18:28:41 -0700 Subject: [PATCH 06/73] usb/xhci: Add support for EHSET tests for host compliance USB 2.0 specification defines following test modes for host electrical compliance: TEST_J/K/SE0_NAK and TEST_PACKET. Hence add support for same. CRs-Fixed: 868394 Change-Id: I885ae66be2d8cca17bcc0b87b7635a71c734e4b2 Signed-off-by: Manu Gautam Signed-off-by: Mayank Rana --- drivers/usb/host/xhci-hub.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index a7b055bc279a..b641d57fbfe1 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -885,6 +885,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 link_state = 0; u16 wake_mask = 0; u16 timeout = 0; + u16 test_mode = 0; max_ports = xhci_get_ports(hcd, &port_array); bus_state = &xhci->bus_state[hcd_index(hcd)]; @@ -958,8 +959,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, link_state = (wIndex & 0xff00) >> 3; if (wValue == USB_PORT_FEAT_REMOTE_WAKE_MASK) wake_mask = wIndex & 0xff00; - /* The MSB of wIndex is the U1/U2 timeout */ - timeout = (wIndex & 0xff00) >> 8; + /* The MSB of wIndex is the U1/U2 timeout OR TEST mode*/ + test_mode = timeout = (wIndex & 0xff00) >> 8; wIndex &= 0xff; if (!wIndex || wIndex > max_ports) goto error; @@ -1133,6 +1134,27 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, temp |= PORT_U2_TIMEOUT(timeout); writel(temp, port_array[wIndex] + PORTPMSC); break; + case USB_PORT_FEAT_TEST: + slot_id = xhci_find_slot_id_by_port(hcd, xhci, + wIndex + 1); + if (test_mode && test_mode <= 5) { + /* unlock to execute stop endpoint commands */ + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_stop_device(xhci, slot_id, 1); + spin_lock_irqsave(&xhci->lock, flags); + xhci_halt(xhci); + + temp = readl_relaxed(port_array[wIndex] + + PORTPMSC); + temp |= test_mode << 28; + writel_relaxed(temp, port_array[wIndex] + + PORTPMSC); + /* to make sure above write goes through */ + mb(); + } else { + goto error; + } + break; default: goto error; } From 2705050d4a352dfa0b5740fab067645a11d478f8 Mon Sep 17 00:00:00 2001 From: Trishansh Bhardwaj Date: Wed, 14 Dec 2016 11:46:28 +0530 Subject: [PATCH 07/73] msm: camera: Change %p into %pK Prevents kernel info leak by changing %p into %pK Change-Id: I7f1419c8f7fd7c371767f6921afe0cd8cfaad18f CRs-Fixed: 1052835 Signed-off-by: Trishansh Bhardwaj --- drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c | 6 +++--- drivers/media/platform/msm/camera_v2/isp/msm_isp40.c | 2 +- drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c | 2 +- .../media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c index 3e3143be0a13..a2d043469047 100644 --- a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c +++ b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c @@ -1097,11 +1097,11 @@ static int cam_smmu_map_secure_buffer_and_add_to_list(int idx, } if (table->sgl) { - CDBG("DMA buf: %p, device: %p, attach: %p, table: %p\n", + CDBG("DMA buf: %pK, device: %pK, attach: %pK, table: %pK\n", (void *)buf, (void *)iommu_cb_set.cb_info[idx].dev, (void *)attach, (void *)table); - CDBG("table sgl: %p, rc: %d, dma_address: 0x%x\n", + CDBG("table sgl: %pK, rc: %d, dma_address: 0x%x\n", (void *)table->sgl, rc, (unsigned int)table->sgl->dma_address); } else { @@ -1134,7 +1134,7 @@ static int cam_smmu_map_secure_buffer_and_add_to_list(int idx, rc = -ENOSPC; goto err_mapping_info; } - CDBG("dev = %p, paddr= %p, len = %u\n", + CDBG("dev = %pK, paddr= %pK, len = %u\n", (void *)iommu_cb_set.cb_info[idx].dev, (void *)*paddr_ptr, (unsigned int)*len_ptr); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c index 2d937fc3ed05..bc775e898a01 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c @@ -1099,7 +1099,7 @@ static int msm_vfe40_start_fetch_engine_multi_pass(struct vfe_device *vfe_dev, rc = vfe_dev->buf_mgr->ops->get_buf_by_index( vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf); if (rc < 0 || !buf) { - pr_err("%s: No fetch buffer rc= %d buf= %p\n", + pr_err("%s: No fetch buffer rc= %d buf= %pK\n", __func__, rc, buf); return -EINVAL; } diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index 1bf628de4df0..f7565d8de6e1 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -1753,7 +1753,7 @@ int msm_isp_cfg_offline_ping_pong_address(struct vfe_device *vfe_dev, rc = vfe_dev->buf_mgr->ops->get_buf_by_index( vfe_dev->buf_mgr, bufq_handle, buf_idx, &buf); if (rc < 0 || !buf) { - pr_err("%s: No fetch buffer rc= %d buf= %p\n", + pr_err("%s: No fetch buffer rc= %d buf= %pK\n", __func__, rc, buf); return -EINVAL; } diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c index 8213f736205a..a8ebafcb20e0 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c @@ -86,7 +86,7 @@ static int cpp_get_clk_freq_tbl_dt(struct cpp_device *cpp_dev) hw_info = &cpp_dev->hw_info; if ((hw_info == NULL) || (of_node == NULL)) { - pr_err("Invalid hw_info %p or ofnode %p\n", hw_info, of_node); + pr_err("Invalid hw_info %pK or ofnode %pK\n", hw_info, of_node); rc = -EINVAL; goto err; From 68a23c3a172b3f1d1712d7516397852ad74a9e8a Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Thu, 20 Jun 2013 13:31:37 -0700 Subject: [PATCH 08/73] usb: xhci: Add support for SINGLE_STEP_SET_FEATURE test of EHSET The Embedded High-speed Host Electrical Test (EHSET) procedure defines the SINGLE_STEP_SET_FEATURE test for an embedded USB Host port. Upon activating this test mode, the SETUP stage of a GetDescriptor request is sent and followed by a delay of 15 seconds before finishing with the DATA and STATUS stages. The idea is that this delay will give the test operator sufficient time to configure the oscilloscope to perform a measurement of the response time delay between the latter two stages. This test is not implemented by the EHCI/xHCI host controller itself but can be implemented in software. Similar to commit 9841f37a1cca ("usb: ehci: Add support for SINGLE_STEP_SET_FEATURE test of EHSET"), this patch adds such support to the xHCI driver. Change-Id: I638ca552f6dae735147378f3e6f6068e0003094b Signed-off-by: Jack Pham --- drivers/usb/host/xhci-hub.c | 152 ++++++++++++++++++++++++++++++++++- drivers/usb/host/xhci-ring.c | 150 ++++++++++++++++++++++++++++++++++ drivers/usb/host/xhci.h | 4 + 3 files changed, 305 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index b641d57fbfe1..e0acf51e1faa 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -20,7 +20,7 @@ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - +#include #include #include @@ -871,6 +871,151 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, return status; } +static void xhci_single_step_completion(struct urb *urb) +{ + struct completion *done = urb->context; + + complete(done); +} + +/* + * Allocate a URB and initialize the various fields of it. + * This API is used by the single_step_set_feature test of + * EHSET where IN packet of the GetDescriptor request is + * sent 15secs after the SETUP packet. + * Return NULL if failed. + */ +static struct urb *xhci_request_single_step_set_feature_urb( + struct usb_device *udev, + void *dr, + void *buf, + struct completion *done) +{ + struct urb *urb; + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + struct usb_host_endpoint *ep; + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) + return NULL; + + urb->pipe = usb_rcvctrlpipe(udev, 0); + ep = udev->ep_in[usb_pipeendpoint(urb->pipe)]; + if (!ep) { + usb_free_urb(urb); + return NULL; + } + + /* + * Initialize the various URB fields as these are used by the HCD + * driver to queue it and as well as when completion happens. + */ + urb->ep = ep; + urb->dev = udev; + urb->setup_packet = dr; + urb->transfer_buffer = buf; + urb->transfer_buffer_length = USB_DT_DEVICE_SIZE; + urb->complete = xhci_single_step_completion; + urb->status = -EINPROGRESS; + urb->actual_length = 0; + urb->transfer_flags = URB_DIR_IN; + usb_get_urb(urb); + atomic_inc(&urb->use_count); + atomic_inc(&urb->dev->urbnum); + usb_hcd_map_urb_for_dma(hcd, urb, GFP_KERNEL); + urb->context = done; + return urb; +} + +/* + * This function implements the USB_PORT_FEAT_TEST handling of the + * SINGLE_STEP_SET_FEATURE test mode as defined in the Embedded + * High-Speed Electrical Test (EHSET) specification. This simply + * issues a GetDescriptor control transfer, with an inserted 15-second + * delay after the end of the SETUP stage and before the IN token of + * the DATA stage is set. The idea is that this gives the test operator + * enough time to configure the oscilloscope to perform a measurement + * of the response time between the DATA and ACK packets that follow. + */ +static int xhci_ehset_single_step_set_feature(struct usb_hcd *hcd, int port) +{ + int retval; + struct usb_ctrlrequest *dr; + struct urb *urb; + struct usb_device *udev; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct usb_device_descriptor *buf; + unsigned long flags; + DECLARE_COMPLETION_ONSTACK(done); + + /* Obtain udev of the rhub's child port */ + udev = usb_hub_find_child(hcd->self.root_hub, port); + if (!udev) { + xhci_err(xhci, "No device attached to the RootHub\n"); + return -ENODEV; + } + buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + if (!dr) { + kfree(buf); + return -ENOMEM; + } + + /* Fill Setup packet for GetDescriptor */ + dr->bRequestType = USB_DIR_IN; + dr->bRequest = USB_REQ_GET_DESCRIPTOR; + dr->wValue = cpu_to_le16(USB_DT_DEVICE << 8); + dr->wIndex = 0; + dr->wLength = cpu_to_le16(USB_DT_DEVICE_SIZE); + urb = xhci_request_single_step_set_feature_urb(udev, dr, buf, &done); + if (!urb) { + retval = -ENOMEM; + goto cleanup; + } + + /* Now complete just the SETUP stage */ + spin_lock_irqsave(&xhci->lock, flags); + retval = xhci_submit_single_step_set_feature(hcd, urb, 1); + spin_unlock_irqrestore(&xhci->lock, flags); + if (retval) + goto out1; + + if (!wait_for_completion_timeout(&done, msecs_to_jiffies(2000))) { + usb_kill_urb(urb); + retval = -ETIMEDOUT; + xhci_err(xhci, "%s SETUP stage timed out on ep0\n", __func__); + goto out1; + } + + /* Sleep for 15 seconds; HC will send SOFs during this period */ + msleep(15 * 1000); + + /* Complete remaining DATA and status stages. Re-use same URB */ + urb->status = -EINPROGRESS; + usb_get_urb(urb); + atomic_inc(&urb->use_count); + atomic_inc(&urb->dev->urbnum); + + spin_lock_irqsave(&xhci->lock, flags); + retval = xhci_submit_single_step_set_feature(hcd, urb, 0); + spin_unlock_irqrestore(&xhci->lock, flags); + if (!retval && !wait_for_completion_timeout(&done, + msecs_to_jiffies(2000))) { + usb_kill_urb(urb); + retval = -ETIMEDOUT; + xhci_err(xhci, "%s IN stage timed out on ep0\n", __func__); + } +out1: + usb_free_urb(urb); +cleanup: + kfree(dr); + kfree(buf); + return retval; +} + int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) { @@ -1151,6 +1296,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, PORTPMSC); /* to make sure above write goes through */ mb(); + } else if (test_mode == 6) { + spin_unlock_irqrestore(&xhci->lock, flags); + retval = xhci_ehset_single_step_set_feature(hcd, + wIndex); + spin_lock_irqsave(&xhci->lock, flags); } else { goto error; } diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 34cd23724bed..5ace1f79b14e 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3544,6 +3544,156 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, return 0; } +/* + * Variant of xhci_queue_ctrl_tx() used to implement EHSET + * SINGLE_STEP_SET_FEATURE test mode. It differs in that the control + * transfer is broken up so that the SETUP stage can happen and call + * the URB's completion handler before the DATA/STATUS stages are + * executed by the xHC hardware. This assumes the control transfer is a + * GetDescriptor, with a DATA stage in the IN direction, and an OUT + * STATUS stage. + * + * This function is called twice, usually with a 15-second delay in between. + * - with is_setup==true, the SETUP stage for the control request + * (GetDescriptor) is queued in the TRB ring and sent to HW immediately + * - with is_setup==false, the DATA and STATUS TRBs are queued and exceuted + * + * Caller must have locked xhci->lock + */ +int xhci_submit_single_step_set_feature(struct usb_hcd *hcd, struct urb *urb, + int is_setup) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_ring *ep_ring; + int num_trbs; + int ret; + unsigned int slot_id, ep_index; + struct usb_ctrlrequest *setup; + struct xhci_generic_trb *start_trb; + int start_cycle; + u32 field, length_field, remainder; + struct urb_priv *urb_priv; + struct xhci_td *td; + + ep_ring = xhci_urb_to_transfer_ring(xhci, urb); + if (!ep_ring) + return -EINVAL; + + /* Need buffer for data stage */ + if (urb->transfer_buffer_length <= 0) + return -EINVAL; + + /* + * Need to copy setup packet into setup TRB, so we can't use the setup + * DMA address. + */ + if (!urb->setup_packet) + return -EINVAL; + setup = (struct usb_ctrlrequest *) urb->setup_packet; + + slot_id = urb->dev->slot_id; + ep_index = xhci_get_endpoint_index(&urb->ep->desc); + + urb_priv = kzalloc(sizeof(struct urb_priv) + + sizeof(struct xhci_td *), GFP_ATOMIC); + if (!urb_priv) + return -ENOMEM; + + td = urb_priv->td[0] = kzalloc(sizeof(struct xhci_td), GFP_ATOMIC); + if (!td) { + kfree(urb_priv); + return -ENOMEM; + } + + urb_priv->length = 1; + urb_priv->td_cnt = 0; + urb->hcpriv = urb_priv; + + num_trbs = is_setup ? 1 : 2; + + ret = prepare_transfer(xhci, xhci->devs[slot_id], + ep_index, urb->stream_id, + num_trbs, urb, 0, GFP_ATOMIC); + if (ret < 0) { + kfree(td); + kfree(urb_priv); + return ret; + } + + /* + * Don't give the first TRB to the hardware (by toggling the cycle bit) + * until we've finished creating all the other TRBs. The ring's cycle + * state may change as we enqueue the other TRBs, so save it too. + */ + start_trb = &ep_ring->enqueue->generic; + start_cycle = ep_ring->cycle_state; + + if (is_setup) { + /* Queue only the setup TRB */ + field = TRB_IDT | TRB_IOC | TRB_TYPE(TRB_SETUP); + if (start_cycle == 0) + field |= 0x1; + + /* xHCI 1.0 6.4.1.2.1: Transfer Type field */ + if (xhci->hci_version == 0x100) { + if (setup->bRequestType & USB_DIR_IN) + field |= TRB_TX_TYPE(TRB_DATA_IN); + else + field |= TRB_TX_TYPE(TRB_DATA_OUT); + } + + /* Save the DMA address of the last TRB in the TD */ + td->last_trb = ep_ring->enqueue; + + queue_trb(xhci, ep_ring, false, + setup->bRequestType | setup->bRequest << 8 | + le16_to_cpu(setup->wValue) << 16, + le16_to_cpu(setup->wIndex) | + le16_to_cpu(setup->wLength) << 16, + TRB_LEN(8) | TRB_INTR_TARGET(0), + field); + } else { + /* Queue data TRB */ + field = TRB_ISP | TRB_TYPE(TRB_DATA); + if (start_cycle == 0) + field |= 0x1; + if (setup->bRequestType & USB_DIR_IN) + field |= TRB_DIR_IN; + + remainder = xhci_td_remainder(xhci, 0, + urb->transfer_buffer_length, + urb->transfer_buffer_length, + urb, 1); + + length_field = TRB_LEN(urb->transfer_buffer_length) | + TRB_TD_SIZE(remainder) | + TRB_INTR_TARGET(0); + + queue_trb(xhci, ep_ring, true, + lower_32_bits(urb->transfer_dma), + upper_32_bits(urb->transfer_dma), + length_field, + field); + + /* Save the DMA address of the last TRB in the TD */ + td->last_trb = ep_ring->enqueue; + + /* Queue status TRB */ + field = TRB_IOC | TRB_TYPE(TRB_STATUS); + if (!(setup->bRequestType & USB_DIR_IN)) + field |= TRB_DIR_IN; + + queue_trb(xhci, ep_ring, false, + 0, + 0, + TRB_INTR_TARGET(0), + field | ep_ring->cycle_state); + } + + giveback_first_trb(xhci, slot_id, ep_index, 0, start_cycle, start_trb); + return 0; +} + static int count_isoc_trbs_needed(struct xhci_hcd *xhci, struct urb *urb, int i) { diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index dc03aac4f88a..097cfa9e4692 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1960,4 +1960,8 @@ struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_container_ struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index); +/* EHSET */ +int xhci_submit_single_step_set_feature(struct usb_hcd *hcd, struct urb *urb, + int is_setup); + #endif /* __LINUX_XHCI_HCD_H */ From 4126207edf24ed9410f48f3b7d591abd43768e18 Mon Sep 17 00:00:00 2001 From: Prasad Sodagudi Date: Tue, 13 Dec 2016 12:50:06 -0800 Subject: [PATCH 09/73] power: reset: Store KASLR offset in IMEM Store kaslr offset in IMEM entry for debugging Change-Id: I2f9b4e9d45f95066ec93bb5fab179a14bc2c62ee Signed-off-by: Prasad Sodagudi --- .../devicetree/bindings/arm/msm/imem.txt | 11 +++++++ drivers/power/reset/msm-poweroff.c | 31 ++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/msm/imem.txt b/Documentation/devicetree/bindings/arm/msm/imem.txt index a9d2a2456cfd..2989fbfe7972 100644 --- a/Documentation/devicetree/bindings/arm/msm/imem.txt +++ b/Documentation/devicetree/bindings/arm/msm/imem.txt @@ -63,6 +63,11 @@ Emergency Download Mode: -compatible: "qcom,msm-imem-emergency_download_mode" -reg: start address and size of emergency_download_mode region in imem +Kaslr Offset: +------------------------ +-compatible: "qcom,msm-imem-kaslr_offset" +-reg: start address and size of kaslr_offset region in imem + USB Diag Cookies: ----------------- Memory region used to store USB PID and serial numbers to be used by @@ -101,6 +106,12 @@ Example: reg = <0x6b0 32>; }; + kaslr_offset@6d0 { + compatible = "qcom,msm-imem-kaslr_offset"; + reg = <0x6d0 12>; + }; + + pil@94c { compatible = "qcom,msm-imem-pil"; reg = <0x94c 200>; diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c index d32f293695bb..267df592ba8a 100644 --- a/drivers/power/reset/msm-poweroff.c +++ b/drivers/power/reset/msm-poweroff.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -65,11 +66,17 @@ static struct kobject dload_kobj; #ifdef CONFIG_QCOM_DLOAD_MODE #define EDL_MODE_PROP "qcom,msm-imem-emergency_download_mode" #define DL_MODE_PROP "qcom,msm-imem-download_mode" +#ifdef CONFIG_RANDOMIZE_BASE +#define KASLR_OFFSET_PROP "qcom,msm-imem-kaslr_offset" +#endif static int in_panic; static void *dload_mode_addr; static bool dload_mode_enabled; static void *emergency_dload_mode_addr; +#ifdef CONFIG_RANDOMIZE_BASE +static void *kaslr_imem_addr; +#endif static bool scm_dload_supported; static int dload_set(const char *val, struct kernel_param *kp); @@ -510,6 +517,28 @@ static int msm_restart_probe(struct platform_device *pdev) pr_err("unable to map imem EDLOAD mode offset\n"); } +#ifdef CONFIG_RANDOMIZE_BASE +#define KASLR_OFFSET_BIT_MASK 0x00000000FFFFFFFF + np = of_find_compatible_node(NULL, NULL, KASLR_OFFSET_PROP); + if (!np) { + pr_err("unable to find DT imem KASLR_OFFSET node\n"); + } else { + kaslr_imem_addr = of_iomap(np, 0); + if (!kaslr_imem_addr) + pr_err("unable to map imem KASLR offset\n"); + } + + if (kaslr_imem_addr && scm_is_secure_device()) { + __raw_writel(0xdead4ead, kaslr_imem_addr); + __raw_writel(KASLR_OFFSET_BIT_MASK & + (kimage_vaddr - KIMAGE_VADDR), kaslr_imem_addr + 4); + __raw_writel(KASLR_OFFSET_BIT_MASK & + ((kimage_vaddr - KIMAGE_VADDR) >> 32), + kaslr_imem_addr + 8); + iounmap(kaslr_imem_addr); + } +#endif + np = of_find_compatible_node(NULL, NULL, "qcom,msm-imem-dload-type"); if (!np) { @@ -603,4 +632,4 @@ static int __init msm_restart_init(void) { return platform_driver_register(&msm_restart_driver); } -device_initcall(msm_restart_init); +pure_initcall(msm_restart_init); From 4f22b257513b89e51c583962197ff2f25b5f1f64 Mon Sep 17 00:00:00 2001 From: Prasad Sodagudi Date: Tue, 13 Dec 2016 13:11:01 -0800 Subject: [PATCH 10/73] ARM: dts: msm: Add kaslr offset IMEM entry for msm8998 Add kaslr offset imem entry for msm8998. Change-Id: I456c62764c88149b785ecf1d65691ea5a775c1db Signed-off-by: Prasad Sodagudi --- arch/arm/boot/dts/qcom/msm8998.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm8998.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi index c265eafcdd30..b40b0c3ef517 100644 --- a/arch/arm/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998.dtsi @@ -2826,6 +2826,11 @@ reg = <0x6b0 32>; }; + kaslr_offset@6d0 { + compatible = "qcom,msm-imem-kaslr_offset"; + reg = <0x6d0 12>; + }; + pil@94c { compatible = "qcom,msm-imem-pil"; reg = <0x94c 200>; From 40512fa4ebee46b726def91300aa73da07d8555c Mon Sep 17 00:00:00 2001 From: Phani Kumar Uppalapati Date: Fri, 16 Dec 2016 17:06:27 -0800 Subject: [PATCH 11/73] ASoC: wcd934x: Fix headset TX mode setting Headset TX can be operated in 3 modes, low-power, high-perf and default. Currently in driver mode is always being set to default even though mixer controls are set for low-power and high-perf. Fix the mode setting by correctly parsing the mixer control value and set it during TX path enable. CRs-Fixed: 1102584 Change-Id: Idd40a0b471293048833b34dda3ac5044a87fc3c9 Signed-off-by: Phani Kumar Uppalapati --- sound/soc/codecs/wcd934x/wcd934x.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c index 1fdf81a3a45f..8b6eb68aadd6 100644 --- a/sound/soc/codecs/wcd934x/wcd934x.c +++ b/sound/soc/codecs/wcd934x/wcd934x.c @@ -5107,19 +5107,18 @@ static int tavil_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - u16 amic_reg; + u16 amic_reg = 0; if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE")) amic_reg = WCD934X_ANA_AMIC1; if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE")) amic_reg = WCD934X_ANA_AMIC3; - else - goto ret; - ucontrol->value.integer.value[0] = - (snd_soc_read(codec, amic_reg) & WCD934X_AMIC_PWR_LVL_MASK) >> - WCD934X_AMIC_PWR_LVL_SHIFT; -ret: + if (amic_reg) + ucontrol->value.integer.value[0] = + (snd_soc_read(codec, amic_reg) & + WCD934X_AMIC_PWR_LVL_MASK) >> + WCD934X_AMIC_PWR_LVL_SHIFT; return 0; } @@ -5128,7 +5127,7 @@ static int tavil_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); u32 mode_val; - u16 amic_reg; + u16 amic_reg = 0; mode_val = ucontrol->value.enumerated.item[0]; @@ -5138,12 +5137,10 @@ static int tavil_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, amic_reg = WCD934X_ANA_AMIC1; if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE")) amic_reg = WCD934X_ANA_AMIC3; - else - goto ret; - snd_soc_update_bits(codec, amic_reg, WCD934X_AMIC_PWR_LVL_MASK, - mode_val << WCD934X_AMIC_PWR_LVL_SHIFT); -ret: + if (amic_reg) + snd_soc_update_bits(codec, amic_reg, WCD934X_AMIC_PWR_LVL_MASK, + mode_val << WCD934X_AMIC_PWR_LVL_SHIFT); return 0; } From 1cef6caaa65c80075975f80f3df29231c938a350 Mon Sep 17 00:00:00 2001 From: Walter Yang Date: Fri, 25 Nov 2016 14:00:57 +0800 Subject: [PATCH 12/73] ASoC: msm: Check prepare state to avoid duplicate channel query PCM prepare may be called for multiple times if any error occurs. Check the prepare state in slim dai driver so that duplicate slimbus channel query can be avoided. CRs-Fixed: 1099101 Change-Id: I41ab0baf1bbe6ccda6b8da2ecd077bea2a388e56 Signed-off-by: Walter Yang --- sound/soc/msm/qdsp6v2/msm-dai-slim.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/msm/qdsp6v2/msm-dai-slim.c b/sound/soc/msm/qdsp6v2/msm-dai-slim.c index 7c56f4ad8884..9f39b08cf08e 100644 --- a/sound/soc/msm/qdsp6v2/msm-dai-slim.c +++ b/sound/soc/msm/qdsp6v2/msm-dai-slim.c @@ -331,6 +331,13 @@ static int msm_dai_slim_prepare(struct snd_pcm_substream *substream, return -EINVAL; } + if (dai_data->status & DAI_STATE_PREPARED) { + dev_dbg(dai->dev, + "%s: dai id (%d) has already prepared.\n", + __func__, dai->id); + return 0; + } + dma_data = &dai_data->dma_data; snd_soc_dai_set_dma_data(dai, substream, dma_data); From 8777df6c6eabb099c5069081dc991bb819337ff6 Mon Sep 17 00:00:00 2001 From: Walter Yang Date: Mon, 28 Nov 2016 13:55:43 +0800 Subject: [PATCH 13/73] ASoC: msm: decrement slim channel ref to set the property Decrement the ref count in slimbus driver via slim_dealloc_ch so that property of slimbus controller can be updated successfully via slim_define_ch. CRs-Fixed: 1099101 Change-Id: I1e76eb2e1c575b433e3899ae2471719bf68ab1c1 Signed-off-by: Walter Yang --- sound/soc/msm/qdsp6v2/msm-dai-slim.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/msm-dai-slim.c b/sound/soc/msm/qdsp6v2/msm-dai-slim.c index 9f39b08cf08e..43a27eb35a44 100644 --- a/sound/soc/msm/qdsp6v2/msm-dai-slim.c +++ b/sound/soc/msm/qdsp6v2/msm-dai-slim.c @@ -314,7 +314,7 @@ static int msm_dai_slim_prepare(struct snd_pcm_substream *substream, struct msm_slim_dai_data *dai_data = NULL; struct slim_ch prop; int rc; - u8 i, j; + u8 i; dai_data = msm_slim_get_dai_data(drv_data, dai); if (!dai_data) { @@ -351,6 +351,10 @@ static int msm_dai_slim_prepare(struct snd_pcm_substream *substream, } } + /* To decrement the channel ref count*/ + for (i = 0; i < dai_data->ch_cnt; i++) + slim_dealloc_ch(drv_data->sdev, dai_data->chan_h[i]); + prop.prot = SLIM_AUTO_ISO; prop.baser = SLIM_RATE_4000HZ; prop.dataf = SLIM_CH_DATAF_NOT_DEFINED; @@ -374,8 +378,6 @@ static int msm_dai_slim_prepare(struct snd_pcm_substream *substream, error_define_chan: error_chan_query: - for (j = 0; j < i; j++) - slim_dealloc_ch(drv_data->sdev, dai_data->chan_h[j]); return rc; } @@ -385,7 +387,6 @@ static void msm_dai_slim_shutdown(struct snd_pcm_substream *stream, struct msm_dai_slim_drv_data *drv_data = dev_get_drvdata(dai->dev); struct msm_slim_dma_data *dma_data = NULL; struct msm_slim_dai_data *dai_data; - int i, rc = 0; dai_data = msm_slim_get_dai_data(drv_data, dai); dma_data = snd_soc_dai_get_dma_data(dai, stream); @@ -404,15 +405,6 @@ static void msm_dai_slim_shutdown(struct snd_pcm_substream *stream, return; } - for (i = 0; i < dai_data->ch_cnt; i++) { - rc = slim_dealloc_ch(drv_data->sdev, dai_data->chan_h[i]); - if (rc) { - dev_err(dai->dev, - "%s: dealloc_ch failed, err = %d\n", - __func__, rc); - } - } - snd_soc_dai_set_dma_data(dai, stream, NULL); /* clear prepared state for the dai */ CLR_DAI_STATE(dai_data->status, DAI_STATE_PREPARED); From da5c2e07e74d4e4d1f9548a22461b7eb1c46fae8 Mon Sep 17 00:00:00 2001 From: "Sravan Kumar D.V.N" Date: Tue, 6 Dec 2016 20:41:38 +0530 Subject: [PATCH 14/73] msm: mdss: Initialize mdss v3 pp driver ops for msmfalcon Define MDSS hw version and initialize mdss v3 pp driver ops for msmfalcon CRs-Fixed: 1102841 Change-Id: I2661a639c19dd451f22c9a29d7d75d9b3fb98114 Signed-off-by: Sravan Kumar D.V.N --- drivers/video/fbdev/msm/mdss_mdp_pp.c | 4 +++- include/uapi/linux/msm_mdp.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c index 5a8438caba4b..238e4466b299 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c @@ -1123,7 +1123,8 @@ static int pp_vig_pipe_setup(struct mdss_mdp_pipe *pipe, u32 *op) mdss_mdp_pp_get_dcm_state(pipe, &dcm_state); mdata = mdss_mdp_get_mdata(); - if (IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, MDSS_MDP_HW_REV_301) || + if (IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, MDSS_MDP_HW_REV_320) || + IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, MDSS_MDP_HW_REV_301) || IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, MDSS_MDP_HW_REV_300)) { if (pipe->src_fmt->is_yuv) { /* TODO: check csc cfg from PP block */ @@ -7663,6 +7664,7 @@ static int pp_get_driver_ops(struct mdp_pp_driver_ops *ops) break; case MDSS_MDP_HW_REV_300: case MDSS_MDP_HW_REV_301: + case MDSS_MDP_HW_REV_320: /* * Some of the REV_300 PP features are same as REV_107. * Get the driver ops for both the versions and update the diff --git a/include/uapi/linux/msm_mdp.h b/include/uapi/linux/msm_mdp.h index 20b879c2e5fc..4df3845c159c 100644 --- a/include/uapi/linux/msm_mdp.h +++ b/include/uapi/linux/msm_mdp.h @@ -118,6 +118,7 @@ #define MDSS_MDP_HW_REV_116 MDSS_MDP_REV(1, 16, 0) /* msmtitanium */ #define MDSS_MDP_HW_REV_300 MDSS_MDP_REV(3, 0, 0) /* msm8998 */ #define MDSS_MDP_HW_REV_301 MDSS_MDP_REV(3, 0, 1) /* msm8998 v1.0 */ +#define MDSS_MDP_HW_REV_320 MDSS_MDP_REV(3, 2, 0) /* msmfalcon */ enum { NOTIFY_UPDATE_INIT, From 5217beb812db9333a53f65c8cc622ed6afdce42b Mon Sep 17 00:00:00 2001 From: Pengfei Liu Date: Wed, 21 Dec 2016 14:57:05 +0800 Subject: [PATCH 15/73] ARM: dts: msm: Add support for new flash mode on msm8998 skuk board Add support for torch mode capability on msm8998 skuk board. Change-Id: I6d59c7804d0dac5087e9b0e6c4a0cdacb5ddf3db Signed-off-by: Pengfei Liu --- arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk.dtsi b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk.dtsi index 69b0286dba09..3e7b5614bc55 100644 --- a/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk.dtsi @@ -16,6 +16,7 @@ cell-index = <0>; compatible = "qcom,camera-flash"; qcom,flash-source = <&pmi8998_flash0 &pmi8998_flash1>; + qcom,torch-source = <&pmi8998_torch0 &pmi8998_torch1>; qcom,switch-source = <&pmi8998_switch0>; status = "ok"; }; @@ -24,6 +25,7 @@ cell-index = <1>; compatible = "qcom,camera-flash"; qcom,flash-source = <&pmi8998_flash2>; + qcom,torch-source = <&pmi8998_torch2>; qcom,switch-source = <&pmi8998_switch1>; status = "ok"; }; From 1822d09d17c643dce84fcda425270fd165a26a74 Mon Sep 17 00:00:00 2001 From: Jin Fu Date: Mon, 19 Dec 2016 14:29:18 +0800 Subject: [PATCH 16/73] ARM: dts: msm: Add TP device node into msm8998 interposer Add synaptics S3320 touch controller device node into msm8998 interposer. CRs-Fixed: 1103891 Change-Id: Iec6247a69c3258660eae398d6e3fe8215e3f254a Signed-off-by: Jin Fu --- arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi | 76 +++++++++++++++++++ ...msm8998-v2.1-interposer-msmfalcon-qrd.dtsi | 30 ++++++++ 2 files changed, 106 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi index d4a2290c9b0a..a8b13ba113bf 100644 --- a/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi @@ -1637,6 +1637,82 @@ }; }; + /* add pingrp for touchscreen */ + pmx_ts_int_active { + ts_int_active: ts_int_active { + mux { + pins = "gpio125"; + function = "gpio"; + }; + + config { + pins = "gpio125"; + drive-strength = <8>; + bias-pull-up; + }; + }; + }; + + pmx_ts_int_suspend { + ts_int_suspend1: ts_int_suspend1 { + mux { + pins = "gpio125"; + function = "gpio"; + }; + + config { + pins = "gpio125"; + drive-strength = <2>; + bias-pull-down; + }; + }; + }; + + pmx_ts_reset_active { + ts_reset_active: ts_reset_active { + mux { + pins = "gpio89"; + function = "gpio"; + }; + + config { + pins = "gpio89"; + drive-strength = <8>; + bias-pull-up; + }; + }; + }; + + pmx_ts_reset_suspend { + ts_reset_suspend1: ts_reset_suspend1 { + mux { + pins = "gpio89"; + function = "gpio"; + }; + + config { + pins = "gpio89"; + drive-strength = <2>; + bias-pull-down; + }; + }; + }; + + pmx_ts_release { + ts_release: ts_release { + mux { + pins = "gpio125", "gpio89"; + function = "gpio"; + }; + + config { + pins = "gpio125", "gpio89"; + drive-strength = <2>; + bias-pull-down; + }; + }; + }; + ts_mux { ts_active: ts_active { mux { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi index 83368136a8b3..7c48af5122fd 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi @@ -120,3 +120,33 @@ status = "ok"; }; + + +&i2c_5 { + status = "okay"; + synaptics@20 { + compatible = "synaptics,dsx"; + reg = <0x20>; + interrupt-parent = <&tlmm>; + interrupts = <125 0x2008>; + avdd-supply = <&pm2falcon_l3>; + vdd-supply = <&pmfalcon_l11>; + synaptics,vdd-voltage = <1880000 1880000>; + synaptics,avdd-voltage = <3000000 3008000>; + synaptics,vdd-current = <40000>; + synaptics,avdd-current = <20000>; + /* pins used by touchscreen */ + pinctrl-names = "pmx_ts_active", "pmx_ts_suspend", + "pmx_ts_release"; + pinctrl-0 = <&ts_int_active &ts_reset_active>; + pinctrl-1 = <&ts_int_suspend1 &ts_reset_suspend1>; + pinctrl-2 = <&ts_release>; + synaptics,display-coords = <0 0 1439 2559>; + synaptics,panel-coords = <0 0 1439 2779>; + synaptics,irq-gpio = <&tlmm 125 0x2008>; + synaptics,reset-gpio = <&tlmm 89 0x0>; + synaptics,i2c-pull-up; + synaptics,disable-gpios; + synaptics,button-map = <139 172 158>; + }; +}; From 9300744481cc098929ec2eab15405a853d949717 Mon Sep 17 00:00:00 2001 From: Srinivas Ramana Date: Thu, 8 Dec 2016 15:51:04 +0530 Subject: [PATCH 17/73] msm: rtb: record counter timestamp for every log record Record counter timestamp in every RTB log record to help correlate these events with other subsystem events which occur outside of cpu subsystem. Change-Id: Ib1291524c53c4ec757a494a1e08cb0925720e1a6 Signed-off-by: Srinivas Ramana --- kernel/trace/msm_rtb.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/kernel/trace/msm_rtb.c b/kernel/trace/msm_rtb.c index ba609d5eb07f..80058b544cb5 100644 --- a/kernel/trace/msm_rtb.c +++ b/kernel/trace/msm_rtb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, 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 @@ -27,6 +27,7 @@ #include #include #include +#include #define SENTINEL_BYTE_1 0xFF #define SENTINEL_BYTE_2 0xAA @@ -41,8 +42,9 @@ * 4) 4 bytes index * 4) 8 bytes extra data from the caller * 5) 8 bytes of timestamp + * 6) 8 bytes of cyclecount * - * Total = 32 bytes. + * Total = 40 bytes. */ struct msm_rtb_layout { unsigned char sentinel[3]; @@ -51,6 +53,7 @@ struct msm_rtb_layout { uint64_t caller; uint64_t data; uint64_t timestamp; + uint64_t cycle_count; } __attribute__ ((__packed__)); @@ -132,6 +135,11 @@ static void msm_rtb_write_timestamp(struct msm_rtb_layout *start) start->timestamp = sched_clock(); } +static void msm_rtb_write_cyclecount(struct msm_rtb_layout *start) +{ + start->cycle_count = get_cycles(); +} + static void uncached_logk_pc_idx(enum logk_event_type log_type, uint64_t caller, uint64_t data, int idx) { @@ -145,6 +153,7 @@ static void uncached_logk_pc_idx(enum logk_event_type log_type, uint64_t caller, msm_rtb_write_idx(idx, start); msm_rtb_write_data(data, start); msm_rtb_write_timestamp(start); + msm_rtb_write_cyclecount(start); mb(); return; From 31ce9ad348d6433eb63eccde6774ff6f0fd3979a Mon Sep 17 00:00:00 2001 From: Manikanta Sivapala Date: Mon, 19 Dec 2016 17:41:19 +0530 Subject: [PATCH 18/73] ARM: dts: msm: Update VA range for venus_ns and modify clock handle - Update Virtual address range for venus_ns. - Change the Handle of MMSSNOC_AXI_CLK clock to RPMCC clock handle. - Remove debug timeout. - Update QOS registers. CRs-Fixed: 1103405 Change-Id: Iaaa69a56f13db9304640f115863bb882c72551a8 Signed-off-by: Manikanta Sivapala --- arch/arm/boot/dts/qcom/msmfalcon-vidc.dtsi | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/arch/arm/boot/dts/qcom/msmfalcon-vidc.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-vidc.dtsi index 73d1cac48f9e..9a9c96f5181d 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-vidc.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-vidc.dtsi @@ -14,6 +14,8 @@ #include #include #include +#include + &soc { msm_vidc: qcom,vidc@cc00000 { @@ -25,16 +27,10 @@ qcom,hfi-version = "3xx"; qcom,firmware-name = "venus"; qcom,sw-power-collapse; - qcom,debug-timeout; qcom,reg-presets = - <0x80124 0x00000003>, - <0x80550 0x01111111>, - <0x80560 0x01111111>, - <0x80568 0x01111111>, - <0x80570 0x01111111>, - <0x80580 0x01111111>, - <0x80588 0x01111111>, - <0xe2010 0x00000000>; + <0x80010 0x00000003>, + <0x80018 0x05555556>, + <0x8001c 0x05555556>; qcom,max-hw-load = <1036800>; /* Full 4k @ 30 */ qcom,allowed-clock-rates = @@ -70,7 +66,7 @@ "mmss_video_axi_clk", "mmss_video_core0_clk"; clocks = <&clock_gcc GCC_MMSS_SYS_NOC_AXI_CLK>, - <&clock_gcc MMSSNOC_AXI_CLK>, + <&clock_rpmcc MMSSNOC_AXI_CLK>, <&clock_mmss MMSS_MNOC_AHB_CLK>, <&clock_mmss MMSS_BIMC_SMMU_AHB_CLK>, <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>, @@ -210,7 +206,7 @@ <&mmss_bimc_smmu 0x411>, <&mmss_bimc_smmu 0x431>; buffer-types = <0xfff>; - virtual-addr-pool = <0x70800000 0x8f800000>; + virtual-addr-pool = <0x70800000 0x6f800000>; }; firmware_cb { From f826f7e32acca3414fd614ef63342618a24224c9 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Thu, 15 Dec 2016 12:32:36 +0530 Subject: [PATCH 19/73] ARM: dts: msm: Add thermal sensor info for msmtriton Add thermal sensor related information, which provides information such as alias, type and scaling factor to Kernel Thermal Monitor(KTM). The KTM exposes these sensor information via sysfs to thermal-engine. Change-Id: Id65a720d20fb34b9b5dccf8626af00a1d0519ce3 Signed-off-by: Manaf Meethalavalappu Pallikunhi --- arch/arm/boot/dts/qcom/msmtriton.dtsi | 98 +++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msmtriton.dtsi b/arch/arm/boot/dts/qcom/msmtriton.dtsi index e577a5692d90..8c676cc2c728 100644 --- a/arch/arm/boot/dts/qcom/msmtriton.dtsi +++ b/arch/arm/boot/dts/qcom/msmtriton.dtsi @@ -449,6 +449,104 @@ qcom,sensors = <12>; }; + qcom,sensor-information { + compatible = "qcom,sensor-information"; + sensor_information0: qcom,sensor-information-0 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor0"; + qcom,scaling-factor = <10>; + }; + sensor_information1: qcom,sensor-information-1 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor1"; + qcom,scaling-factor = <10>; + }; + sensor_information2: qcom,sensor-information-2 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor2"; + qcom,scaling-factor = <10>; + }; + sensor_information3: qcom,sensor-information-3 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor3"; + qcom,scaling-factor = <10>; + }; + sensor_information4: qcom,sensor-information-4 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor4"; + qcom,scaling-factor = <10>; + }; + sensor_information5: qcom,sensor-information-5 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor5"; + qcom,scaling-factor = <10>; + }; + sensor_information6: qcom,sensor-information-6 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor6"; + qcom,scaling-factor = <10>; + }; + sensor_information7: qcom,sensor-information-7 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor7"; + qcom,scaling-factor = <10>; + }; + sensor_information8: qcom,sensor-information-8 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor8"; + qcom,scaling-factor = <10>; + qcom,alias-name = "gpu"; + }; + sensor_information9: qcom,sensor-information-9 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor9"; + qcom,scaling-factor = <10>; + }; + sensor_information10: qcom,sensor-information-10 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor10"; + qcom,scaling-factor = <10>; + }; + sensor_information11: qcom,sensor-information-11 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor11"; + qcom,scaling-factor = <10>; + }; + sensor_information12: qcom,sensor-information-12 { + qcom,sensor-type = "alarm"; + qcom,sensor-name = "pmfalcon_tz"; + qcom,scaling-factor = <1000>; + }; + sensor_information13: qcom,sensor-information-13 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "msm_therm"; + }; + sensor_information14: qcom,sensor-information-14 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "xo_therm"; + }; + sensor_information15: qcom,sensor-information-15 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "pa_therm0"; + }; + sensor_information16: qcom,sensor-information-16 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "pa_therm1"; + }; + sensor_information17: qcom,sensor-information-17 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "quiet_therm"; + }; + sensor_information18: qcom,sensor-information-18 { + qcom,sensor-type = "llm"; + qcom,sensor-name = "limits_sensor-00"; + }; + sensor_information19: qcom,sensor-information-19 { + qcom,sensor-type = "llm"; + qcom,sensor-name = "limits_sensor-01"; + }; + }; + wdog: qcom,wdt@17817000 { status = "disabled"; compatible = "qcom,msm-watchdog"; From 65f2f71b1ff51236ce1034cd92810da0d0e0969b Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Thu, 15 Dec 2016 12:48:37 +0530 Subject: [PATCH 20/73] ARM: dts: msm: Add thermal mitigation properties to msmtriton Add thermal properties to enable kernel thermal monitoring and mitigations like hotplug, thermal reset, vdd restriction, etc. for msmtriton. Add mitigation profiles for each physical CPU which has information like sensor to monitor and various mitigation types to enable for msmtriton. Change-Id: Ie85f7ede2d91767d0d5d20c90a481e6365ad7189 Signed-off-by: Manaf Meethalavalappu Pallikunhi --- arch/arm/boot/dts/qcom/msmtriton.dtsi | 74 +++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msmtriton.dtsi b/arch/arm/boot/dts/qcom/msmtriton.dtsi index 8c676cc2c728..958536fc05a4 100644 --- a/arch/arm/boot/dts/qcom/msmtriton.dtsi +++ b/arch/arm/boot/dts/qcom/msmtriton.dtsi @@ -46,6 +46,7 @@ compatible = "arm,armv8"; reg = <0x0 0x100>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile0>; efficiency = <1024>; next-level-cache = <&L2_1>; L2_1: l2-cache { @@ -69,6 +70,7 @@ compatible = "arm,armv8"; reg = <0x0 0x101>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile1>; efficiency = <1024>; next-level-cache = <&L2_1>; L1_I_101: l1-icache { @@ -86,6 +88,7 @@ compatible = "arm,armv8"; reg = <0x0 0x102>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile2>; efficiency = <1024>; next-level-cache = <&L2_1>; L1_I_102: l1-icache { @@ -103,6 +106,7 @@ compatible = "arm,armv8"; reg = <0x0 0x103>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile3>; efficiency = <1024>; next-level-cache = <&L2_1>; L1_I_103: l1-icache { @@ -120,6 +124,7 @@ compatible = "arm,armv8"; reg = <0x0 0x0>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile4>; efficiency = <1024>; next-level-cache = <&L2_0>; L2_0: l2-cache { @@ -143,6 +148,7 @@ compatible = "arm,armv8"; reg = <0x0 0x1>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile4>; efficiency = <1024>; next-level-cache = <&L2_0>; L1_I_1: l1-icache { @@ -160,6 +166,7 @@ compatible = "arm,armv8"; reg = <0x0 0x2>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile4>; efficiency = <1024>; next-level-cache = <&L2_0>; L1_I_2: l1-icache { @@ -177,6 +184,7 @@ compatible = "arm,armv8"; reg = <0x0 0x3>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile4>; efficiency = <1024>; next-level-cache = <&L2_0>; L1_I_3: l1-icache { @@ -547,6 +555,72 @@ }; }; + mitigation_profile0: qcom,limit_info-0 { + qcom,temperature-sensor = <&sensor_information3>; + qcom,hotplug-mitigation-enable; + }; + + mitigation_profile1: qcom,limit_info-1 { + qcom,temperature-sensor = <&sensor_information4>; + qcom,hotplug-mitigation-enable; + }; + + mitigation_profile2: qcom,limit_info-2 { + qcom,temperature-sensor = <&sensor_information5>; + qcom,hotplug-mitigation-enable; + }; + + mitigation_profile3: qcom,limit_info-3 { + qcom,temperature-sensor = <&sensor_information6>; + qcom,hotplug-mitigation-enable; + }; + + mitigation_profile4: qcom,limit_info-4 { + qcom,temperature-sensor = <&sensor_information1>; + qcom,hotplug-mitigation-enable; + }; + + qcom,msm-thermal { + compatible = "qcom,msm-thermal"; + qcom,sensor-id = <3>; + qcom,poll-ms = <100>; + qcom,therm-reset-temp = <115>; + qcom,core-limit-temp = <70>; + qcom,core-temp-hysteresis = <10>; + qcom,hotplug-temp = <105>; + qcom,hotplug-temp-hysteresis = <20>; + qcom,online-hotplug-core; + qcom,synchronous-cluster-id = <0 1>; + qcom,synchronous-cluster-map = <0 4 &CPU4 &CPU5 &CPU6 &CPU7>, + <1 4 &CPU0 &CPU1 &CPU2 &CPU3>; + + qcom,vdd-restriction-temp = <5>; + qcom,vdd-restriction-temp-hysteresis = <10>; + + vdd-dig-supply = <&pm2falcon_s3_floor_level>; + vdd-gfx-supply = <&gfx_vreg_corner>; + + qcom,vdd-dig-rstr{ + qcom,vdd-rstr-reg = "vdd-dig"; + qcom,levels = ; + qcom,min-level = ; + }; + + qcom,vdd-gfx-rstr{ + qcom,vdd-rstr-reg = "vdd-gfx"; + qcom,levels = <5 6 6>; /* Nominal, Turbo, Turbo */ + qcom,min-level = <1>; /* No Request */ + }; + + msm_thermal_freq: qcom,vdd-apps-rstr{ + qcom,vdd-rstr-reg = "vdd-apps"; + qcom,levels = <1248000>; + qcom,freq-req; + }; + }; + wdog: qcom,wdt@17817000 { status = "disabled"; compatible = "qcom,msm-watchdog"; From 4c2873aec71996537843d04468d006eae8af0d68 Mon Sep 17 00:00:00 2001 From: Raviteja Tamatam Date: Mon, 19 Dec 2016 16:02:31 +0530 Subject: [PATCH 21/73] msm: mdss: Add mdss capabilities for msmfalcon Add MDSS version info along with other capabilities for msmfalcon. Change-Id: Ide652165711eec23644d36837f3847d896293709 Signed-off-by: Raviteja Tamatam --- drivers/video/fbdev/msm/mdss_debug.c | 4 ++- drivers/video/fbdev/msm/mdss_mdp.c | 42 ++++++++++++++++++++++++++++ drivers/video/fbdev/msm/mdss_mdp.h | 4 ++- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_debug.c b/drivers/video/fbdev/msm/mdss_debug.c index 6b455e0f1e6f..9ab88d4a7a52 100644 --- a/drivers/video/fbdev/msm/mdss_debug.c +++ b/drivers/video/fbdev/msm/mdss_debug.c @@ -1359,7 +1359,9 @@ static inline struct mdss_mdp_misr_map *mdss_misr_get_map(u32 block_id, (mdata->mdp_rev == MDSS_MDP_HW_REV_300) || (mdata->mdp_rev == - MDSS_MDP_HW_REV_301)) { + MDSS_MDP_HW_REV_301) || + (mdata->mdp_rev == + MDSS_MDP_HW_REV_320)) { ctrl_reg += 0x8; value_reg += 0x8; } diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index 58e0d9676736..ffb9cd5dc8cd 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -2052,6 +2052,48 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata) set_bit(MDSS_CAPS_AVR_SUPPORTED, mdata->mdss_caps_map); set_bit(MDSS_CAPS_SEC_DETACH_SMMU, mdata->mdss_caps_map); break; + case MDSS_MDP_HW_REV_320: + mdata->max_target_zorder = 7; /* excluding base layer */ + mdata->max_cursor_size = 512; + mdata->per_pipe_ib_factor.numer = 8; + mdata->per_pipe_ib_factor.denom = 5; + mdata->apply_post_scale_bytes = false; + mdata->hflip_buffer_reused = false; + mdata->min_prefill_lines = 25; + mdata->has_ubwc = true; + mdata->pixel_ram_size = 50 * 1024; + mdata->rects_per_sspp[MDSS_MDP_PIPE_TYPE_DMA] = 2; + + mem_protect_sd_ctrl_id = MEM_PROTECT_SD_CTRL_SWITCH; + set_bit(MDSS_QOS_PER_PIPE_IB, mdata->mdss_qos_map); + set_bit(MDSS_QOS_REMAPPER, mdata->mdss_qos_map); + set_bit(MDSS_QOS_TS_PREFILL, mdata->mdss_qos_map); + set_bit(MDSS_QOS_OVERHEAD_FACTOR, mdata->mdss_qos_map); + set_bit(MDSS_QOS_CDP, mdata->mdss_qos_map); /* cdp supported */ + mdata->enable_cdp = false; /* disable cdp */ + set_bit(MDSS_QOS_OTLIM, mdata->mdss_qos_map); + set_bit(MDSS_QOS_PER_PIPE_LUT, mdata->mdss_qos_map); + set_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map); + set_bit(MDSS_QOS_TS_PREFILL, mdata->mdss_qos_map); + set_bit(MDSS_QOS_IB_NOCR, mdata->mdss_qos_map); + set_bit(MDSS_QOS_WB2_WRITE_GATHER_EN, mdata->mdss_qos_map); + set_bit(MDSS_CAPS_YUV_CONFIG, mdata->mdss_caps_map); + set_bit(MDSS_CAPS_SCM_RESTORE_NOT_REQUIRED, + mdata->mdss_caps_map); + set_bit(MDSS_CAPS_3D_MUX_UNDERRUN_RECOVERY_SUPPORTED, + mdata->mdss_caps_map); + set_bit(MDSS_CAPS_QSEED3, mdata->mdss_caps_map); + set_bit(MDSS_CAPS_MDP_VOTE_CLK_NOT_SUPPORTED, + mdata->mdss_caps_map); + mdss_mdp_init_default_prefill_factors(mdata); + mdss_set_quirk(mdata, MDSS_QUIRK_DSC_RIGHT_ONLY_PU); + mdss_set_quirk(mdata, MDSS_QUIRK_DSC_2SLICE_PU_THRPUT); + mdss_set_quirk(mdata, MDSS_QUIRK_MMSS_GDSC_COLLAPSE); + mdss_set_quirk(mdata, MDSS_QUIRK_MDP_CLK_SET_RATE); + mdata->has_wb_ubwc = true; + set_bit(MDSS_CAPS_10_BIT_SUPPORTED, mdata->mdss_caps_map); + set_bit(MDSS_CAPS_SEC_DETACH_SMMU, mdata->mdss_caps_map); + break; default: mdata->max_target_zorder = 4; /* excluding base layer */ mdata->max_cursor_size = 64; diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 20aeabfdf9a4..ab2a7184aa45 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -1285,7 +1285,9 @@ static inline int mdss_mdp_panic_signal_support_mode( IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, MDSS_MDP_HW_REV_116) || IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, - MDSS_MDP_HW_REV_300)) + MDSS_MDP_HW_REV_300) || + IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, + MDSS_MDP_HW_REV_320)) signal_mode = MDSS_MDP_PANIC_PER_PIPE_CFG; return signal_mode; From cf0c68c29a1eba1642921a6cca3a6e819611ee3c Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Thu, 15 Dec 2016 15:38:23 +0530 Subject: [PATCH 22/73] ARM: dts: msm: Configure lmh hardware for msmtriton Configure the limits hardware with the interrupt to listen for. Limits hardware driver will interact with the trustzone to get throttling information from the hardware. Change-Id: I780f9187256596d6f5d93b3847dc98a3c410a51e Signed-off-by: Manaf Meethalavalappu Pallikunhi --- arch/arm/boot/dts/qcom/msmtriton.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msmtriton.dtsi b/arch/arm/boot/dts/qcom/msmtriton.dtsi index 958536fc05a4..f115539a7a61 100644 --- a/arch/arm/boot/dts/qcom/msmtriton.dtsi +++ b/arch/arm/boot/dts/qcom/msmtriton.dtsi @@ -621,6 +621,11 @@ }; }; + qcom,lmh { + compatible = "qcom,lmh_v1"; + interrupts = ; + }; + wdog: qcom,wdt@17817000 { status = "disabled"; compatible = "qcom,msm-watchdog"; From f24aac1b253f413ea6675a4145bbab467d003e37 Mon Sep 17 00:00:00 2001 From: Ram Chandrasekar Date: Wed, 14 Dec 2016 16:28:31 -0700 Subject: [PATCH 23/73] msm: thermal: Update error handling of device offline When device enters suspend, the suspend framework disables CPU hotplug functionality. During the suspend, any attempt from KTM to hotplug CPU will return error and in this case, KTM wont clear the cpus_offlined mask. In this case, the device framework assumes the core is still online. Next time the device resumes from suspend the core online attempt will be nacked by KTM. Thus the core will be offlined and subsequent attempts to bring the core online using device framework will fail. Update KTM error handling to remove the CPUs from the cpus_offlined mask, when device offline APIs return error. Thus KTM wont block suspend framework from bringing the core online. Also, update KTM not to evaluate new request to offline or online a core when the device is in suspend entry or exit. The re-evaluation will be triggered when the device exits suspend. Change-Id: I334fd782a2c5d604cafb94f44832d9c700891ba2 Signed-off-by: Ram Chandrasekar --- drivers/thermal/msm_thermal.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c index 7158fb1239df..f685892edd39 100644 --- a/drivers/thermal/msm_thermal.c +++ b/drivers/thermal/msm_thermal.c @@ -2931,7 +2931,7 @@ static void __ref do_core_control(int temp) cpu_dev = get_cpu_device(i); trace_thermal_pre_core_offline(i); ret = device_offline(cpu_dev); - if (ret) + if (ret < 0) pr_err("Error %d offline core %d\n", ret, i); trace_thermal_post_core_offline(i, @@ -3004,7 +3004,8 @@ static int __ref update_offline_cores(int val) cpu_dev = get_cpu_device(cpu); trace_thermal_pre_core_offline(cpu); ret = device_offline(cpu_dev); - if (ret) { + if (ret < 0) { + cpus_offlined &= ~BIT(cpu); pr_err_ratelimited( "Unable to offline CPU%d. err:%d\n", cpu, ret); @@ -3074,6 +3075,14 @@ static __ref int do_hotplug(void *data) &hotplug_notify_complete) != 0) ; reinit_completion(&hotplug_notify_complete); + + /* + * Suspend framework will have disabled the + * hotplug functionality. So wait till the suspend exits + * and then re-evaluate. + */ + if (in_suspend) + continue; mask = 0; mutex_lock(&core_control_mutex); From c4f8934a71801956eecf7768bbd55709356260ef Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Wed, 21 Dec 2016 10:38:52 -0800 Subject: [PATCH 24/73] icnss: Add EXEC permission when assigning the MSA0 back to host When MSA0 memory is re-assigned back to host, it needs to get RWX permissions so that it can be used for data as well as instructions. CRs-Fixed: 1104183 Change-Id: I58e19def0042022046e730dd97008a9e1c25b6d6 Signed-off-by: Yuanyuan Liu --- drivers/soc/qcom/icnss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 49510bfd6b24..c3792d5a72ac 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -781,7 +781,7 @@ static int icnss_unmap_msa_permissions(struct icnss_priv *priv, u32 index) u32 size; u32 dest_vmids[1] = {VMID_HLOS}; int source_vmlist[3] = {VMID_MSS_MSA, VMID_WLAN, 0}; - int dest_perms[1] = {PERM_READ|PERM_WRITE}; + int dest_perms[1] = {PERM_READ|PERM_WRITE|PERM_EXEC}; int source_nelems = 0; int dest_nelems = sizeof(dest_vmids)/sizeof(u32); From f931841b3f043000a1e7a221cbeaba792e740673 Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Tue, 22 Nov 2016 13:52:35 -0800 Subject: [PATCH 25/73] defconfig: msm: disable CRYPTO_DEC_QCE device on msm8998 CRYPTO_DEV_QCE device only provides a subset of crypto algorithms, and it also has conflict with HW crypto device CRYPTO_DEV_QCRYPTO, so disable it. Change-Id: I406a41ac961757d31209ae0a0a4b4d9cc4d31a1e Signed-off-by: Zhen Kong --- arch/arm64/configs/msmcortex-perf_defconfig | 1 - arch/arm64/configs/msmcortex_defconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig index 5d76e41d4fed..caf35789e2d9 100644 --- a/arch/arm64/configs/msmcortex-perf_defconfig +++ b/arch/arm64/configs/msmcortex-perf_defconfig @@ -600,7 +600,6 @@ CONFIG_CRYPTO_DEV_QCRYPTO=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y CONFIG_CRYPTO_DEV_QCEDEV=y CONFIG_CRYPTO_DEV_OTA_CRYPTO=y -CONFIG_CRYPTO_DEV_QCE=y CONFIG_CRYPTO_DEV_QCOM_ICE=y CONFIG_ARM64_CRYPTO=y CONFIG_CRYPTO_SHA1_ARM64_CE=y diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index 367822dd0a94..0e6d2c59a3e4 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -666,7 +666,6 @@ CONFIG_CRYPTO_DEV_QCRYPTO=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y CONFIG_CRYPTO_DEV_QCEDEV=y CONFIG_CRYPTO_DEV_OTA_CRYPTO=y -CONFIG_CRYPTO_DEV_QCE=y CONFIG_CRYPTO_DEV_QCOM_ICE=y CONFIG_ARM64_CRYPTO=y CONFIG_CRYPTO_SHA1_ARM64_CE=y From 654eb19d416a9a94b5e1e8e11dbbf80dddea6577 Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Tue, 29 Nov 2016 16:01:05 -0800 Subject: [PATCH 26/73] msm: crypto: fix AEAD issues for HW crypto driver on msm-4.4 Make change to fix AEAD operation issues due to incorrect usage of new aead interface introduced into kernel msm-4.4. Change-Id: I472449c52bff40d48f7d65b05e145cc47cba9357 Signed-off-by: Zhen Kong --- drivers/crypto/msm/qce50.c | 20 ++++++++++---- drivers/crypto/msm/qcrypto.c | 53 ++++++++++++++++++++++++------------ 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c index 61f99370863d..c810021dba9c 100644 --- a/drivers/crypto/msm/qce50.c +++ b/drivers/crypto/msm/qce50.c @@ -2476,8 +2476,11 @@ static int _qce_sps_add_sg_data_off(struct qce_device *pce_dev, res_within_sg = sg_dma_len(sg_src); while (off > 0) { - if (!sg_src) + if (!sg_src) { + pr_err("broken sg list off %d nbytes %d\n", + off, nbytes); return -ENOENT; + } len = sg_dma_len(sg_src); if (off < len) { res_within_sg = len - off; @@ -2485,7 +2488,8 @@ static int _qce_sps_add_sg_data_off(struct qce_device *pce_dev, } off -= len; sg_src = sg_next(sg_src); - res_within_sg = sg_dma_len(sg_src); + if (sg_src) + res_within_sg = sg_dma_len(sg_src); } while (nbytes > 0 && sg_src) { len = min(nbytes, res_within_sg); @@ -2516,9 +2520,15 @@ static int _qce_sps_add_sg_data_off(struct qce_device *pce_dev, addr += data_cnt; len -= data_cnt; } - sg_src = sg_next(sg_src); - off = 0; - res_within_sg = sg_dma_len(sg_src); + if (nbytes) { + sg_src = sg_next(sg_src); + if (!sg_src) { + pr_err("more data bytes %d\n", nbytes); + return -ENOMEM; + } + res_within_sg = sg_dma_len(sg_src); + off = 0; + } } return 0; } diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c index faeff0b55202..a898dbcbd0ca 100644 --- a/drivers/crypto/msm/qcrypto.c +++ b/drivers/crypto/msm/qcrypto.c @@ -821,19 +821,16 @@ static struct qcrypto_alg *_qcrypto_aead_alg_alloc(struct crypto_priv *cp, return q_alg; }; -static int _qcrypto_cipher_cra_init(struct crypto_tfm *tfm) +static int _qcrypto_cipher_ctx_init(struct qcrypto_cipher_ctx *ctx, + struct qcrypto_alg *q_alg) { - struct crypto_alg *alg = tfm->__crt_alg; - struct qcrypto_alg *q_alg; - struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm); - - - q_alg = container_of(alg, struct qcrypto_alg, cipher_alg); + if (!ctx || !q_alg) { + pr_err("ctx or q_alg is NULL\n"); + return -EINVAL; + } ctx->flags = 0; - /* update context with ptr to cp */ ctx->cp = q_alg->cp; - /* random first IV */ get_random_bytes(ctx->iv, QCRYPTO_MAX_IV_LENGTH); if (_qcrypto_init_assign) { @@ -845,6 +842,16 @@ static int _qcrypto_cipher_cra_init(struct crypto_tfm *tfm) INIT_LIST_HEAD(&ctx->rsp_queue); ctx->auth_alg = QCE_HASH_LAST; return 0; +} + +static int _qcrypto_cipher_cra_init(struct crypto_tfm *tfm) +{ + struct crypto_alg *alg = tfm->__crt_alg; + struct qcrypto_alg *q_alg; + struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm); + + q_alg = container_of(alg, struct qcrypto_alg, cipher_alg); + return _qcrypto_cipher_ctx_init(ctx, q_alg); }; static int _qcrypto_ahash_cra_init(struct crypto_tfm *tfm) @@ -941,13 +948,22 @@ static int _qcrypto_cra_aes_ablkcipher_init(struct crypto_tfm *tfm) return _qcrypto_cra_ablkcipher_init(tfm); }; +static int _qcrypto_aead_cra_init(struct crypto_aead *tfm) +{ + struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); + struct aead_alg *aeadalg = crypto_aead_alg(tfm); + struct qcrypto_alg *q_alg = container_of(aeadalg, struct qcrypto_alg, + aead_alg); + return _qcrypto_cipher_ctx_init(ctx, q_alg); +}; + static int _qcrypto_cra_aead_sha1_init(struct crypto_aead *tfm) { int rc; struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); ctx->auth_alg = QCE_HASH_SHA1_HMAC; return rc; } @@ -958,7 +974,7 @@ static int _qcrypto_cra_aead_sha256_init(struct crypto_aead *tfm) struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); ctx->auth_alg = QCE_HASH_SHA256_HMAC; return rc; } @@ -969,7 +985,7 @@ static int _qcrypto_cra_aead_ccm_init(struct crypto_aead *tfm) struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); ctx->auth_alg = QCE_HASH_AES_CMAC; return rc; } @@ -980,7 +996,7 @@ static int _qcrypto_cra_aead_rfc4309_ccm_init(struct crypto_aead *tfm) struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); ctx->auth_alg = QCE_HASH_AES_CMAC; return rc; } @@ -992,7 +1008,7 @@ static int _qcrypto_cra_aead_aes_sha1_init(struct crypto_aead *tfm) struct crypto_priv *cp = &qcrypto_dev; crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); if (rc) return rc; ctx->cipher_aes192_fb = NULL; @@ -1023,7 +1039,7 @@ static int _qcrypto_cra_aead_aes_sha256_init(struct crypto_aead *tfm) struct crypto_priv *cp = &qcrypto_dev; crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); if (rc) return rc; ctx->cipher_aes192_fb = NULL; @@ -1828,7 +1844,7 @@ static void _qce_aead_complete(void *cookie, unsigned char *icv, if (rctx->dir == QCE_ENCRYPT) { /* copy the icv to dst */ scatterwalk_map_and_copy(icv, areq->dst, - areq->cryptlen, + areq->cryptlen + areq->assoclen, ctx->authsize, 1); } else { @@ -1836,8 +1852,9 @@ static void _qce_aead_complete(void *cookie, unsigned char *icv, /* compare icv from src */ scatterwalk_map_and_copy(tmp, - areq->src, areq->cryptlen - - ctx->authsize, ctx->authsize, 0); + areq->src, areq->assoclen + + areq->cryptlen - ctx->authsize, + ctx->authsize, 0); ret = memcmp(icv, tmp, ctx->authsize); if (ret != 0) ret = -EBADMSG; From c76f7c2f3f63d404875de52fda4cd7df1511735f Mon Sep 17 00:00:00 2001 From: Tatenda Chipeperekwa Date: Mon, 21 Nov 2016 13:06:54 -0800 Subject: [PATCH 27/73] msm: mdss: dp: add support for PHY compliance tests Add support for PHY compliance tests by parsing requests from the reference sink and generating the requested PHY test patterns from DP PHY. CRs-Fixed: 1076516 Change-Id: I290ec786bbe5c45873265ea74290eefcd3d16cb1 Signed-off-by: Tatenda Chipeperekwa --- drivers/video/fbdev/msm/mdss_dp.c | 63 ++++++++++++- drivers/video/fbdev/msm/mdss_dp.h | 55 ++++++++++- drivers/video/fbdev/msm/mdss_dp_aux.c | 126 +++++++++++++++++++++---- drivers/video/fbdev/msm/mdss_dp_util.c | 84 +++++++++++++++++ drivers/video/fbdev/msm/mdss_dp_util.h | 6 ++ 5 files changed, 314 insertions(+), 20 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c index da3c8ca23fb6..394d31941c8a 100644 --- a/drivers/video/fbdev/msm/mdss_dp.c +++ b/drivers/video/fbdev/msm/mdss_dp.c @@ -1351,9 +1351,16 @@ static inline bool mdss_dp_is_link_training_requested( return (dp->test_data.test_requested == TEST_LINK_TRAINING); } +static inline bool mdss_dp_is_phy_test_pattern_requested( + struct mdss_dp_drv_pdata *dp) +{ + return (dp->test_data.test_requested == PHY_TEST_PATTERN); +} + static inline bool mdss_dp_soft_hpd_reset(struct mdss_dp_drv_pdata *dp) { - return mdss_dp_is_link_training_requested(dp) && + return (mdss_dp_is_link_training_requested(dp) || + mdss_dp_is_phy_test_pattern_requested(dp)) && dp->alt_mode.dp_status.hpd_irq; } @@ -2500,6 +2507,57 @@ static int mdss_dp_process_link_training_request(struct mdss_dp_drv_pdata *dp) return 0; } +/** + * mdss_dp_process_phy_test_pattern_request() - process new phy test requests + * @dp: Display Port Driver data + * + * This function will handle new phy test pattern requests that are initiated + * by the sink. The function will return 0 if a phy test pattern has been + * processed, otherwise it will return -EINVAL. + */ +static int mdss_dp_process_phy_test_pattern_request( + struct mdss_dp_drv_pdata *dp) +{ + u32 test_link_rate = 0, test_lane_count = 0; + + if (!mdss_dp_is_phy_test_pattern_requested(dp)) + return -EINVAL; + + mdss_dp_send_test_response(dp); + + test_link_rate = dp->test_data.test_link_rate; + test_lane_count = dp->test_data.test_lane_count; + + pr_info("%s link rate = 0x%x, lane count = 0x%x\n", + mdss_dp_get_test_name(TEST_LINK_TRAINING), + test_link_rate, test_lane_count); + + /** + * Retrain the mainlink if there is a change in link rate or lane + * count. + */ + if (mdss_dp_aux_is_link_rate_valid(test_link_rate) && + mdss_dp_aux_is_lane_count_valid(test_lane_count) && + ((dp->dpcd.max_lane_count != test_lane_count) || + (dp->link_rate != test_link_rate))) { + + pr_info("updated link rate or lane count, retraining.\n"); + + dp->dpcd.max_lane_count = dp->test_data.test_lane_count; + dp->link_rate = dp->test_data.test_link_rate; + + mdss_dp_link_retraining(dp); + } + + mdss_dp_config_ctrl(dp); + + mdss_dp_aux_update_voltage_and_pre_emphasis_lvl(dp); + + mdss_dp_phy_send_test_pattern(dp); + + return 0; +} + /** * mdss_dp_process_downstream_port_status_change() - process port status changes * @dp: Display Port Driver data @@ -2548,6 +2606,9 @@ static int mdss_dp_process_hpd_irq_high(struct mdss_dp_drv_pdata *dp) if (!ret) goto exit; + ret = mdss_dp_process_phy_test_pattern_request(dp); + if (!ret) + goto exit; pr_debug("done\n"); exit: mdss_dp_reset_test_data(dp); diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h index c4494aa9c629..399ca61e0f46 100644 --- a/drivers/video/fbdev/msm/mdss_dp.h +++ b/drivers/video/fbdev/msm/mdss_dp.h @@ -268,6 +268,7 @@ struct dpcd_test_request { u32 test_requested; u32 test_link_rate; u32 test_lane_count; + u32 phy_test_pattern_sel; u32 response; }; @@ -509,6 +510,51 @@ enum dp_lane_count { DP_LANE_COUNT_4 = 4, }; +enum phy_test_pattern { + PHY_TEST_PATTERN_NONE, + PHY_TEST_PATTERN_D10_2_NO_SCRAMBLING, + PHY_TEST_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT, + PHY_TEST_PATTERN_PRBS7, + PHY_TEST_PATTERN_80_BIT_CUSTOM_PATTERN, + PHY_TEST_PATTERN_HBR2_CTS_EYE_PATTERN, +}; + +static inline char *mdss_dp_get_phy_test_pattern(u32 phy_test_pattern_sel) +{ + switch (phy_test_pattern_sel) { + case PHY_TEST_PATTERN_NONE: + return DP_ENUM_STR(PHY_TEST_PATTERN_NONE); + case PHY_TEST_PATTERN_D10_2_NO_SCRAMBLING: + return DP_ENUM_STR(PHY_TEST_PATTERN_D10_2_NO_SCRAMBLING); + case PHY_TEST_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT: + return DP_ENUM_STR(PHY_TEST_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT); + case PHY_TEST_PATTERN_PRBS7: + return DP_ENUM_STR(PHY_TEST_PATTERN_PRBS7); + case PHY_TEST_PATTERN_80_BIT_CUSTOM_PATTERN: + return DP_ENUM_STR(PHY_TEST_PATTERN_80_BIT_CUSTOM_PATTERN); + case PHY_TEST_PATTERN_HBR2_CTS_EYE_PATTERN: + return DP_ENUM_STR(PHY_TEST_PATTERN_HBR2_CTS_EYE_PATTERN); + default: + return "unknown"; + } +} + +static inline bool mdss_dp_is_phy_test_pattern_supported( + u32 phy_test_pattern_sel) +{ + switch (phy_test_pattern_sel) { + case PHY_TEST_PATTERN_NONE: + case PHY_TEST_PATTERN_D10_2_NO_SCRAMBLING: + case PHY_TEST_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT: + case PHY_TEST_PATTERN_PRBS7: + case PHY_TEST_PATTERN_80_BIT_CUSTOM_PATTERN: + case PHY_TEST_PATTERN_HBR2_CTS_EYE_PATTERN: + return true; + default: + return false; + } +} + enum dp_aux_error { EDP_AUX_ERR_NONE = 0, EDP_AUX_ERR_ADDR = -1, @@ -561,7 +607,7 @@ static inline char *mdss_dp_get_test_response(u32 test_response) enum test_type { UNKNOWN_TEST = 0, TEST_LINK_TRAINING = BIT(0), - TEST_PATTERN = BIT(1), + PHY_TEST_PATTERN = BIT(3), TEST_EDID_READ = BIT(2), }; @@ -569,7 +615,7 @@ static inline char *mdss_dp_get_test_name(u32 test_requested) { switch (test_requested) { case TEST_LINK_TRAINING: return DP_ENUM_STR(TEST_LINK_TRAINING); - case TEST_PATTERN: return DP_ENUM_STR(TEST_PATTERN); + case PHY_TEST_PATTERN: return DP_ENUM_STR(PHY_TEST_PATTERN); case TEST_EDID_READ: return DP_ENUM_STR(TEST_EDID_READ); default: return "unknown"; } @@ -640,5 +686,10 @@ void *mdss_dp_get_hdcp_data(struct device *dev); int mdss_dp_hdcp2p2_init(struct mdss_dp_drv_pdata *dp_drv); bool mdss_dp_aux_clock_recovery_done(struct mdss_dp_drv_pdata *ep); bool mdss_dp_aux_channel_eq_done(struct mdss_dp_drv_pdata *ep); +bool mdss_dp_aux_is_link_rate_valid(u32 link_rate); +bool mdss_dp_aux_is_lane_count_valid(u32 lane_count); +int mdss_dp_aux_link_status_read(struct mdss_dp_drv_pdata *ep, int len); +void mdss_dp_aux_update_voltage_and_pre_emphasis_lvl( + struct mdss_dp_drv_pdata *dp); #endif /* MDSS_DP_H */ diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c index b216506fe2a9..82588f681585 100644 --- a/drivers/video/fbdev/msm/mdss_dp_aux.c +++ b/drivers/video/fbdev/msm/mdss_dp_aux.c @@ -960,7 +960,7 @@ static void dp_sink_capability_read(struct mdss_dp_drv_pdata *ep, dp_sink_parse_sink_count(ep); } -static int dp_link_status_read(struct mdss_dp_drv_pdata *ep, int len) +int mdss_dp_aux_link_status_read(struct mdss_dp_drv_pdata *ep, int len) { char *bp; char data; @@ -1031,12 +1031,12 @@ void mdss_dp_aux_send_test_response(struct mdss_dp_drv_pdata *dp) } /** - * dp_is_link_rate_valid() - validates the link rate + * mdss_dp_aux_is_link_rate_valid() - validates the link rate * @lane_rate: link rate requested by the sink * * Returns true if the requested link rate is supported. */ -static bool dp_is_link_rate_valid(u32 link_rate) +bool mdss_dp_aux_is_link_rate_valid(u32 link_rate) { return (link_rate == DP_LINK_RATE_162) || (link_rate == DP_LINK_RATE_270) || @@ -1044,12 +1044,12 @@ static bool dp_is_link_rate_valid(u32 link_rate) } /** - * dp_is_lane_count_valid() - validates the lane count + * mdss_dp_aux_is_lane_count_valid() - validates the lane count * @lane_count: lane count requested by the sink * * Returns true if the requested lane count is supported. */ -static bool dp_is_lane_count_valid(u32 lane_count) +bool mdss_dp_aux_is_lane_count_valid(u32 lane_count) { return (lane_count == DP_LANE_COUNT_1) || (lane_count == DP_LANE_COUNT_2) || @@ -1086,7 +1086,7 @@ static int dp_parse_link_training_params(struct mdss_dp_drv_pdata *ep) bp = rp->data; data = *bp++; - if (!dp_is_link_rate_valid(data)) { + if (!mdss_dp_aux_is_link_rate_valid(data)) { pr_err("invalid link rate = 0x%x\n", data); ret = -EINVAL; goto exit; @@ -1108,7 +1108,7 @@ static int dp_parse_link_training_params(struct mdss_dp_drv_pdata *ep) data = *bp++; data &= 0x1F; - if (!dp_is_lane_count_valid(data)) { + if (!mdss_dp_aux_is_lane_count_valid(data)) { pr_err("invalid lane count = 0x%x\n", data); ret = -EINVAL; goto exit; @@ -1156,6 +1156,53 @@ static void dp_sink_parse_sink_count(struct mdss_dp_drv_pdata *ep) ep->sink_count.count, ep->sink_count.cp_ready); } +/** + * dp_parse_phy_test_params() - parses the phy test parameters + * @ep: Display Port Driver data + * + * Parses the DPCD (Byte 0x248) for the DP PHY test pattern that is being + * requested. + */ +static int dp_parse_phy_test_params(struct mdss_dp_drv_pdata *ep) +{ + char *bp; + char data; + struct edp_buf *rp; + int rlen; + int const param_len = 0x1; + int const phy_test_pattern_addr = 0x248; + int const dpcd_version_1_2 = 0x12; + int ret = 0; + + rlen = dp_aux_read_buf(ep, phy_test_pattern_addr, param_len, 0); + if (rlen < param_len) { + pr_err("failed to read phy test pattern\n"); + ret = -EINVAL; + goto end; + } + + rp = &ep->rxp; + bp = rp->data; + data = *bp++; + + if (ep->dpcd.major == dpcd_version_1_2) + data = data & 0x7; + else + data = data & 0x3; + + ep->test_data.phy_test_pattern_sel = data; + + pr_debug("phy_test_pattern_sel = %s\n", + mdss_dp_get_phy_test_pattern(data)); + + if (!mdss_dp_is_phy_test_pattern_supported(data)) + ret = -EINVAL; + +end: + return ret; +} + + /** * dp_is_test_supported() - checks if test requested by sink is supported * @test_requested: test requested by the sink @@ -1165,7 +1212,8 @@ static void dp_sink_parse_sink_count(struct mdss_dp_drv_pdata *ep) static bool dp_is_test_supported(u32 test_requested) { return (test_requested == TEST_LINK_TRAINING) || - (test_requested == TEST_EDID_READ); + (test_requested == TEST_EDID_READ) || + (test_requested == PHY_TEST_PATTERN); } /** @@ -1229,8 +1277,19 @@ static void dp_sink_parse_test_request(struct mdss_dp_drv_pdata *ep) pr_debug("%s requested\n", mdss_dp_get_test_name(data)); ep->test_data.test_requested = data; - if (ep->test_data.test_requested == TEST_LINK_TRAINING) + switch (ep->test_data.test_requested) { + case PHY_TEST_PATTERN: + ret = dp_parse_phy_test_params(ep); + if (ret) + break; + case TEST_LINK_TRAINING: ret = dp_parse_link_training_params(ep); + break; + default: + pr_debug("test 0x%x not supported\n", + ep->test_data.test_requested); + return; + } /** * Send a TEST_ACK if all test parameters are valid, otherwise send @@ -1453,7 +1512,8 @@ char vm_voltage_swing[4][4] = { {0x1E, 0xFF, 0xFF, 0xFF} /* sw1, 1.2 v, optional */ }; -static void dp_voltage_pre_emphasise_set(struct mdss_dp_drv_pdata *dp) +static void dp_aux_set_voltage_and_pre_emphasis_lvl( + struct mdss_dp_drv_pdata *dp) { u32 value0 = 0; u32 value1 = 0; @@ -1488,6 +1548,38 @@ static void dp_voltage_pre_emphasise_set(struct mdss_dp_drv_pdata *dp) } +/** + * mdss_dp_aux_update_voltage_and_pre_emphasis_lvl() - updates DP PHY settings + * @ep: Display Port Driver data + * + * Updates the DP PHY with the requested voltage swing and pre-emphasis + * levels if they are different from the current settings. + */ +void mdss_dp_aux_update_voltage_and_pre_emphasis_lvl( + struct mdss_dp_drv_pdata *dp) +{ + int const num_bytes = 6; + struct dpcd_link_status *status = &dp->link_status; + + /* Read link status for updated voltage and pre-emphasis levels. */ + mdss_dp_aux_link_status_read(dp, num_bytes); + + pr_info("Current: v_level = %d, p_level = %d\n", + dp->v_level, dp->p_level); + pr_info("Requested: v_level = %d, p_level = %d\n", + status->req_voltage_swing[0], + status->req_pre_emphasis[0]); + + if ((status->req_voltage_swing[0] != dp->v_level) || + (status->req_pre_emphasis[0] != dp->p_level)) { + dp->v_level = status->req_voltage_swing[0]; + dp->p_level = status->req_pre_emphasis[0]; + + dp_aux_set_voltage_and_pre_emphasis_lvl(dp); + } + + pr_debug("end\n"); +} static int dp_start_link_train_1(struct mdss_dp_drv_pdata *ep) { int tries, old_v_level; @@ -1500,7 +1592,7 @@ static int dp_start_link_train_1(struct mdss_dp_drv_pdata *ep) dp_host_train_set(ep, 0x01); /* train_1 */ dp_cap_lane_rate_set(ep); dp_train_pattern_set_write(ep, 0x21); /* train_1 */ - dp_voltage_pre_emphasise_set(ep); + dp_aux_set_voltage_and_pre_emphasis_lvl(ep); tries = 0; old_v_level = ep->v_level; @@ -1508,7 +1600,7 @@ static int dp_start_link_train_1(struct mdss_dp_drv_pdata *ep) usleep_time = ep->dpcd.training_read_interval; usleep_range(usleep_time, usleep_time); - dp_link_status_read(ep, 6); + mdss_dp_aux_link_status_read(ep, 6); if (mdss_dp_aux_clock_recovery_done(ep)) { ret = 0; break; @@ -1531,7 +1623,7 @@ static int dp_start_link_train_1(struct mdss_dp_drv_pdata *ep) } dp_sink_train_set_adjust(ep); - dp_voltage_pre_emphasise_set(ep); + dp_aux_set_voltage_and_pre_emphasis_lvl(ep); } return ret; @@ -1555,13 +1647,13 @@ static int dp_start_link_train_2(struct mdss_dp_drv_pdata *ep) dp_train_pattern_set_write(ep, pattern | 0x20);/* train_2 */ do { - dp_voltage_pre_emphasise_set(ep); + dp_aux_set_voltage_and_pre_emphasis_lvl(ep); dp_host_train_set(ep, pattern); usleep_time = ep->dpcd.training_read_interval; usleep_range(usleep_time, usleep_time); - dp_link_status_read(ep, 6); + mdss_dp_aux_link_status_read(ep, 6); if (mdss_dp_aux_channel_eq_done(ep)) { ret = 0; @@ -1698,7 +1790,7 @@ void mdss_dp_aux_parse_sink_status_field(struct mdss_dp_drv_pdata *ep) { dp_sink_parse_sink_count(ep); dp_sink_parse_test_request(ep); - dp_link_status_read(ep, 6); + mdss_dp_aux_link_status_read(ep, 6); } int mdss_dp_dpcd_status_read(struct mdss_dp_drv_pdata *ep) @@ -1706,7 +1798,7 @@ int mdss_dp_dpcd_status_read(struct mdss_dp_drv_pdata *ep) struct dpcd_link_status *sp; int ret = 0; /* not sync */ - ret = dp_link_status_read(ep, 6); + ret = mdss_dp_aux_link_status_read(ep, 6); if (ret) { sp = &ep->link_status; diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c index b1bfe2c548ba..3b294a11f555 100644 --- a/drivers/video/fbdev/msm/mdss_dp_util.c +++ b/drivers/video/fbdev/msm/mdss_dp_util.c @@ -892,3 +892,87 @@ void mdss_dp_audio_enable(struct dss_io_data *ctrl_io, bool enable) writel_relaxed(audio_ctrl, ctrl_io->base + MMSS_DP_AUDIO_CFG); } + +/** + * mdss_dp_phy_send_test_pattern() - sends the requested PHY test pattern + * @ep: Display Port Driver data + * + * Updates the DP controller state and sends the requested PHY test pattern + * to the sink. + */ +void mdss_dp_phy_send_test_pattern(struct mdss_dp_drv_pdata *dp) +{ + struct dss_io_data *io = &dp->ctrl_io; + u32 phy_test_pattern_sel = dp->test_data.phy_test_pattern_sel; + u32 value = 0x0; + + if (!mdss_dp_is_phy_test_pattern_supported(phy_test_pattern_sel)) { + pr_err("test pattern 0x%x not supported\n", + phy_test_pattern_sel); + return; + } + + /* Disable mainlink */ + writel_relaxed(0x0, io->base + DP_MAINLINK_CTRL); + + /* Reset mainlink */ + mdss_dp_mainlink_reset(io); + + /* Enable mainlink */ + writel_relaxed(0x0, io->base + DP_MAINLINK_CTRL); + + /* Initialize DP state control */ + mdss_dp_state_ctrl(io, 0x00); + + pr_debug("phy_test_pattern_sel = %s\n", + mdss_dp_get_phy_test_pattern(phy_test_pattern_sel)); + + switch (phy_test_pattern_sel) { + case PHY_TEST_PATTERN_D10_2_NO_SCRAMBLING: + mdss_dp_state_ctrl(io, BIT(0)); + break; + case PHY_TEST_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT: + value = readl_relaxed(io->base + + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET); + value &= ~(1 << 16); + writel_relaxed(value, io->base + + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET); + value |= 0xFC; + writel_relaxed(value, io->base + + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET); + writel_relaxed(0x2, io->base + DP_MAINLINK_LEVELS); + mdss_dp_state_ctrl(io, BIT(4)); + break; + case PHY_TEST_PATTERN_PRBS7: + mdss_dp_state_ctrl(io, BIT(5)); + break; + case PHY_TEST_PATTERN_80_BIT_CUSTOM_PATTERN: + mdss_dp_state_ctrl(io, BIT(6)); + /* 00111110000011111000001111100000 */ + writel_relaxed(0x3E0F83E0, io->base + + DP_TEST_80BIT_CUSTOM_PATTERN_REG0); + /* 00001111100000111110000011111000 */ + writel_relaxed(0x0F83E0F8, io->base + + DP_TEST_80BIT_CUSTOM_PATTERN_REG1); + /* 1111100000111110 */ + writel_relaxed(0x0000F83E, io->base + + DP_TEST_80BIT_CUSTOM_PATTERN_REG2); + break; + case PHY_TEST_PATTERN_HBR2_CTS_EYE_PATTERN: + value = readl_relaxed(io->base + + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET); + value |= BIT(16); + writel_relaxed(value, io->base + + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET); + value |= 0xFC; + writel_relaxed(value, io->base + + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET); + writel_relaxed(0x2, io->base + DP_MAINLINK_LEVELS); + mdss_dp_state_ctrl(io, BIT(4)); + break; + default: + pr_debug("No valid test pattern requested: 0x%x\n", + phy_test_pattern_sel); + return; + } +} diff --git a/drivers/video/fbdev/msm/mdss_dp_util.h b/drivers/video/fbdev/msm/mdss_dp_util.h index 5e238d5be2b4..c046deef48a3 100644 --- a/drivers/video/fbdev/msm/mdss_dp_util.h +++ b/drivers/video/fbdev/msm/mdss_dp_util.h @@ -60,6 +60,11 @@ #define DP_MAINLINK_LEVELS (0x00000444) #define DP_TU (0x0000044C) +#define DP_HBR2_COMPLIANCE_SCRAMBLER_RESET (0x00000454) +#define DP_TEST_80BIT_CUSTOM_PATTERN_REG0 (0x000004C0) +#define DP_TEST_80BIT_CUSTOM_PATTERN_REG1 (0x000004C4) +#define DP_TEST_80BIT_CUSTOM_PATTERN_REG2 (0x000004C8) + #define MMSS_DP_AUDIO_TIMING_GEN (0x00000480) #define MMSS_DP_AUDIO_TIMING_RBR_32 (0x00000484) #define MMSS_DP_AUDIO_TIMING_HBR_32 (0x00000488) @@ -315,5 +320,6 @@ void mdss_dp_audio_set_sample_rate(struct dss_io_data *ctrl_io, void mdss_dp_set_safe_to_exit_level(struct dss_io_data *ctrl_io, uint32_t lane_cnt); int mdss_dp_aux_read_rx_status(struct mdss_dp_drv_pdata *dp, u8 *rx_status); +void mdss_dp_phy_send_test_pattern(struct mdss_dp_drv_pdata *dp); #endif /* __DP_UTIL_H__ */ From c23be78397bd1a6efa8ee1bdc5abd435e365c019 Mon Sep 17 00:00:00 2001 From: Aravind Venkateswaran Date: Thu, 15 Dec 2016 17:36:54 -0800 Subject: [PATCH 28/73] msm: mdss: dp: fix calculation of link rate If the calculated link rate based on sink's capabilities exceeds the maximum supported link rate, do not error out. Instead, cap the link rate at the maximum supported rate. This fixes instability issues seen when connecting to sinks at 4K resolution. Change-Id: I214bb19385f855af61da628fdf1cf7efc5dd08d6 Signed-off-by: Aravind Venkateswaran --- drivers/video/fbdev/msm/mdss_dp_aux.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c index 82588f681585..b8be110f04f0 100644 --- a/drivers/video/fbdev/msm/mdss_dp_aux.c +++ b/drivers/video/fbdev/msm/mdss_dp_aux.c @@ -537,8 +537,9 @@ char mdss_dp_gen_link_clk(struct mdss_panel_info *pinfo, char lane_cnt) else if (min_link_rate <= DP_LINK_RATE_540) calc_link_rate = DP_LINK_RATE_540; else { - pr_err("link_rate = %d is unsupported\n", min_link_rate); - calc_link_rate = 0; + /* Cap the link rate to the max supported rate */ + pr_debug("link_rate = %d is unsupported\n", min_link_rate); + calc_link_rate = DP_LINK_RATE_540; } return calc_link_rate; From 5f41a670d14345da8ba300ab6b8029bdd06344f2 Mon Sep 17 00:00:00 2001 From: Aravind Venkateswaran Date: Thu, 15 Dec 2016 17:41:04 -0800 Subject: [PATCH 29/73] msm: mdss: dp: fix handling of link training mutex Remove the additional unbalanced unlock being called for the link training mutex. This fixes random crashes seen while running Display Port connection/disconnection tests. Change-Id: I2fce80cec72e3bd8b1561fd46fa1a1520cddd294 Signed-off-by: Aravind Venkateswaran --- drivers/video/fbdev/msm/mdss_dp.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c index 394d31941c8a..7076b36bb6b6 100644 --- a/drivers/video/fbdev/msm/mdss_dp.c +++ b/drivers/video/fbdev/msm/mdss_dp.c @@ -1211,16 +1211,20 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv) ret = mdss_dp_get_lane_mapping(dp_drv, dp_drv->orientation, &ln_map); - if (ret) + if (ret) { + mutex_unlock(&dp_drv->train_mutex); goto exit; + } mdss_dp_phy_share_lane_config(&dp_drv->phy_io, dp_drv->orientation, dp_drv->dpcd.max_lane_count); ret = mdss_dp_enable_mainlink_clocks(dp_drv); - if (ret) + if (ret) { + mutex_unlock(&dp_drv->train_mutex); goto exit; + } mdss_dp_mainlink_reset(&dp_drv->ctrl_io); @@ -1238,7 +1242,6 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv) pr_debug("end\n"); exit: - mutex_unlock(&dp_drv->train_mutex); return ret; } From 7c2b101e73eef0d22b365adbd7b0e2219611605a Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Fri, 16 Dec 2016 16:55:44 -0800 Subject: [PATCH 30/73] usb: phy: qusb2: Switch to SE clk from diff clk upon suspend Upon out of XO shutdown due to remote wakeup, as soon as XO gets restored refclk is supplied to phy before even refgen current is stabilized. USB3 controller asserts suspend_n signal asynchronously for remote wake-up scenario solely based on utmi_linestate switching from J state(suspend) to K state(resume). As a result phy attempts to lock PLL since all prerequisites are met but, PLL lock attempt fails and phy gets stuck. Since GCC_RX1_USB2_CLKREF_EN which was supposed to control differential(CML) clock output to QUSB2 is a no-op, hence switch to SE clock by PHY CSR controlled mux upon suspend. This prevents refclk output to go directly to phy upon XO restore and prevents premature phy pll locking. Phy PLL actually gets locked when phy driver switches back from SE clk to diff clk. Change-Id: Ie5474c42ccdd88df4c101b2113ca8d924eddf037 Signed-off-by: Hemant Kumar --- drivers/usb/phy/phy-msm-qusb-v2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/phy/phy-msm-qusb-v2.c b/drivers/usb/phy/phy-msm-qusb-v2.c index 86908d2ce9d5..a47d16357898 100644 --- a/drivers/usb/phy/phy-msm-qusb-v2.c +++ b/drivers/usb/phy/phy-msm-qusb-v2.c @@ -600,7 +600,8 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend) readl_relaxed(qphy->base + QUSB2PHY_PLL_ANALOG_CONTROLS_TWO); - writel_relaxed(0x1b, + /* use CSR & switch to SE clk */ + writel_relaxed(0xb, qphy->base + QUSB2PHY_PLL_ANALOG_CONTROLS_TWO); /* enable clock bypass */ From 4569877e351900be3df0b34f4e7acb1d32e687fa Mon Sep 17 00:00:00 2001 From: Fenglin Wu Date: Tue, 22 Nov 2016 13:21:11 +0800 Subject: [PATCH 31/73] input: qpnp-power-on: Set ship mode in system_pwr_off Set ship mode in qpnp_pon_system_pwr_off() API if it has been requested previously. CRs-Fixed: 1092969 Change-Id: I6e315eec256f01c143ffc8b463279f2b30e64610 Signed-off-by: Fenglin Wu --- drivers/input/qpnp-power-on.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/input/qpnp-power-on.c b/drivers/input/qpnp-power-on.c index 760c92a47a36..967b23cae05c 100644 --- a/drivers/input/qpnp-power-on.c +++ b/drivers/input/qpnp-power-on.c @@ -31,6 +31,7 @@ #include #include #include +#include #define PMIC_VER_8941 0x01 #define PMIC_VERSION_REG 0x0105 @@ -220,6 +221,11 @@ struct qpnp_pon { bool store_hard_reset_reason; }; +static int pon_ship_mode_en; +module_param_named( + ship_mode_en, pon_ship_mode_en, int, S_IRUSR | S_IWUSR +); + static struct qpnp_pon *sys_reset_dev; static DEFINE_SPINLOCK(spon_list_slock); static LIST_HEAD(spon_dev_list); @@ -523,6 +529,8 @@ int qpnp_pon_system_pwr_off(enum pon_power_off_type type) int rc = 0; struct qpnp_pon *pon = sys_reset_dev; struct qpnp_pon *tmp; + struct power_supply *batt_psy; + union power_supply_propval val; unsigned long flags; if (!pon) @@ -557,6 +565,19 @@ int qpnp_pon_system_pwr_off(enum pon_power_off_type type) goto out; } } + /* Set ship mode here if it has been requested */ + if (!!pon_ship_mode_en) { + batt_psy = power_supply_get_by_name("battery"); + if (batt_psy) { + pr_debug("Set ship mode!\n"); + val.intval = 1; + rc = power_supply_set_property(batt_psy, + POWER_SUPPLY_PROP_SET_SHIP_MODE, &val); + if (rc) + dev_err(&pon->pdev->dev, + "Set ship-mode failed\n"); + } + } out: spin_unlock_irqrestore(&spon_list_slock, flags); return rc; From 79871232a8109132dfadf64bb7e13890fa342340 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Thu, 17 Nov 2016 11:20:23 +0530 Subject: [PATCH 32/73] clk: qcom: Support CPU clock for OSM for common clock framework Following list of changes have been made - Update the clock osm to register to common clock framework - Update clock ops as per common clock framework - cleanup unused function (clk_osm_setup_osm_was) - Fix tabs for macro definitions - Add clocks ids for power and perf clock for clients Change-Id: I389cc9e93a26a434be752cf74444d6c0985ff36d Signed-off-by: Taniya Das --- .../devicetree/bindings/arm/msm/qcom,osm.txt | 5 +- drivers/clk/qcom/Kconfig | 12 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/clk-cpu-osm.c | 1105 +++++++++-------- drivers/clk/qcom/common.h | 1 + include/dt-bindings/clock/qcom,cpu-osm.h | 23 + 6 files changed, 602 insertions(+), 545 deletions(-) create mode 100644 include/dt-bindings/clock/qcom,cpu-osm.h diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt index a8334e1cfde7..be8f27d87738 100644 --- a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt +++ b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt @@ -9,8 +9,9 @@ Properties: - compatible Usage: required Value type: - Definition: must be "qcom,cpu-clock-osm-msm8998-v1" or - "qcom,cpu-clock-osm-msm8998-v2". + Definition: must be "qcom,cpu-clock-osm-msm8998-v1", + "qcom,cpu-clock-osm-msm8998-v2" or + "qcom,clk-cpu-osm". - reg Usage: required diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 2148dad33e87..b5dd556b3f96 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -219,4 +219,16 @@ config QCOM_A53 Say Y if you want to support CPU frequency scaling on devices such as MSM8916. +config CLOCK_CPU_OSM + tristate "OSM CPU Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the osm clock controller. + Operating State Manager (OSM) is a hardware engine used by some + Qualcomm Technologies, Inc. (QTI) SoCs to manage frequency and + voltage scaling in hardware. OSM is capable of controlling + frequency and voltage requests for multiple clusters via the + existence of multiple OSM domains. + Say Y if you want to support osm clocks. + source "drivers/clk/qcom/mdss/Kconfig" diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 176dc3103cdb..a63065c97319 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -37,5 +37,6 @@ obj-$(CONFIG_KRAITCC) += krait-cc.o obj-$(CONFIG_QCOM_A53) += clk-a53.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o +obj-$(CONFIG_CLOCK_CPU_OSM) += clk-cpu-osm.o obj-y += mdss/ diff --git a/drivers/clk/qcom/clk-cpu-osm.c b/drivers/clk/qcom/clk-cpu-osm.c index f97cd1b03c81..ab6a1384ffbd 100644 --- a/drivers/clk/qcom/clk-cpu-osm.c +++ b/drivers/clk/qcom/clk-cpu-osm.c @@ -22,9 +22,7 @@ #include #include #include -#include -#include -#include +#include #include #include #include @@ -32,18 +30,20 @@ #include #include #include +#include #include #include - #include -#include -#include -#include +#include -#include -#include +#include "common.h" +#include "clk-regmap.h" +#include "clk-rcg.h" -#include "clock.h" +enum { + LMH_LITE_CLK_SRC, + P_XO, +}; enum clk_osm_bases { OSM_BASE, @@ -74,210 +74,192 @@ enum clk_osm_trace_packet_id { TRACE_PACKET3, }; -#define SEQ_REG(n) (0x300 + (n) * 4) -#define MEM_ACC_SEQ_REG_CFG_START(n) (SEQ_REG(12 + (n))) -#define MEM_ACC_SEQ_CONST(n) (n) -#define MEM_ACC_INSTR_COMP(n) (0x67 + ((n) * 0x40)) -#define MEM_ACC_SEQ_REG_VAL_START(n) (SEQ_REG(60 + (n))) -#define SEQ_REG1_MSMCOBALT_V2 0x1048 -#define VERSION_REG 0x0 -#define VERSION_1P1 0x00010100 +#define SEQ_REG(n) (0x300 + (n) * 4) +#define MEM_ACC_SEQ_REG_CFG_START(n) (SEQ_REG(12 + (n))) +#define MEM_ACC_SEQ_CONST(n) (n) +#define MEM_ACC_INSTR_COMP(n) (0x67 + ((n) * 0x40)) +#define MEM_ACC_SEQ_REG_VAL_START(n) (SEQ_REG(60 + (n))) +#define SEQ_REG1_OFFSET 0x1048 +#define VERSION_REG 0x0 -#define OSM_TABLE_SIZE 40 -#define MAX_CLUSTER_CNT 2 -#define MAX_CONFIG 4 -#define LLM_SW_OVERRIDE_CNT 3 +#define OSM_TABLE_SIZE 40 +#define MAX_CLUSTER_CNT 2 +#define LLM_SW_OVERRIDE_CNT 3 +#define CORE_COUNT_VAL(val) ((val & GENMASK(18, 16)) >> 16) +#define SINGLE_CORE 1 +#define MAX_CORE_COUNT 4 -#define ENABLE_REG 0x1004 -#define INDEX_REG 0x1150 -#define FREQ_REG 0x1154 -#define VOLT_REG 0x1158 -#define OVERRIDE_REG 0x115C -#define SPARE_REG 0x1164 +#define ENABLE_REG 0x1004 +#define INDEX_REG 0x1150 +#define FREQ_REG 0x1154 +#define VOLT_REG 0x1158 +#define OVERRIDE_REG 0x115C +#define SPARE_REG 0x1164 -#define OSM_CYCLE_COUNTER_CTRL_REG 0x1F00 -#define OSM_CYCLE_COUNTER_STATUS_REG 0x1F04 -#define DCVS_PERF_STATE_DESIRED_REG 0x1F10 -#define DCVS_PERF_STATE_DEVIATION_INTR_STAT 0x1F14 -#define DCVS_PERF_STATE_DEVIATION_INTR_EN 0x1F18 -#define DCVS_PERF_STATE_DEVIATION_INTR_CLEAR 0x1F1C -#define DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_STAT 0x1F20 -#define DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_EN 0x1F24 -#define DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_CLEAR 0x1F28 -#define DCVS_PERF_STATE_MET_INTR_STAT 0x1F2C -#define DCVS_PERF_STATE_MET_INTR_EN 0x1F30 -#define DCVS_PERF_STATE_MET_INTR_CLR 0x1F34 -#define OSM_CORE_TABLE_SIZE 8192 -#define OSM_REG_SIZE 32 +#define OSM_CYCLE_COUNTER_CTRL_REG 0x1F00 +#define OSM_CYCLE_COUNTER_STATUS_REG 0x1F04 +#define DCVS_PERF_STATE_DESIRED_REG 0x1F10 +#define DCVS_PERF_STATE_DEVIATION_INTR_STAT 0x1F14 +#define DCVS_PERF_STATE_DEVIATION_INTR_EN 0x1F18 +#define DCVS_PERF_STATE_DEVIATION_INTR_CLEAR 0x1F1C +#define DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_STAT 0x1F20 +#define DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_EN 0x1F24 +#define DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_CLEAR 0x1F28 +#define DCVS_PERF_STATE_MET_INTR_STAT 0x1F2C +#define DCVS_PERF_STATE_MET_INTR_EN 0x1F30 +#define DCVS_PERF_STATE_MET_INTR_CLR 0x1F34 +#define OSM_CORE_TABLE_SIZE 8192 +#define OSM_REG_SIZE 32 -#define WDOG_DOMAIN_PSTATE_STATUS 0x1c00 -#define WDOG_PROGRAM_COUNTER 0x1c74 +#define WDOG_DOMAIN_PSTATE_STATUS 0x1c00 +#define WDOG_PROGRAM_COUNTER 0x1c74 -#define OSM_CYCLE_COUNTER_USE_XO_EDGE_EN BIT(8) -#define PLL_MODE 0x0 -#define PLL_L_VAL 0x4 -#define PLL_USER_CTRL 0xC -#define PLL_CONFIG_CTL_LO 0x10 -#define PLL_TEST_CTL_HI 0x1C -#define PLL_STATUS 0x2C -#define PLL_LOCK_DET_MASK BIT(16) -#define PLL_WAIT_LOCK_TIME_US 10 -#define PLL_WAIT_LOCK_TIME_NS (PLL_WAIT_LOCK_TIME_US * 1000) -#define PLL_MIN_LVAL 43 +#define OSM_CYCLE_COUNTER_USE_XO_EDGE_EN BIT(8) -#define CC_ZERO_BEHAV_CTRL 0x100C -#define SPM_CC_DCVS_DISABLE 0x1020 -#define SPM_CC_CTRL 0x1028 -#define SPM_CC_HYSTERESIS 0x101C -#define SPM_CORE_RET_MAPPING 0x1024 -#define CFG_DELAY_VAL_3 0x12C +#define PLL_MODE 0x0 +#define PLL_L_VAL 0x4 +#define PLL_USER_CTRL 0xC +#define PLL_CONFIG_CTL_LO 0x10 +#define PLL_TEST_CTL_HI 0x1C +#define PLL_STATUS 0x2C +#define PLL_LOCK_DET_MASK BIT(16) +#define PLL_WAIT_LOCK_TIME_US 10 +#define PLL_WAIT_LOCK_TIME_NS (PLL_WAIT_LOCK_TIME_US * 1000) +#define PLL_MIN_LVAL 43 +#define L_VAL(freq_data) ((freq_data) & GENMASK(7, 0)) -#define LLM_FREQ_VOTE_HYSTERESIS 0x102C -#define LLM_VOLT_VOTE_HYSTERESIS 0x1030 -#define LLM_INTF_DCVS_DISABLE 0x1034 +#define CC_ZERO_BEHAV_CTRL 0x100C +#define SPM_CC_DCVS_DISABLE 0x1020 +#define SPM_CC_CTRL 0x1028 +#define SPM_CC_HYSTERESIS 0x101C +#define SPM_CORE_RET_MAPPING 0x1024 +#define CFG_DELAY_VAL_3 0x12C -#define ENABLE_OVERRIDE BIT(0) +#define LLM_FREQ_VOTE_HYSTERESIS 0x102C +#define LLM_VOLT_VOTE_HYSTERESIS 0x1030 +#define LLM_INTF_DCVS_DISABLE 0x1034 -#define ITM_CL0_DISABLE_CL1_ENABLED 0x2 -#define ITM_CL0_ENABLED_CL1_DISABLE 0x1 +#define ENABLE_OVERRIDE BIT(0) -#define APM_MX_MODE 0 -#define APM_APC_MODE BIT(1) -#define APM_MODE_SWITCH_MASK (BVAL(4, 2, 7) | BVAL(1, 0, 3)) -#define APM_MX_MODE_VAL 0 -#define APM_APC_MODE_VAL 0x3 +#define ITM_CL0_DISABLE_CL1_ENABLED 0x2 +#define ITM_CL0_ENABLED_CL1_DISABLE 0x1 -#define GPLL_SEL 0x400 -#define PLL_EARLY_SEL 0x500 -#define PLL_MAIN_SEL 0x300 -#define RCG_UPDATE 0x3 -#define RCG_UPDATE_SUCCESS 0x2 -#define PLL_POST_DIV1 0x1F -#define PLL_POST_DIV2 0x11F +#define APM_MX_MODE 0 +#define APM_APC_MODE BIT(1) +#define APM_MODE_SWITCH_MASK (BVAL(4, 2, 7) | BVAL(1, 0, 3)) +#define APM_MX_MODE_VAL 0 +#define APM_APC_MODE_VAL 0x3 -#define LLM_SW_OVERRIDE_REG 0x1038 -#define VMIN_REDUC_ENABLE_REG 0x103C -#define VMIN_REDUC_TIMER_REG 0x1040 -#define PDN_FSM_CTRL_REG 0x1070 -#define CC_BOOST_TIMER_REG0 0x1074 -#define CC_BOOST_TIMER_REG1 0x1078 -#define CC_BOOST_TIMER_REG2 0x107C -#define CC_BOOST_EN_MASK BIT(0) -#define PS_BOOST_EN_MASK BIT(1) -#define DCVS_BOOST_EN_MASK BIT(2) -#define PC_RET_EXIT_DROOP_EN_MASK BIT(3) -#define WFX_DROOP_EN_MASK BIT(4) -#define DCVS_DROOP_EN_MASK BIT(5) -#define LMH_PS_EN_MASK BIT(6) -#define IGNORE_PLL_LOCK_MASK BIT(15) -#define SAFE_FREQ_WAIT_NS 5000 -#define DEXT_DECREMENT_WAIT_NS 1000 -#define DCVS_BOOST_TIMER_REG0 0x1084 -#define DCVS_BOOST_TIMER_REG1 0x1088 -#define DCVS_BOOST_TIMER_REG2 0x108C -#define PS_BOOST_TIMER_REG0 0x1094 -#define PS_BOOST_TIMER_REG1 0x1098 -#define PS_BOOST_TIMER_REG2 0x109C -#define BOOST_PROG_SYNC_DELAY_REG 0x10A0 -#define DROOP_CTRL_REG 0x10A4 -#define DROOP_RELEASE_TIMER_CTRL 0x10A8 -#define DROOP_PROG_SYNC_DELAY_REG 0x10BC -#define DROOP_UNSTALL_TIMER_CTRL_REG 0x10AC -#define DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG 0x10B0 -#define DROOP_WAIT_TO_RELEASE_TIMER_CTRL1_REG 0x10B4 -#define OSM_PLL_SW_OVERRIDE_EN 0x10C0 +#define GPLL_SEL 0x400 +#define PLL_EARLY_SEL 0x500 +#define PLL_MAIN_SEL 0x300 +#define RCG_UPDATE 0x3 +#define RCG_UPDATE_SUCCESS 0x2 +#define PLL_POST_DIV1 0x1F +#define PLL_POST_DIV2 0x11F -#define PLL_SW_OVERRIDE_DROOP_EN BIT(0) -#define DCVS_DROOP_TIMER_CTRL 0x10B8 -#define SEQ_MEM_ADDR 0x500 -#define SEQ_CFG_BR_ADDR 0x170 -#define MAX_INSTRUCTIONS 256 -#define MAX_BR_INSTRUCTIONS 49 +#define LLM_SW_OVERRIDE_REG 0x1038 +#define VMIN_REDUC_ENABLE_REG 0x103C +#define VMIN_REDUC_TIMER_REG 0x1040 +#define PDN_FSM_CTRL_REG 0x1070 +#define CC_BOOST_TIMER_REG0 0x1074 +#define CC_BOOST_TIMER_REG1 0x1078 +#define CC_BOOST_TIMER_REG2 0x107C +#define CC_BOOST_EN_MASK BIT(0) +#define PS_BOOST_EN_MASK BIT(1) +#define DCVS_BOOST_EN_MASK BIT(2) +#define PC_RET_EXIT_DROOP_EN_MASK BIT(3) +#define WFX_DROOP_EN_MASK BIT(4) +#define DCVS_DROOP_EN_MASK BIT(5) +#define LMH_PS_EN_MASK BIT(6) +#define IGNORE_PLL_LOCK_MASK BIT(15) +#define SAFE_FREQ_WAIT_NS 5000 +#define DEXT_DECREMENT_WAIT_NS 1000 +#define DCVS_BOOST_TIMER_REG0 0x1084 +#define DCVS_BOOST_TIMER_REG1 0x1088 +#define DCVS_BOOST_TIMER_REG2 0x108C +#define PS_BOOST_TIMER_REG0 0x1094 +#define PS_BOOST_TIMER_REG1 0x1098 +#define PS_BOOST_TIMER_REG2 0x109C +#define BOOST_PROG_SYNC_DELAY_REG 0x10A0 +#define DROOP_CTRL_REG 0x10A4 +#define DROOP_RELEASE_TIMER_CTRL 0x10A8 +#define DROOP_PROG_SYNC_DELAY_REG 0x10BC +#define DROOP_UNSTALL_TIMER_CTRL_REG 0x10AC +#define DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG 0x10B0 +#define DROOP_WAIT_TO_RELEASE_TIMER_CTRL1_REG 0x10B4 +#define OSM_PLL_SW_OVERRIDE_EN 0x10C0 -#define MAX_MEM_ACC_LEVELS 3 -#define MAX_MEM_ACC_VAL_PER_LEVEL 3 -#define MAX_MEM_ACC_VALUES (MAX_MEM_ACC_LEVELS * \ - MAX_MEM_ACC_VAL_PER_LEVEL) -#define MEM_ACC_APM_READ_MASK 0xff +#define PLL_SW_OVERRIDE_DROOP_EN BIT(0) +#define DCVS_DROOP_TIMER_CTRL 0x10B8 +#define SEQ_MEM_ADDR 0x500 +#define SEQ_CFG_BR_ADDR 0x170 +#define MAX_INSTRUCTIONS 256 +#define MAX_BR_INSTRUCTIONS 49 -#define TRACE_CTRL 0x1F38 -#define TRACE_CTRL_EN_MASK BIT(0) -#define TRACE_CTRL_ENABLE 1 -#define TRACE_CTRL_DISABLE 0 -#define TRACE_CTRL_ENABLE_WDOG_STATUS BIT(30) -#define TRACE_CTRL_PACKET_TYPE_MASK BVAL(2, 1, 3) -#define TRACE_CTRL_PACKET_TYPE_SHIFT 1 -#define TRACE_CTRL_PERIODIC_TRACE_EN_MASK BIT(3) -#define TRACE_CTRL_PERIODIC_TRACE_ENABLE BIT(3) -#define PERIODIC_TRACE_TIMER_CTRL 0x1F3C -#define PERIODIC_TRACE_MIN_NS 1000 -#define PERIODIC_TRACE_MAX_NS 21474836475 -#define PERIODIC_TRACE_DEFAULT_NS 1000000 +#define MAX_MEM_ACC_LEVELS 3 +#define MAX_MEM_ACC_VAL_PER_LEVEL 3 +#define MAX_MEM_ACC_VALUES (MAX_MEM_ACC_LEVELS * \ + MAX_MEM_ACC_VAL_PER_LEVEL) +#define MEM_ACC_APM_READ_MASK 0xff -#define PLL_DD_USER_CTL_LO_ENABLE 0x0f04c408 -#define PLL_DD_USER_CTL_LO_DISABLE 0x1f04c41f -#define PLL_DD_D0_USER_CTL_LO 0x17916208 -#define PLL_DD_D1_USER_CTL_LO 0x17816208 +#define TRACE_CTRL 0x1F38 +#define TRACE_CTRL_EN_MASK BIT(0) +#define TRACE_CTRL_ENABLE 1 +#define TRACE_CTRL_DISABLE 0 +#define TRACE_CTRL_ENABLE_WDOG_STATUS BIT(30) +#define TRACE_CTRL_PACKET_TYPE_MASK BVAL(2, 1, 3) +#define TRACE_CTRL_PACKET_TYPE_SHIFT 1 +#define TRACE_CTRL_PERIODIC_TRACE_EN_MASK BIT(3) +#define TRACE_CTRL_PERIODIC_TRACE_ENABLE BIT(3) +#define PERIODIC_TRACE_TIMER_CTRL 0x1F3C +#define PERIODIC_TRACE_MIN_NS 1000 +#define PERIODIC_TRACE_MAX_NS 21474836475ULL +#define PERIODIC_TRACE_DEFAULT_NS 1000000 -#define PWRCL_EFUSE_SHIFT 0 -#define PWRCL_EFUSE_MASK 0 -#define PERFCL_EFUSE_SHIFT 29 -#define PERFCL_EFUSE_MASK 0x7 +#define PLL_DD_USER_CTL_LO_ENABLE 0x0f04c408 +#define PLL_DD_USER_CTL_LO_DISABLE 0x1f04c41f +#define PLL_DD_D0_USER_CTL_LO 0x17916208 +#define PLL_DD_D1_USER_CTL_LO 0x17816208 -#define MSMCOBALTV1_PWRCL_BOOT_RATE 1478400000 -#define MSMCOBALTV1_PERFCL_BOOT_RATE 1536000000 -#define MSMCOBALTV2_PWRCL_BOOT_RATE 1555200000 -#define MSMCOBALTV2_PERFCL_BOOT_RATE 1728000000 +#define PWRCL_EFUSE_SHIFT 0 +#define PWRCL_EFUSE_MASK 0 +#define PERFCL_EFUSE_SHIFT 29 +#define PERFCL_EFUSE_MASK 0x7 /* ACD registers */ -#define ACD_HW_VERSION 0x0 -#define ACDCR 0x4 -#define ACDTD 0x8 -#define ACDSSCR 0x28 -#define ACD_EXTINT_CFG 0x30 -#define ACD_DCVS_SW 0x34 -#define ACD_GFMUX_CFG 0x3c -#define ACD_READOUT_CFG 0x48 -#define ACD_AUTOXFER_CFG 0x80 -#define ACD_AUTOXFER 0x84 -#define ACD_AUTOXFER_CTL 0x88 -#define ACD_AUTOXFER_STATUS 0x8c -#define ACD_WRITE_CTL 0x90 -#define ACD_WRITE_STATUS 0x94 -#define ACD_READOUT 0x98 +#define ACD_HW_VERSION 0x0 +#define ACDCR 0x4 +#define ACDTD 0x8 +#define ACDSSCR 0x28 +#define ACD_EXTINT_CFG 0x30 +#define ACD_DCVS_SW 0x34 +#define ACD_GFMUX_CFG 0x3c +#define ACD_READOUT_CFG 0x48 +#define ACD_AUTOXFER_CFG 0x80 +#define ACD_AUTOXFER 0x84 +#define ACD_AUTOXFER_CTL 0x88 +#define ACD_AUTOXFER_STATUS 0x8c +#define ACD_WRITE_CTL 0x90 +#define ACD_WRITE_STATUS 0x94 +#define ACD_READOUT 0x98 -#define ACD_MASTER_ONLY_REG_ADDR 0x80 -#define ACD_WRITE_CTL_UPDATE_EN BIT(0) -#define ACD_WRITE_CTL_SELECT_SHIFT 1 -#define ACD_GFMUX_CFG_SELECT BIT(0) -#define ACD_AUTOXFER_START_CLEAR 0 -#define ACD_AUTOXFER_START_SET BIT(0) -#define AUTO_XFER_DONE_MASK BIT(0) -#define ACD_DCVS_SW_DCVS_IN_PRGR_SET BIT(0) -#define ACD_DCVS_SW_DCVS_IN_PRGR_CLEAR 0 -#define ACD_LOCAL_TRANSFER_TIMEOUT_NS 500 +#define ACD_MASTER_ONLY_REG_ADDR 0x80 +#define ACD_WRITE_CTL_UPDATE_EN BIT(0) +#define ACD_WRITE_CTL_SELECT_SHIFT 1 +#define ACD_GFMUX_CFG_SELECT BIT(0) +#define ACD_AUTOXFER_START_CLEAR 0 +#define ACD_AUTOXFER_START_SET BIT(0) +#define AUTO_XFER_DONE_MASK BIT(0) +#define ACD_DCVS_SW_DCVS_IN_PRGR_SET BIT(0) +#define ACD_DCVS_SW_DCVS_IN_PRGR_CLEAR 0 +#define ACD_LOCAL_TRANSFER_TIMEOUT_NS 500 -static void __iomem *virt_base; -static void __iomem *debug_base; - -#define lmh_lite_clk_src_source_val 1 - -#define ACD_REG_RELATIVE_ADDR(addr) (addr / 4) +#define ACD_REG_RELATIVE_ADDR(addr) (addr / 4) #define ACD_REG_RELATIVE_ADDR_BITMASK(addr) \ - (1 << (ACD_REG_RELATIVE_ADDR(addr))) + (1 << (ACD_REG_RELATIVE_ADDR(addr))) -#define FIXDIV(div) (div ? (2 * (div) - 1) : (0)) - -#define F(f, s, div, m, n) \ - { \ - .freq_hz = (f), \ - .src_clk = &s.c, \ - .m_val = (m), \ - .n_val = ~((n)-(m)) * !!(n), \ - .d_val = ~(n),\ - .div_src_val = BVAL(4, 0, (int)FIXDIV(div)) \ - | BVAL(10, 8, s##_source_val), \ - } +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } static u32 seq_instr[] = { 0xc2005000, 0x2c9e3b21, 0xc0ab2cdc, 0xc2882525, 0x359dc491, @@ -325,10 +307,6 @@ static u32 seq_br_instr[] = { 0x20c, }; -DEFINE_EXT_CLK(xo_ao, NULL); -DEFINE_EXT_CLK(sys_apcsaux_clk_gcc, NULL); -DEFINE_EXT_CLK(lmh_lite_clk_src, NULL); - struct osm_entry { u16 virtual_corner; u16 open_loop_volt; @@ -338,10 +316,20 @@ struct osm_entry { long frequency; }; +static void __iomem *virt_base; static struct dentry *osm_debugfs_base; +static struct regulator *vdd_pwrcl; +static struct regulator *vdd_perfcl; + +static const struct regmap_config osm_qcom_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .fast_io = true, +}; struct clk_osm { - struct clk c; + struct clk_hw hw; struct osm_entry osm_table[OSM_TABLE_SIZE]; struct dentry *debugfs; struct regulator *vdd_reg; @@ -350,13 +338,14 @@ struct clk_osm { unsigned long pbases[NUM_BASES]; spinlock_t lock; - u32 version; u32 cpu_reg_mask; u32 num_entries; u32 cluster_num; u32 irq; u32 apm_crossover_vc; u32 apm_threshold_vc; + u32 mem_acc_crossover_vc; + u32 mem_acc_threshold_vc; u32 cycle_counter_reads; u32 cycle_counter_delay; u32 cycle_counter_factor; @@ -399,9 +388,6 @@ struct clk_osm { bool wdog_trace_en; }; -static bool msmcobalt_v1; -static bool msmcobalt_v2; - static inline void clk_osm_masked_write_reg(struct clk_osm *c, u32 val, u32 offset, u32 mask) { @@ -600,63 +586,86 @@ static inline int clk_osm_count_ns(struct clk_osm *c, u64 nsec) return temp; } -static inline struct clk_osm *to_clk_osm(struct clk *c) +static inline struct clk_osm *to_clk_osm(struct clk_hw *_hw) { - return container_of(c, struct clk_osm, c); + return container_of(_hw, struct clk_osm, hw); } -static enum handoff clk_osm_handoff(struct clk *c) +static long clk_osm_list_rate(struct clk_hw *hw, unsigned n, + unsigned long rate_max) { - return HANDOFF_DISABLED_CLK; -} - -static long clk_osm_list_rate(struct clk *c, unsigned n) -{ - if (n >= c->num_fmax) + if (n >= hw->init->num_rate_max) return -ENXIO; - return c->fmax[n]; + return hw->init->rate_max[n]; } -static long clk_osm_round_rate(struct clk *c, unsigned long rate) +static inline bool is_better_rate(unsigned long req, unsigned long best, + unsigned long new) +{ + if (IS_ERR_VALUE(new)) + return false; + + return (req <= new && new < best) || (best < req && best < new); +} + +static long clk_osm_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) { int i; unsigned long rrate = 0; /* - * If the rate passed in is 0, return the first frequency in - * the FMAX table. + * If the rate passed in is 0, return the first frequency in the + * FMAX table. */ if (!rate) - return c->fmax[0]; + return hw->init->rate_max[0]; - for (i = 0; i < c->num_fmax; i++) { - if (is_better_rate(rate, rrate, c->fmax[i])) { - rrate = c->fmax[i]; - if (rrate == rate) + for (i = 0; i < hw->init->num_rate_max; i++) { + if (is_better_rate(rate, rrate, hw->init->rate_max[i])) { + rrate = hw->init->rate_max[i]; + if (rate == rrate) break; } } + pr_debug("%s: rate %lu, rrate %ld, Rate max %ld\n", __func__, rate, + rrate, hw->init->rate_max[i]); + return rrate; } static int clk_osm_search_table(struct osm_entry *table, int entries, long rate) { - int i; + int quad_core_index, single_core_index = 0; + int core_count; + + for (quad_core_index = 0; quad_core_index < entries; + quad_core_index++) { + core_count = CORE_COUNT_VAL(table[quad_core_index].freq_data); + if (rate == table[quad_core_index].frequency && + core_count == SINGLE_CORE) { + single_core_index = quad_core_index; + continue; + } + if (rate == table[quad_core_index].frequency && + core_count == MAX_CORE_COUNT) + return quad_core_index; + } + if (single_core_index) + return single_core_index; - for (i = 0; i < entries; i++) - if (rate == table[i].frequency) - return i; return -EINVAL; } -static int clk_osm_set_rate(struct clk *c, unsigned long rate) +static int clk_osm_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) { - struct clk_osm *cpuclk = to_clk_osm(c); + struct clk_osm *cpuclk = to_clk_osm(hw); int index = 0; unsigned long r_rate; - r_rate = clk_osm_round_rate(c, rate); + r_rate = clk_osm_round_rate(hw, rate, NULL); if (rate != r_rate) { pr_err("invalid rate requested rate=%ld\n", rate); @@ -675,9 +684,9 @@ static int clk_osm_set_rate(struct clk *c, unsigned long rate) if (cpuclk->llm_sw_overr[0]) { clk_osm_write_reg(cpuclk, cpuclk->llm_sw_overr[0], - LLM_SW_OVERRIDE_REG); + LLM_SW_OVERRIDE_REG); clk_osm_write_reg(cpuclk, cpuclk->llm_sw_overr[1], - LLM_SW_OVERRIDE_REG); + LLM_SW_OVERRIDE_REG); udelay(1); } @@ -687,7 +696,7 @@ static int clk_osm_set_rate(struct clk *c, unsigned long rate) if (cpuclk->llm_sw_overr[0]) { udelay(1); clk_osm_write_reg(cpuclk, cpuclk->llm_sw_overr[2], - LLM_SW_OVERRIDE_REG); + LLM_SW_OVERRIDE_REG); } /* Make sure the write goes through before proceeding */ @@ -696,9 +705,9 @@ static int clk_osm_set_rate(struct clk *c, unsigned long rate) return 0; } -static int clk_osm_enable(struct clk *c) +static int clk_osm_enable(struct clk_hw *hw) { - struct clk_osm *cpuclk = to_clk_osm(c); + struct clk_osm *cpuclk = to_clk_osm(hw); clk_osm_write_reg(cpuclk, 1, ENABLE_REG); @@ -713,96 +722,109 @@ static int clk_osm_enable(struct clk *c) return 0; } +static unsigned long clk_osm_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_osm *cpuclk = to_clk_osm(hw); + int index = 0; + + index = clk_osm_read_reg(cpuclk, DCVS_PERF_STATE_DESIRED_REG); + + pr_debug("%s: Index %d, freq %ld\n", __func__, index, + cpuclk->osm_table[index].frequency); + + /* Convert index to frequency. + * The frequency corresponding to the index requested might not + * be what the clock is actually running at. + * There are other inputs into OSM(acd, LMH, sequencer) + * which might decide the final rate. + */ + return cpuclk->osm_table[index].frequency; +} + static struct clk_ops clk_ops_cpu_osm = { .enable = clk_osm_enable, .set_rate = clk_osm_set_rate, .round_rate = clk_osm_round_rate, .list_rate = clk_osm_list_rate, - .handoff = clk_osm_handoff, + .recalc_rate = clk_osm_recalc_rate, }; -static struct regulator *vdd_pwrcl; -static struct regulator *vdd_perfcl; - -static struct clk_freq_tbl ftbl_osm_clk_src[] = { - F( 200000000, lmh_lite_clk_src, 1.5, 0, 0), - F_END +static const struct parent_map gcc_parent_map_1[] = { + { P_XO, 0 }, + { LMH_LITE_CLK_SRC, 1 }, }; -static struct rcg_clk osm_clk_src = { - .cmd_rcgr_reg = APCS_COMMON_LMH_CMD_RCGR, - .set_rate = set_rate_hid, +static const char * const gcc_parent_names_1[] = { + "xo", + "hmss_gpll0_clk_src", +}; + +static struct freq_tbl ftbl_osm_clk_src[] = { + F(200000000, LMH_LITE_CLK_SRC, 3, 0, 0), + { } +}; + +/* APCS_COMMON_LMH_CMD_RCGR */ +static struct clk_rcg2 osm_clk_src = { + .cmd_rcgr = 0x0012c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, .freq_tbl = ftbl_osm_clk_src, - .current_freq = &rcg_dummy_freq, - .base = &virt_base, - .c = { - .dbg_name = "osm_clk_src", - .ops = &clk_ops_rcg, - CLK_INIT(osm_clk_src.c), + .clkr.hw.init = &(struct clk_init_data){ + .name = "osm_clk_src", + .parent_names = gcc_parent_names_1, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_fixed_factor sys_apcsaux_clk_gcc = { + .div = 1, + .mult = 1, + .hw.init = &(struct clk_init_data){ + .name = "sys_apcsaux_clk_gcc", + .parent_names = (const char *[]){ "hmss_gpll0_clk_src" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_init_data osm_clks_init[] = { + [0] = { + .name = "pwrcl_clk", + .parent_names = (const char *[]){ "cxo_a" }, + .num_parents = 1, + .ops = &clk_ops_cpu_osm, + }, + [1] = { + .name = "perfcl_clk", + .parent_names = (const char *[]){ "cxo_a" }, + .num_parents = 1, + .ops = &clk_ops_cpu_osm, }, }; static struct clk_osm pwrcl_clk = { .cluster_num = 0, .cpu_reg_mask = 0x3, - .c = { - .dbg_name = "pwrcl_clk", - .ops = &clk_ops_cpu_osm, - .parent = &xo_ao.c, - CLK_INIT(pwrcl_clk.c), - }, + .hw.init = &osm_clks_init[0], }; static struct clk_osm perfcl_clk = { .cluster_num = 1, .cpu_reg_mask = 0x103, - .c = { - .dbg_name = "perfcl_clk", - .ops = &clk_ops_cpu_osm, - .parent = &xo_ao.c, - CLK_INIT(perfcl_clk.c), - }, + .hw.init = &osm_clks_init[1], }; -static struct clk_ops clk_ops_cpu_dbg_mux; - -static struct mux_clk cpu_debug_mux = { - .offset = 0x0, - .mask = 0x3, - .shift = 8, - .ops = &mux_reg_ops, - MUX_SRC_LIST( - { &pwrcl_clk.c, 0x00 }, - { &perfcl_clk.c, 0x01 }, - ), - .base = &debug_base, - .c = { - .dbg_name = "cpu_debug_mux", - .ops = &clk_ops_cpu_dbg_mux, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(cpu_debug_mux.c), - }, +static struct clk_hw *osm_qcom_clk_hws[] = { + [SYS_APCSAUX_CLK_GCC] = &sys_apcsaux_clk_gcc.hw, + [PWRCL_CLK] = &pwrcl_clk.hw, + [PERFCL_CLK] = &perfcl_clk.hw, + [OSM_CLK_SRC] = &osm_clk_src.clkr.hw, }; -static struct clk_lookup cpu_clocks_osm[] = { - CLK_LIST(pwrcl_clk), - CLK_LIST(perfcl_clk), - CLK_LIST(sys_apcsaux_clk_gcc), - CLK_LIST(xo_ao), - CLK_LIST(osm_clk_src), - CLK_LIST(cpu_debug_mux), -}; - -static unsigned long cpu_dbg_mux_get_rate(struct clk *clk) -{ - /* Account for the divider between the clock and the debug mux */ - if (!strcmp(clk->parent->dbg_name, "pwrcl_clk")) - return clk->rate/4; - else if (!strcmp(clk->parent->dbg_name, "perfcl_clk")) - return clk->rate/8; - return clk->rate; -} - static void clk_osm_print_osm_table(struct clk_osm *c) { int i; @@ -813,7 +835,7 @@ static void clk_osm_print_osm_table(struct clk_osm *c) for (i = 0; i < c->num_entries; i++) { pll_src = (table[i].freq_data & GENMASK(27, 26)) >> 26; pll_div = (table[i].freq_data & GENMASK(25, 24)) >> 24; - lval = table[i].freq_data & GENMASK(7, 0); + lval = L_VAL(table[i].freq_data); core_count = (table[i].freq_data & GENMASK(18, 16)) >> 16; pr_debug("%3d, %11lu, %2u, %5u, %2u, %6u, %8u, %7u, %5u\n", @@ -828,18 +850,21 @@ static void clk_osm_print_osm_table(struct clk_osm *c) table[i].spare_data); } pr_debug("APM threshold corner=%d, crossover corner=%d\n", - c->apm_threshold_vc, c->apm_crossover_vc); + c->apm_threshold_vc, c->apm_crossover_vc); + pr_debug("MEM-ACC threshold corner=%d, crossover corner=%d\n", + c->mem_acc_threshold_vc, c->mem_acc_crossover_vc); } static int clk_osm_get_lut(struct platform_device *pdev, struct clk_osm *c, char *prop_name) { - struct clk *clk = &c->c; struct device_node *of = pdev->dev.of_node; int prop_len, total_elems, num_rows, i, j, k; int rc = 0; u32 *array; + u32 *fmax_temp; u32 data; + unsigned long abs_fmax = 0; bool last_entry = false; if (!of_find_property(of, prop_name, &prop_len)) { @@ -855,9 +880,9 @@ static int clk_osm_get_lut(struct platform_device *pdev, num_rows = total_elems / NUM_FIELDS; - clk->fmax = devm_kzalloc(&pdev->dev, num_rows * sizeof(unsigned long), - GFP_KERNEL); - if (!clk->fmax) + fmax_temp = devm_kzalloc(&pdev->dev, num_rows * sizeof(unsigned long), + GFP_KERNEL); + if (!fmax_temp) return -ENOMEM; array = devm_kzalloc(&pdev->dev, prop_len, GFP_KERNEL); @@ -893,18 +918,34 @@ static int clk_osm_get_lut(struct platform_device *pdev, c->osm_table[j].spare_data); data = (array[i + FREQ_DATA] & GENMASK(18, 16)) >> 16; - if (!last_entry) { - clk->fmax[k] = array[i]; + if (!last_entry && data == MAX_CORE_COUNT) { + fmax_temp[k] = array[i]; k++; } if (i < total_elems - NUM_FIELDS) i += NUM_FIELDS; - else + else { + abs_fmax = array[i]; last_entry = true; + } } - clk->num_fmax = k; + fmax_temp[k] = abs_fmax; + + osm_clks_init[c->cluster_num].rate_max = devm_kzalloc(&pdev->dev, + k * sizeof(unsigned long), + GFP_KERNEL); + if (!osm_clks_init[c->cluster_num].rate_max) { + rc = -ENOMEM; + goto exit; + } + + for (i = 0; i < k; i++) + osm_clks_init[c->cluster_num].rate_max[i] = fmax_temp[i]; + + osm_clks_init[c->cluster_num].num_rate_max = k; exit: + devm_kfree(&pdev->dev, fmax_temp); devm_kfree(&pdev->dev, array); return rc; } @@ -1192,7 +1233,6 @@ static int clk_osm_resources_init(struct platform_device *pdev) { struct device_node *node; struct resource *res; - struct clk *c; unsigned long pbase; int i, rc = 0; void *vbase; @@ -1213,9 +1253,9 @@ static int clk_osm_resources_init(struct platform_device *pdev) } perfcl_clk.pbases[OSM_BASE] = pwrcl_clk.pbases[OSM_BASE] + - perfcl_clk.cluster_num * OSM_CORE_TABLE_SIZE; + perfcl_clk.cluster_num * OSM_CORE_TABLE_SIZE; perfcl_clk.vbases[OSM_BASE] = pwrcl_clk.vbases[OSM_BASE] + - perfcl_clk.cluster_num * OSM_CORE_TABLE_SIZE; + perfcl_clk.cluster_num * OSM_CORE_TABLE_SIZE; for (i = 0; i < MAX_CLUSTER_CNT; i++) { res = platform_get_resource_byname(pdev, IORESOURCE_MEM, @@ -1244,22 +1284,6 @@ static int clk_osm_resources_init(struct platform_device *pdev) } } - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "debug"); - if (!res) { - dev_err(&pdev->dev, "Failed to get debug mux base\n"); - return -EINVAL; - } - - debug_base = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); - if (!debug_base) { - dev_err(&pdev->dev, "Unable to map in debug mux base\n"); - return -ENOMEM; - } - - clk_ops_cpu_dbg_mux = clk_ops_gen_mux; - clk_ops_cpu_dbg_mux.get_rate = cpu_dbg_mux_get_rate; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apcs_common"); if (!res) { dev_err(&pdev->dev, "Failed to get apcs common base\n"); @@ -1272,6 +1296,13 @@ static int clk_osm_resources_init(struct platform_device *pdev) return -ENOMEM; } + osm_clk_src.clkr.regmap = devm_regmap_init_mmio(&pdev->dev, virt_base, + &osm_qcom_regmap_config); + if (IS_ERR(osm_clk_src.clkr.regmap)) { + dev_err(&pdev->dev, "Couldn't get regmap OSM clock\n"); + return PTR_ERR(osm_clk_src.clkr.regmap); + } + /* efuse speed bin fuses are optional */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwrcl_efuse"); @@ -1381,26 +1412,6 @@ static int clk_osm_resources_init(struct platform_device *pdev) return -EINVAL; } - c = devm_clk_get(&pdev->dev, "aux_clk"); - if (IS_ERR(c)) { - rc = PTR_ERR(c); - if (rc != -EPROBE_DEFER) - dev_err(&pdev->dev, "Unable to get aux_clk, rc=%d\n", - rc); - return rc; - } - sys_apcsaux_clk_gcc.c.parent = c; - - c = devm_clk_get(&pdev->dev, "xo_ao"); - if (IS_ERR(c)) { - rc = PTR_ERR(c); - if (rc != -EPROBE_DEFER) - dev_err(&pdev->dev, "Unable to get xo_ao clk, rc=%d\n", - rc); - return rc; - } - xo_ao.c.parent = c; - return 0; } @@ -1490,20 +1501,27 @@ static int clk_osm_resolve_open_loop_voltages(struct clk_osm *c) } static int clk_osm_resolve_crossover_corners(struct clk_osm *c, - struct platform_device *pdev) + struct platform_device *pdev, + const char *mem_acc_prop) { struct regulator *regulator = c->vdd_reg; - int count, vc, i, threshold, rc = 0; + int count, vc, i, apm_threshold; + int mem_acc_threshold = 0; + int rc = 0; u32 corner_volt; rc = of_property_read_u32(pdev->dev.of_node, "qcom,apm-threshold-voltage", - &threshold); + &apm_threshold); if (rc) { pr_info("qcom,apm-threshold-voltage property not specified\n"); return rc; } + if (mem_acc_prop) + of_property_read_u32(pdev->dev.of_node, mem_acc_prop, + &mem_acc_threshold); + /* Determine crossover virtual corner */ count = regulator_count_voltages(regulator); if (count < 0) { @@ -1511,19 +1529,49 @@ static int clk_osm_resolve_crossover_corners(struct clk_osm *c, return count; } - c->apm_crossover_vc = count - 1; + /* + * CPRh corners (in hardware) are ordered: + * 0 - n-1 - for n functional corners + * APM crossover - required for OSM + * [MEM ACC Crossover] - optional + * + * 'count' corresponds to the total number of corners including n + * functional corners, the APM crossover corner, and potentially the + * MEM ACC cross over corner. + */ + if (mem_acc_threshold) { + c->apm_crossover_vc = count - 2; + c->mem_acc_crossover_vc = count - 1; + } else { + c->apm_crossover_vc = count - 1; + } - /* Determine threshold virtual corner */ + /* Determine APM threshold virtual corner */ for (i = 0; i < OSM_TABLE_SIZE; i++) { vc = c->osm_table[i].virtual_corner + 1; corner_volt = regulator_list_corner_voltage(regulator, vc); - if (corner_volt >= threshold) { + if (corner_volt >= apm_threshold) { c->apm_threshold_vc = c->osm_table[i].virtual_corner; break; } } + /* Determine MEM ACC threshold virtual corner */ + if (mem_acc_threshold) { + for (i = 0; i < OSM_TABLE_SIZE; i++) { + vc = c->osm_table[i].virtual_corner + 1; + corner_volt = + regulator_list_corner_voltage(regulator, vc); + + if (corner_volt >= mem_acc_threshold) { + c->mem_acc_threshold_vc + = c->osm_table[i].virtual_corner; + break; + } + } + } + return 0; } @@ -1777,9 +1825,9 @@ static int clk_osm_set_llm_volt_policy(struct platform_device *pdev) /* Enable or disable LLM VOLT DVCS */ regval = val | clk_osm_read_reg(&pwrcl_clk, LLM_INTF_DCVS_DISABLE); - clk_osm_write_reg(&pwrcl_clk, val, LLM_INTF_DCVS_DISABLE); + clk_osm_write_reg(&pwrcl_clk, regval, LLM_INTF_DCVS_DISABLE); regval = val | clk_osm_read_reg(&perfcl_clk, LLM_INTF_DCVS_DISABLE); - clk_osm_write_reg(&perfcl_clk, val, LLM_INTF_DCVS_DISABLE); + clk_osm_write_reg(&perfcl_clk, regval, LLM_INTF_DCVS_DISABLE); /* Wait for the writes to complete */ clk_osm_mb(&perfcl_clk, OSM_BASE); @@ -1820,8 +1868,10 @@ static void clk_osm_program_apm_regs(struct clk_osm *c) static void clk_osm_program_mem_acc_regs(struct clk_osm *c) { + struct osm_entry *table = c->osm_table; int i, curr_level, j = 0; int mem_acc_level_map[MAX_MEM_ACC_LEVELS] = {0, 0, 0}; + int threshold_vc[4]; curr_level = c->osm_table[0].spare_data; for (i = 0; i < c->num_entries; i++) { @@ -1829,7 +1879,8 @@ static void clk_osm_program_mem_acc_regs(struct clk_osm *c) break; if (c->osm_table[i].spare_data != curr_level) { - mem_acc_level_map[j++] = i - 1; + mem_acc_level_map[j++] = + c->osm_table[i].virtual_corner - 1; curr_level = c->osm_table[i].spare_data; } } @@ -1855,16 +1906,49 @@ static void clk_osm_program_mem_acc_regs(struct clk_osm *c) clk_osm_write_reg(c, c->apcs_mem_acc_cfg[i], MEM_ACC_SEQ_REG_CFG_START(i)); } else { + if (c->mem_acc_crossover_vc) + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(88), + c->mem_acc_crossover_vc); + + threshold_vc[0] = mem_acc_level_map[0]; + threshold_vc[1] = mem_acc_level_map[0] + 1; + threshold_vc[2] = mem_acc_level_map[1]; + threshold_vc[3] = mem_acc_level_map[1] + 1; + + /* + * Use dynamic MEM ACC threshold voltage based value for the + * highest MEM ACC threshold if it is specified instead of the + * fixed mapping in the LUT. + */ + if (c->mem_acc_threshold_vc) { + threshold_vc[2] = c->mem_acc_threshold_vc - 1; + threshold_vc[3] = c->mem_acc_threshold_vc; + if (threshold_vc[1] >= threshold_vc[2]) + threshold_vc[1] = threshold_vc[2] - 1; + if (threshold_vc[0] >= threshold_vc[1]) + threshold_vc[0] = threshold_vc[1] - 1; + } + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(55), - mem_acc_level_map[0]); + threshold_vc[0]); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(56), - mem_acc_level_map[0] + 1); + threshold_vc[1]); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(57), - mem_acc_level_map[1]); + threshold_vc[2]); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(58), - mem_acc_level_map[1] + 1); + threshold_vc[3]); /* SEQ_REG(49) = SEQ_REG(28) init by TZ */ } + + /* + * Program L_VAL corresponding to the first virtual + * corner with MEM ACC level 3. + */ + if (c->mem_acc_threshold_vc) + for (i = 0; i < c->num_entries; i++) + if (c->mem_acc_threshold_vc == table[i].virtual_corner) + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(32), + L_VAL(table[i].freq_data)); } void clk_osm_setup_sequencer(struct clk_osm *c) @@ -1895,95 +1979,15 @@ static void clk_osm_setup_cycle_counters(struct clk_osm *c) /* Setup OSM clock to XO ratio */ do_div(ratio, c->xo_clk_rate); val |= BVAL(5, 1, ratio - 1) | OSM_CYCLE_COUNTER_USE_XO_EDGE_EN; + clk_osm_write_reg(c, val, OSM_CYCLE_COUNTER_CTRL_REG); + c->total_cycle_counter = 0; c->prev_cycle_counter = 0; + pr_debug("OSM to XO clock ratio: %d\n", ratio); } -static void clk_osm_setup_osm_was(struct clk_osm *c) -{ - u32 cc_hyst; - u32 val; - - if (msmcobalt_v2) - return; - - val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG); - val |= IGNORE_PLL_LOCK_MASK; - cc_hyst = clk_osm_read_reg(c, SPM_CC_HYSTERESIS); - - if (c->secure_init) { - clk_osm_write_reg(c, val, SEQ_REG(47)); - val &= ~IGNORE_PLL_LOCK_MASK; - clk_osm_write_reg(c, val, SEQ_REG(48)); - - clk_osm_write_reg(c, c->pbases[OSM_BASE] + SEQ_REG(42), - SEQ_REG(40)); - clk_osm_write_reg(c, c->pbases[OSM_BASE] + SEQ_REG(43), - SEQ_REG(41)); - clk_osm_write_reg(c, 0x1, SEQ_REG(44)); - clk_osm_write_reg(c, 0x0, SEQ_REG(45)); - clk_osm_write_reg(c, c->pbases[OSM_BASE] + PDN_FSM_CTRL_REG, - SEQ_REG(46)); - - /* C2D/C3 + D2D workaround */ - clk_osm_write_reg(c, c->pbases[OSM_BASE] + SPM_CC_HYSTERESIS, - SEQ_REG(6)); - clk_osm_write_reg(c, cc_hyst, SEQ_REG(7)); - - /* Droop detector PLL lock detect workaround */ - clk_osm_write_reg(c, PLL_DD_USER_CTL_LO_ENABLE, SEQ_REG(4)); - clk_osm_write_reg(c, PLL_DD_USER_CTL_LO_DISABLE, SEQ_REG(5)); - clk_osm_write_reg(c, c->cluster_num == 0 ? PLL_DD_D0_USER_CTL_LO - : PLL_DD_D1_USER_CTL_LO, SEQ_REG(21)); - - /* PLL lock detect and HMSS AHB clock workaround */ - clk_osm_write_reg(c, 0x640, CFG_DELAY_VAL_3); - - /* DxFSM workaround */ - clk_osm_write_reg(c, c->cluster_num == 0 ? 0x17911200 : - 0x17811200, SEQ_REG(22)); - clk_osm_write_reg(c, 0x80800, SEQ_REG(23)); - clk_osm_write_reg(c, 0x179D1100, SEQ_REG(24)); - clk_osm_write_reg(c, 0x11f, SEQ_REG(25)); - clk_osm_write_reg(c, c->cluster_num == 0 ? 0x17912000 : - 0x17811290, SEQ_REG(26)); - clk_osm_write_reg(c, c->cluster_num == 0 ? 0x17911290 : - 0x17811290, SEQ_REG(20)); - clk_osm_write_reg(c, c->cluster_num == 0 ? 0x17811290 : - 0x17911290, SEQ_REG(32)); - clk_osm_write_reg(c, 0x179D4020, SEQ_REG(35)); - clk_osm_write_reg(c, 0x11f, SEQ_REG(25)); - clk_osm_write_reg(c, 0xa, SEQ_REG(86)); - clk_osm_write_reg(c, 0xe, SEQ_REG(87)); - clk_osm_write_reg(c, 0x00400000, SEQ_REG(88)); - clk_osm_write_reg(c, 0x00700000, SEQ_REG(89)); - } else { - scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(47), val); - val &= ~IGNORE_PLL_LOCK_MASK; - scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(48), val); - - /* C2D/C3 + D2D workaround */ - scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(7), - cc_hyst); - - /* Droop detector PLL lock detect workaround */ - scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(4), - PLL_DD_USER_CTL_LO_ENABLE); - } - - if (c->cluster_num == 0) { - val = readl_relaxed(c->vbases[PLL_BASE] + PLL_TEST_CTL_HI) - | BIT(13); - writel_relaxed(val, c->vbases[PLL_BASE] + - PLL_TEST_CTL_HI); - } - - /* Ensure writes complete before returning */ - clk_osm_mb(c, OSM_BASE); -} - static void clk_osm_setup_fsms(struct clk_osm *c) { u32 val; @@ -2128,7 +2132,7 @@ static void clk_osm_do_additional_setup(struct clk_osm *c, return; dev_info(&pdev->dev, "Performing additional OSM setup due to lack of TZ for cluster=%d\n", - c->cluster_num); + c->cluster_num); clk_osm_write_reg(c, BVAL(23, 16, 0xF), SPM_CC_CTRL); @@ -2157,7 +2161,7 @@ static void clk_osm_do_additional_setup(struct clk_osm *c, /* ITM to OSM handoff */ clk_osm_setup_itm_to_osm_handoff(); - pr_debug("seq_size: %lu, seqbr_size: %lu\n", ARRAY_SIZE(seq_instr), + pr_debug("seq_size: %zu, seqbr_size: %zu\n", ARRAY_SIZE(seq_instr), ARRAY_SIZE(seq_br_instr)); clk_osm_setup_sequencer(&pwrcl_clk); clk_osm_setup_sequencer(&perfcl_clk); @@ -2175,38 +2179,31 @@ static void clk_osm_apm_vc_setup(struct clk_osm *c) clk_osm_write_reg(c, c->apm_threshold_vc, SEQ_REG(1)); clk_osm_write_reg(c, c->apm_crossover_vc, SEQ_REG(72)); clk_osm_write_reg(c, c->pbases[OSM_BASE] + SEQ_REG(1), - SEQ_REG(8)); - clk_osm_write_reg(c, c->apm_threshold_vc, - SEQ_REG(15)); + SEQ_REG(8)); + clk_osm_write_reg(c, c->apm_threshold_vc, SEQ_REG(15)); clk_osm_write_reg(c, c->apm_threshold_vc != 0 ? - c->apm_threshold_vc - 1 : 0xff, - SEQ_REG(31)); + c->apm_threshold_vc - 1 : 0xff, + SEQ_REG(31)); clk_osm_write_reg(c, 0x3b | c->apm_threshold_vc << 6, - SEQ_REG(73)); + SEQ_REG(73)); clk_osm_write_reg(c, 0x39 | c->apm_threshold_vc << 6, - SEQ_REG(76)); + SEQ_REG(76)); /* Ensure writes complete before returning */ clk_osm_mb(c, OSM_BASE); } else { - if (msmcobalt_v1) { - scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(1), - c->apm_threshold_vc); - scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(73), - 0x3b | c->apm_threshold_vc << 6); - } else if (msmcobalt_v2) { + if (c->apm_threshold_vc) clk_osm_write_reg(c, c->apm_threshold_vc, - SEQ_REG1_MSMCOBALT_V2); - } + SEQ_REG1_OFFSET); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(72), - c->apm_crossover_vc); + c->apm_crossover_vc); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(15), - c->apm_threshold_vc); + c->apm_threshold_vc); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(31), - c->apm_threshold_vc != 0 ? - c->apm_threshold_vc - 1 : 0xff); + c->apm_threshold_vc != 0 ? + c->apm_threshold_vc - 1 : 0xff); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(76), - 0x39 | c->apm_threshold_vc << 6); + 0x39 | c->apm_threshold_vc << 6); } } @@ -2298,11 +2295,12 @@ static int add_opp(struct clk_osm *c, struct device *dev) u32 uv; long rc; int j = 0; - unsigned long min_rate = c->c.fmax[0]; - unsigned long max_rate = c->c.fmax[c->c.num_fmax - 1]; + unsigned long min_rate = c->hw.init->rate_max[0]; + unsigned long max_rate = + c->hw.init->rate_max[c->hw.init->num_rate_max - 1]; while (1) { - rate = c->c.fmax[j++]; + rate = c->hw.init->rate_max[j++]; uv = find_voltage(c, rate); if (uv <= 0) { pr_warn("No voltage for %lu.\n", rate); @@ -2360,12 +2358,12 @@ static struct clk *logical_cpu_to_clk(int cpu) hwid = of_read_number(cell, of_n_addr_cells(cpu_node)); if ((hwid | pwrcl_clk.cpu_reg_mask) == pwrcl_clk.cpu_reg_mask) { - cpu_clk_map[cpu] = &pwrcl_clk.c; - return &pwrcl_clk.c; + cpu_clk_map[cpu] = pwrcl_clk.hw.clk; + return pwrcl_clk.hw.clk; } if ((hwid | perfcl_clk.cpu_reg_mask) == perfcl_clk.cpu_reg_mask) { - cpu_clk_map[cpu] = &perfcl_clk.c; - return &perfcl_clk.c; + cpu_clk_map[cpu] = perfcl_clk.hw.clk; + return perfcl_clk.hw.clk; } fail: @@ -2378,9 +2376,9 @@ static u64 clk_osm_get_cpu_cycle_counter(int cpu) u32 val; unsigned long flags; - if (logical_cpu_to_clk(cpu) == &pwrcl_clk.c) + if (logical_cpu_to_clk(cpu) == pwrcl_clk.hw.clk) c = &pwrcl_clk; - else if (logical_cpu_to_clk(cpu) == &perfcl_clk.c) + else if (logical_cpu_to_clk(cpu) == perfcl_clk.hw.clk) c = &perfcl_clk; else { pr_err("no clock device for CPU=%d\n", cpu); @@ -2409,11 +2407,11 @@ static void populate_opp_table(struct platform_device *pdev) int cpu; for_each_possible_cpu(cpu) { - if (logical_cpu_to_clk(cpu) == &pwrcl_clk.c) { + if (logical_cpu_to_clk(cpu) == pwrcl_clk.hw.clk) { WARN(add_opp(&pwrcl_clk, get_cpu_device(cpu)), "Failed to add OPP levels for power cluster\n"); } - if (logical_cpu_to_clk(cpu) == &perfcl_clk.c) { + if (logical_cpu_to_clk(cpu) == perfcl_clk.hw.clk) { WARN(add_opp(&perfcl_clk, get_cpu_device(cpu)), "Failed to add OPP levels for perf cluster\n"); } @@ -2456,15 +2454,11 @@ static int debugfs_set_wdog_trace(void *data, u64 val) struct clk_osm *c = data; int regval; - if (c->version >= VERSION_1P1) { - regval = clk_osm_read_reg(c, TRACE_CTRL); - regval = val ? regval | TRACE_CTRL_ENABLE_WDOG_STATUS : + regval = clk_osm_read_reg(c, TRACE_CTRL); + regval = val ? regval | TRACE_CTRL_ENABLE_WDOG_STATUS : regval & ~TRACE_CTRL_ENABLE_WDOG_STATUS; - clk_osm_write_reg(c, regval, TRACE_CTRL); - c->wdog_trace_en = val ? true : false; - } else { - pr_info("wdog status registers enabled by default\n"); - } + clk_osm_write_reg(c, regval, TRACE_CTRL); + c->wdog_trace_en = val ? true : false; return 0; } @@ -2618,7 +2612,7 @@ static int debugfs_set_trace_periodic_timer(void *data, u64 val) struct clk_osm *c = data; if (val < PERIODIC_TRACE_MIN_NS || val > PERIODIC_TRACE_MAX_NS) { - pr_err("supported periodic trace periods=%d-%ld ns\n", + pr_err("supported periodic trace periods=%d-%lld ns\n", PERIODIC_TRACE_MIN_NS, PERIODIC_TRACE_MAX_NS); return 0; } @@ -2760,7 +2754,7 @@ static void populate_debugfs_dir(struct clk_osm *c) } } - c->debugfs = debugfs_create_dir(c->c.dbg_name, osm_debugfs_base); + c->debugfs = debugfs_create_dir(c->hw.init->name, osm_debugfs_base); if (IS_ERR_OR_NULL(c->debugfs)) { pr_err("osm debugfs directory creation failed\n"); return; @@ -2977,31 +2971,60 @@ static int clk_osm_acd_init(struct clk_osm *c) static unsigned long init_rate = 300000000; static unsigned long osm_clk_init_rate = 200000000; +static unsigned long pwrcl_boot_rate = 1401600000; +static unsigned long perfcl_boot_rate = 1747200000; -static int cpu_clock_osm_driver_probe(struct platform_device *pdev) +static int clk_cpu_osm_driver_probe(struct platform_device *pdev) { - int rc, cpu; + int rc, cpu, i; int speedbin = 0, pvs_ver = 0; u32 pte_efuse; - char pwrclspeedbinstr[] = "qcom,pwrcl-speedbin0-v0"; + int num_clks = ARRAY_SIZE(osm_qcom_clk_hws); + struct clk *clk; + struct clk *ext_xo_clk, *ext_hmss_gpll0_clk_src; + struct device *dev = &pdev->dev; + struct clk_onecell_data *clk_data; char perfclspeedbinstr[] = "qcom,perfcl-speedbin0-v0"; + char pwrclspeedbinstr[] = "qcom,pwrcl-speedbin0-v0"; struct cpu_cycle_counter_cb cb = { .get_cpu_cycle_counter = clk_osm_get_cpu_cycle_counter, }; - if (of_find_compatible_node(NULL, NULL, - "qcom,cpu-clock-osm-msmcobalt-v1")) { - msmcobalt_v1 = true; - } else if (of_find_compatible_node(NULL, NULL, - "qcom,cpu-clock-osm-msmcobalt-v2")) { - msmcobalt_v2 = true; + /* + * Require the RPM-XO clock and GCC-HMSS-GPLL0 clocks to be registererd + * before OSM. + */ + ext_xo_clk = devm_clk_get(dev, "xo_a"); + if (IS_ERR(ext_xo_clk)) { + if (PTR_ERR(ext_xo_clk) != -EPROBE_DEFER) + dev_err(dev, "Unable to get xo clock\n"); + return PTR_ERR(ext_xo_clk); } + ext_hmss_gpll0_clk_src = devm_clk_get(dev, "aux_clk"); + if (IS_ERR(ext_hmss_gpll0_clk_src)) { + if (PTR_ERR(ext_hmss_gpll0_clk_src) != -EPROBE_DEFER) + dev_err(dev, "Unable to get aux_clk clock\n"); + return PTR_ERR(ext_hmss_gpll0_clk_src); + } + + clk_data = devm_kzalloc(&pdev->dev, sizeof(struct clk_onecell_data), + GFP_KERNEL); + if (!clk_data) + goto exit; + + clk_data->clks = devm_kzalloc(&pdev->dev, (num_clks * + sizeof(struct clk *)), GFP_KERNEL); + if (!clk_data->clks) + goto clk_err; + + clk_data->clk_num = num_clks; + rc = clk_osm_resources_init(pdev); if (rc) { if (rc != -EPROBE_DEFER) dev_err(&pdev->dev, "resources init failed, rc=%d\n", - rc); + rc); return rc; } @@ -3011,17 +3034,11 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) return rc; } - if ((pwrcl_clk.secure_init || perfcl_clk.secure_init) && - msmcobalt_v2) { - pr_err("unsupported configuration for msmcobalt v2\n"); - return -EINVAL; - } - if (pwrcl_clk.vbases[EFUSE_BASE]) { /* Multiple speed-bins are supported */ pte_efuse = readl_relaxed(pwrcl_clk.vbases[EFUSE_BASE]); speedbin = ((pte_efuse >> PWRCL_EFUSE_SHIFT) & - PWRCL_EFUSE_MASK); + PWRCL_EFUSE_MASK); snprintf(pwrclspeedbinstr, ARRAY_SIZE(pwrclspeedbinstr), "qcom,pwrcl-speedbin%d-v%d", speedbin, pvs_ver); } @@ -3029,8 +3046,7 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) dev_info(&pdev->dev, "using pwrcl speed bin %u and pvs_ver %d\n", speedbin, pvs_ver); - rc = clk_osm_get_lut(pdev, &pwrcl_clk, - pwrclspeedbinstr); + rc = clk_osm_get_lut(pdev, &pwrcl_clk, pwrclspeedbinstr); if (rc) { dev_err(&pdev->dev, "Unable to get OSM LUT for power cluster, rc=%d\n", rc); @@ -3041,7 +3057,7 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) /* Multiple speed-bins are supported */ pte_efuse = readl_relaxed(perfcl_clk.vbases[EFUSE_BASE]); speedbin = ((pte_efuse >> PERFCL_EFUSE_SHIFT) & - PERFCL_EFUSE_MASK); + PERFCL_EFUSE_MASK); snprintf(perfclspeedbinstr, ARRAY_SIZE(perfclspeedbinstr), "qcom,perfcl-speedbin%d-v%d", speedbin, pvs_ver); } @@ -3074,13 +3090,14 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) return rc; } - rc = clk_osm_resolve_crossover_corners(&pwrcl_clk, pdev); + rc = clk_osm_resolve_crossover_corners(&pwrcl_clk, pdev, NULL); if (rc) dev_info(&pdev->dev, "No APM crossover corner programmed\n"); - rc = clk_osm_resolve_crossover_corners(&perfcl_clk, pdev); + rc = clk_osm_resolve_crossover_corners(&perfcl_clk, pdev, + "qcom,perfcl-apcs-mem-acc-threshold-voltage"); if (rc) - dev_info(&pdev->dev, "No APM crossover corner programmed\n"); + dev_info(&pdev->dev, "No MEM-ACC crossover corner programmed\n"); clk_osm_setup_cycle_counters(&pwrcl_clk); clk_osm_setup_cycle_counters(&perfcl_clk); @@ -3146,11 +3163,7 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) if (rc) pr_err("Debug IRQ not set for perfcl\n"); - clk_osm_setup_osm_was(&pwrcl_clk); - clk_osm_setup_osm_was(&perfcl_clk); - - if (of_property_read_bool(pdev->dev.of_node, - "qcom,osm-pll-setup")) { + if (of_property_read_bool(pdev->dev.of_node, "qcom,osm-pll-setup")) { clk_osm_setup_cluster_pll(&pwrcl_clk); clk_osm_setup_cluster_pll(&perfcl_clk); } @@ -3176,12 +3189,22 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) atomic_notifier_chain_register(&panic_notifier_list, &perfcl_clk.panic_notifier); - rc = of_msm_clock_register(pdev->dev.of_node, cpu_clocks_osm, - ARRAY_SIZE(cpu_clocks_osm)); + /* Register OSM pwr and perf clocks with Clock Framework */ + for (i = 0; i < num_clks; i++) { + clk = devm_clk_register(&pdev->dev, osm_qcom_clk_hws[i]); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "Unable to register CPU clock at index %d\n", + i); + return PTR_ERR(clk); + } + clk_data->clks[i] = clk; + } + + rc = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, + clk_data); if (rc) { - dev_err(&pdev->dev, "Unable to register CPU clocks, rc=%d\n", - rc); - return rc; + dev_err(&pdev->dev, "Unable to register CPU clocks\n"); + goto provider_err; } /* @@ -3189,15 +3212,15 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) * frequency before enabling OSM. LUT index 0 is always sourced from * this clock. */ - rc = clk_set_rate(&sys_apcsaux_clk_gcc.c, init_rate); + rc = clk_set_rate(sys_apcsaux_clk_gcc.hw.clk, init_rate); if (rc) { dev_err(&pdev->dev, "Unable to set init rate on hmss_gpll0, rc=%d\n", rc); return rc; } - clk_prepare_enable(&sys_apcsaux_clk_gcc.c); + clk_prepare_enable(sys_apcsaux_clk_gcc.hw.clk); - rc = clk_set_rate(&osm_clk_src.c, osm_clk_init_rate); + rc = clk_set_rate(osm_clk_src.clkr.hw.clk, osm_clk_init_rate); if (rc) { dev_err(&pdev->dev, "Unable to set init rate on osm_clk, rc=%d\n", rc); @@ -3205,14 +3228,14 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) } /* Make sure index zero is selected */ - rc = clk_set_rate(&pwrcl_clk.c, init_rate); + rc = clk_set_rate(pwrcl_clk.hw.clk, init_rate); if (rc) { dev_err(&pdev->dev, "Unable to set init rate on pwr cluster, rc=%d\n", rc); goto exit2; } - rc = clk_set_rate(&perfcl_clk.c, init_rate); + rc = clk_set_rate(perfcl_clk.hw.clk, init_rate); if (rc) { dev_err(&pdev->dev, "Unable to set init rate on perf cluster, rc=%d\n", rc); @@ -3228,27 +3251,20 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) } /* Set final boot rate */ - rc = clk_set_rate(&pwrcl_clk.c, msmcobalt_v1 ? - MSMCOBALTV1_PWRCL_BOOT_RATE : - MSMCOBALTV2_PWRCL_BOOT_RATE); + rc = clk_set_rate(pwrcl_clk.hw.clk, pwrcl_boot_rate); if (rc) { dev_err(&pdev->dev, "Unable to set boot rate on pwr cluster, rc=%d\n", rc); goto exit2; } - rc = clk_set_rate(&perfcl_clk.c, msmcobalt_v1 ? - MSMCOBALTV1_PERFCL_BOOT_RATE : - MSMCOBALTV2_PERFCL_BOOT_RATE); + rc = clk_set_rate(perfcl_clk.hw.clk, perfcl_boot_rate); if (rc) { dev_err(&pdev->dev, "Unable to set boot rate on perf cluster, rc=%d\n", rc); goto exit2; } - pwrcl_clk.version = clk_osm_read_reg(&pwrcl_clk, VERSION_REG); - perfcl_clk.version = clk_osm_read_reg(&perfcl_clk, VERSION_REG); - populate_opp_table(pdev); populate_debugfs_dir(&pwrcl_clk); populate_debugfs_dir(&perfcl_clk); @@ -3263,39 +3279,42 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) return 0; exit2: - clk_disable_unprepare(&sys_apcsaux_clk_gcc.c); + clk_disable_unprepare(sys_apcsaux_clk_gcc.hw.clk); +provider_err: + if (clk_data) + devm_kfree(&pdev->dev, clk_data->clks); +clk_err: + devm_kfree(&pdev->dev, clk_data); exit: - dev_err(&pdev->dev, "OSM driver failed to initialize, rc=%d\n", - rc); + dev_err(&pdev->dev, "OSM driver failed to initialize, rc=%d\n", rc); panic("Unable to Setup OSM"); } static const struct of_device_id match_table[] = { - { .compatible = "qcom,cpu-clock-osm-msmcobalt-v1" }, - { .compatible = "qcom,cpu-clock-osm-msmcobalt-v2" }, + { .compatible = "qcom,clk-cpu-osm" }, {} }; -static struct platform_driver cpu_clock_osm_driver = { - .probe = cpu_clock_osm_driver_probe, +static struct platform_driver clk_cpu_osm_driver = { + .probe = clk_cpu_osm_driver_probe, .driver = { - .name = "cpu-clock-osm", + .name = "clk-cpu-osm", .of_match_table = match_table, .owner = THIS_MODULE, }, }; -static int __init cpu_clock_osm_init(void) +static int __init clk_cpu_osm_init(void) { - return platform_driver_register(&cpu_clock_osm_driver); + return platform_driver_register(&clk_cpu_osm_driver); } -arch_initcall(cpu_clock_osm_init); +arch_initcall(clk_cpu_osm_init); -static void __exit cpu_clock_osm_exit(void) +static void __exit clk_cpu_osm_exit(void) { - platform_driver_unregister(&cpu_clock_osm_driver); + platform_driver_unregister(&clk_cpu_osm_driver); } -module_exit(cpu_clock_osm_exit); +module_exit(clk_cpu_osm_exit); MODULE_DESCRIPTION("CPU clock driver for OSM"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h index 841367eb21ff..76c010970b51 100644 --- a/drivers/clk/qcom/common.h +++ b/drivers/clk/qcom/common.h @@ -137,6 +137,7 @@ struct clk_debug_mux { }; #define BM(msb, lsb) (((((uint32_t)-1) << (31-msb)) >> (31-msb+lsb)) << lsb) +#define BVAL(msb, lsb, val) (((val) << lsb) & BM(msb, lsb)) #define to_clk_measure(_hw) container_of((_hw), struct clk_debug_mux, hw) diff --git a/include/dt-bindings/clock/qcom,cpu-osm.h b/include/dt-bindings/clock/qcom,cpu-osm.h new file mode 100644 index 000000000000..71745fab287a --- /dev/null +++ b/include/dt-bindings/clock/qcom,cpu-osm.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2016, 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. + */ + +#ifndef _DT_BINDINGS_CLK_MSM_CPU_OSM_H +#define _DT_BINDINGS_CLK_MSM_CPU_OSM_H + +/* CPU clock IDs */ +#define SYS_APCSAUX_CLK_GCC 0 +#define PWRCL_CLK 1 +#define PERFCL_CLK 2 +#define OSM_CLK_SRC 3 + +#endif From 20da6a6d279a7ecf6d6df1dc4218d390f376e2c8 Mon Sep 17 00:00:00 2001 From: ansharma Date: Sat, 17 Dec 2016 19:53:02 +0530 Subject: [PATCH 33/73] leds: qpnp-wled: Update WLED config Update WLED configuration to enable HVG_PULL_SWITCH bit to temporarily pull up Hvgate with larger switch(for pm2falcon) and enable DEBOUNCE_BYPASS_ILIM bit to remove debouncing for Ilim. This guarantee stable operation of WLED. CRs-Fixed: 1102641 Change-Id: I39a1266f4158e71238f374b6cba49e1a8c2b1a3b Signed-off-by: ansharma --- drivers/leds/leds-qpnp-wled.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/leds/leds-qpnp-wled.c b/drivers/leds/leds-qpnp-wled.c index 85b1133df4f5..e0b39df63ab7 100644 --- a/drivers/leds/leds-qpnp-wled.c +++ b/drivers/leds/leds-qpnp-wled.c @@ -108,7 +108,14 @@ #define QPNP_WLED_SWITCH_FREQ_1600_KHZ 1600 #define QPNP_WLED_SWITCH_FREQ_OVERWRITE 0x80 #define QPNP_WLED_OVP_MASK GENMASK(1, 0) -#define QPNP_WLED_TEST4_EN_VREF_UP 0x32 +#define QPNP_WLED_TEST4_EN_DEB_BYPASS_ILIM_BIT BIT(6) +#define QPNP_WLED_TEST4_EN_SH_FOR_SS_BIT BIT(5) +#define QPNP_WLED_TEST4_EN_CLAMP_BIT BIT(4) +#define QPNP_WLED_TEST4_EN_SOFT_START_BIT BIT(1) +#define QPNP_WLED_TEST4_EN_VREF_UP \ + (QPNP_WLED_TEST4_EN_SH_FOR_SS_BIT | \ + QPNP_WLED_TEST4_EN_CLAMP_BIT | \ + QPNP_WLED_TEST4_EN_SOFT_START_BIT) #define QPNP_WLED_TEST4_EN_IIND_UP 0x1 /* sink registers */ @@ -167,6 +174,7 @@ #define QPNP_WLED_SINK_TEST5_HYB 0x14 #define QPNP_WLED_SINK_TEST5_DIG 0x1E +#define QPNP_WLED_SINK_TEST5_HVG_PULL_STR_BIT BIT(3) #define QPNP_WLED_SWITCH_FREQ_800_KHZ_CODE 0x0B #define QPNP_WLED_SWITCH_FREQ_1600_KHZ_CODE 0x05 @@ -1005,7 +1013,8 @@ static int qpnp_wled_set_disp(struct qpnp_wled *wled, u16 base_addr) /* * enable VREF_UP to avoid false ovp on low brightness for LCD */ - reg = QPNP_WLED_TEST4_EN_VREF_UP; + reg = QPNP_WLED_TEST4_EN_VREF_UP + | QPNP_WLED_TEST4_EN_DEB_BYPASS_ILIM_BIT; rc = qpnp_wled_sec_write_reg(wled, QPNP_WLED_TEST4_REG(base_addr), reg); if (rc) @@ -1520,10 +1529,13 @@ static int qpnp_wled_config(struct qpnp_wled *wled) return rc; /* Configure TEST5 register */ - if (wled->dim_mode == QPNP_WLED_DIM_DIGITAL) + if (wled->dim_mode == QPNP_WLED_DIM_DIGITAL) { reg = QPNP_WLED_SINK_TEST5_DIG; - else + } else { reg = QPNP_WLED_SINK_TEST5_HYB; + if (wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) + reg |= QPNP_WLED_SINK_TEST5_HVG_PULL_STR_BIT; + } rc = qpnp_wled_sec_write_reg(wled, QPNP_WLED_SINK_TEST5_REG(wled->sink_base), reg); From 9ae68a63d8eab98f39a184995894805c1fa5cda0 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Sat, 26 Nov 2016 15:40:13 +0530 Subject: [PATCH 34/73] defconfig: msm: Add support for CPU OSM clock CPU OSM clock is required to be enabled for cpu to be able to scale frequencies for the CPU. Change-Id: I5680dc5333c9664e1316c29a91e29231f15eb4f1 Signed-off-by: Taniya Das --- arch/arm/configs/msmfalcon_defconfig | 1 + arch/arm64/configs/msmfalcon-perf_defconfig | 1 + arch/arm64/configs/msmfalcon_defconfig | 1 + 3 files changed, 3 insertions(+) diff --git a/arch/arm/configs/msmfalcon_defconfig b/arch/arm/configs/msmfalcon_defconfig index 058a1b3ddd24..ae0ccfe902c9 100644 --- a/arch/arm/configs/msmfalcon_defconfig +++ b/arch/arm/configs/msmfalcon_defconfig @@ -482,6 +482,7 @@ CONFIG_USB_BAM=y CONFIG_QCOM_CLK_SMD_RPM=y CONFIG_MSM_GPUCC_FALCON=y CONFIG_MSM_MMCC_FALCON=y +CONFIG_CLOCK_CPU_OSM=y CONFIG_QCOM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y CONFIG_ARM_SMMU=y diff --git a/arch/arm64/configs/msmfalcon-perf_defconfig b/arch/arm64/configs/msmfalcon-perf_defconfig index 6f1e987e6d0c..56f31336128c 100644 --- a/arch/arm64/configs/msmfalcon-perf_defconfig +++ b/arch/arm64/configs/msmfalcon-perf_defconfig @@ -504,6 +504,7 @@ CONFIG_USB_BAM=y CONFIG_QCOM_CLK_SMD_RPM=y CONFIG_MSM_GPUCC_FALCON=y CONFIG_MSM_MMCC_FALCON=y +CONFIG_CLOCK_CPU_OSM=y CONFIG_QCOM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y CONFIG_IOMMU_IO_PGTABLE_FAST=y diff --git a/arch/arm64/configs/msmfalcon_defconfig b/arch/arm64/configs/msmfalcon_defconfig index c83e8427389e..431a474e7694 100644 --- a/arch/arm64/configs/msmfalcon_defconfig +++ b/arch/arm64/configs/msmfalcon_defconfig @@ -513,6 +513,7 @@ CONFIG_USB_BAM=y CONFIG_QCOM_CLK_SMD_RPM=y CONFIG_MSM_GPUCC_FALCON=y CONFIG_MSM_MMCC_FALCON=y +CONFIG_CLOCK_CPU_OSM=y CONFIG_QCOM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y CONFIG_IOMMU_IO_PGTABLE_FAST=y From d8d0e55ed104252f0295767d5e2e026c93404870 Mon Sep 17 00:00:00 2001 From: Michael Turquette Date: Thu, 17 Nov 2016 18:47:30 +0530 Subject: [PATCH 35/73] clk: introduce CLK_ENABLE_HAND_OFF flag Some clocks are critical to system operation (e.g. cpu, memory, etc) and should not be gated until a driver that knows best claims such a clock and expressly gates that clock through the normal clk.h api. The typical way to handle this is for the clk driver or some other early code to call clk_prepare_enable on this important clock as soon as it is registered and before the clk_disable_unused garbage collector kicks in. This patch introduces a formal way to handle this scenario that is provided by the clk framework. Clk driver authors can set the CLK_ENABLE_HAND_OFF flag in their clk data, which will cause the clk to be enabled in clk_register(). Then when the first clk consumer driver comes along and calls clk_get() & clk_prepare_enable(), the reference counts taken during clk registration are transfered (or handed off) to the clk consumer. At this point handling the clk is the same as any other clock which as not set the new CLK_ENABLE_HAND_OFF flag. In fact no changes to any clock consumer driver are needed for this to work. Change-Id: Ib5247f6bceb1f555c03103f061af089755b2de62 Signed-off-by: Michael Turquette Patch-mainline: patchwork.kernel.org @ 02/11/16, 9:19 Signed-off-by: Taniya Das --- drivers/clk/clk.c | 57 ++++++++++++++++++++++++++++++++++-- include/linux/clk-provider.h | 3 ++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index c4aec62d1014..55b44559bae4 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -71,6 +71,8 @@ struct clk_core { bool orphan; unsigned int enable_count; unsigned int prepare_count; + bool need_handoff_enable; + bool need_handoff_prepare; unsigned long min_rate; unsigned long max_rate; unsigned long accuracy; @@ -925,15 +927,29 @@ static int clk_core_prepare(struct clk_core *core) */ int clk_prepare(struct clk *clk) { - int ret; + int ret = 0; if (!clk) return 0; + /* + * setting CLK_ENABLE_HAND_OFF flag triggers this conditional + * + * need_handoff_prepare implies this clk was already prepared by + * __clk_init. now we have a proper user, so unset the flag in our + * internal bookkeeping. See CLK_ENABLE_HAND_OFF flag in clk-provider.h + * for details. + */ + if (clk->core->need_handoff_prepare) { + clk->core->need_handoff_prepare = false; + goto out; + } + clk_prepare_lock(); ret = clk_core_prepare(clk->core); clk_prepare_unlock(); +out: return ret; } EXPORT_SYMBOL_GPL(clk_prepare); @@ -1040,15 +1056,29 @@ static int clk_core_enable(struct clk_core *core) int clk_enable(struct clk *clk) { unsigned long flags; - int ret; + int ret = 0; if (!clk) return 0; + /* + * setting CLK_ENABLE_HAND_OFF flag triggers this conditional + * + * need_handoff_enable implies this clk was already enabled by + * __clk_init. now we have a proper user, so unset the flag in our + * internal bookkeeping. See CLK_ENABLE_HAND_OFF flag in clk-provider.h + * for details. + */ + if (clk->core->need_handoff_enable) { + clk->core->need_handoff_enable = false; + goto out; + } + flags = clk_enable_lock(); ret = clk_core_enable(clk->core); clk_enable_unlock(flags); +out: return ret; } EXPORT_SYMBOL_GPL(clk_enable); @@ -3146,6 +3176,29 @@ static int __clk_init(struct device *dev, struct clk *clk_user) clk_enable_unlock(flags); } + /* + * enable clocks with the CLK_ENABLE_HAND_OFF flag set + * + * This flag causes the framework to enable the clock at registration + * time, which is sometimes necessary for clocks that would cause a + * system crash when gated (e.g. cpu, memory, etc). The prepare_count + * is migrated over to the first clk consumer to call clk_prepare(). + * Similarly the clk's enable_count is migrated to the first consumer + * to call clk_enable(). + */ + if (core->flags & CLK_ENABLE_HAND_OFF) { + unsigned long flags; + + core->need_handoff_prepare = true; + core->need_handoff_enable = true; + ret = clk_core_prepare(core); + if (ret) + goto out; + flags = clk_enable_lock(); + clk_core_enable(core); + clk_enable_unlock(flags); + } + kref_init(&core->ref); out: clk_prepare_unlock(); diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 744167a9ca8b..f91991b97888 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -33,6 +33,9 @@ #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */ #define CLK_RECALC_NEW_RATES BIT(9) /* recalc rates after notifications */ #define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */ +#define CLK_ENABLE_HAND_OFF BIT(12) /* enable clock when registered. + hand-off enable_count & prepare_count + to first consumer that enables clk */ #define CLK_IS_MEASURE BIT(14) /* measure clock */ struct clk; From 44aa223a3e4ab5c3ea59e916899a3695b0dac06d Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Sat, 3 Dec 2016 20:35:23 +0530 Subject: [PATCH 36/73] clk: move check for CLK_ENABLE_HAND_OFF at unused tree The commit 04a0136aeea5 ("clk: introduce CLK_ENABLE_HAND_OFF flag") assumes that the first time clock client calls a clk_prepare & clk_enable, the clocks from that point of time could be on their own. But there could be use cases which could have impacts due to this handling. Moving the handoff counts for prepare and enable at unused tree level. Change-Id: I7d527571c2eb4d53d58d82126989bd673de12e2d Signed-off-by: Taniya Das --- drivers/clk/clk.c | 78 +++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 55b44559bae4..ac815c6dbac0 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -197,6 +197,19 @@ static void clk_unprepare_unused_subtree(struct clk_core *core) hlist_for_each_entry(child, &core->children, child_node) clk_unprepare_unused_subtree(child); + /* + * setting CLK_ENABLE_HAND_OFF flag triggers this conditional + * + * need_handoff_prepare implies this clk was already prepared by + * __clk_init. now we have a proper user, so unset the flag in our + * internal bookkeeping. See CLK_ENABLE_HAND_OFF flag in clk-provider.h + * for details. + */ + if (core->need_handoff_prepare) { + core->need_handoff_prepare = false; + core->prepare_count--; + } + if (core->prepare_count) return; @@ -223,6 +236,19 @@ static void clk_disable_unused_subtree(struct clk_core *core) hlist_for_each_entry(child, &core->children, child_node) clk_disable_unused_subtree(child); + /* + * setting CLK_ENABLE_HAND_OFF flag triggers this conditional + * + * need_handoff_enable implies this clk was already enabled by + * __clk_init. now we have a proper user, so unset the flag in our + * internal bookkeeping. See CLK_ENABLE_HAND_OFF flag in clk-provider.h + * for details. + */ + if (core->need_handoff_enable) { + core->need_handoff_enable = false; + core->enable_count--; + } + flags = clk_enable_lock(); if (core->enable_count) @@ -932,24 +958,10 @@ int clk_prepare(struct clk *clk) if (!clk) return 0; - /* - * setting CLK_ENABLE_HAND_OFF flag triggers this conditional - * - * need_handoff_prepare implies this clk was already prepared by - * __clk_init. now we have a proper user, so unset the flag in our - * internal bookkeeping. See CLK_ENABLE_HAND_OFF flag in clk-provider.h - * for details. - */ - if (clk->core->need_handoff_prepare) { - clk->core->need_handoff_prepare = false; - goto out; - } - clk_prepare_lock(); ret = clk_core_prepare(clk->core); clk_prepare_unlock(); -out: return ret; } EXPORT_SYMBOL_GPL(clk_prepare); @@ -1061,24 +1073,10 @@ int clk_enable(struct clk *clk) if (!clk) return 0; - /* - * setting CLK_ENABLE_HAND_OFF flag triggers this conditional - * - * need_handoff_enable implies this clk was already enabled by - * __clk_init. now we have a proper user, so unset the flag in our - * internal bookkeeping. See CLK_ENABLE_HAND_OFF flag in clk-provider.h - * for details. - */ - if (clk->core->need_handoff_enable) { - clk->core->need_handoff_enable = false; - goto out; - } - flags = clk_enable_lock(); ret = clk_core_enable(clk->core); clk_enable_unlock(flags); -out: return ret; } EXPORT_SYMBOL_GPL(clk_enable); @@ -3189,14 +3187,22 @@ static int __clk_init(struct device *dev, struct clk *clk_user) if (core->flags & CLK_ENABLE_HAND_OFF) { unsigned long flags; - core->need_handoff_prepare = true; - core->need_handoff_enable = true; - ret = clk_core_prepare(core); - if (ret) - goto out; - flags = clk_enable_lock(); - clk_core_enable(core); - clk_enable_unlock(flags); + /* + * Few clocks might have hardware gating which would be required + * to be ON before prepare/enabling the clocks. So check if the + * clock has been turned ON earlier and we should + * prepare/enable those clocks. + */ + if (clk_core_is_enabled(core)) { + core->need_handoff_prepare = true; + core->need_handoff_enable = true; + ret = clk_core_prepare(core); + if (ret) + goto out; + flags = clk_enable_lock(); + clk_core_enable(core); + clk_enable_unlock(flags); + } } kref_init(&core->ref); From 3a55a2de326d10c5e02570d639891dfafd75f80d Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Wed, 21 Dec 2016 14:21:39 +0530 Subject: [PATCH 37/73] usb: gadget: u_data_ipa: Fix condition check for IPA pipes updation Only RmNet and DPL need to update their IPA pipes during ipa_data_connect_work context. Add this check before updation of the pipes. Also fix usage of spinlock to avoid potential device crash. Change-Id: I45d13b40fab9bf6686277c0c26a07668410cdfb2 Signed-off-by: Ajay Agarwal --- drivers/usb/gadget/function/u_data_ipa.c | 32 ++++++++++++++++-------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/function/u_data_ipa.c b/drivers/usb/gadget/function/u_data_ipa.c index cc9e5f3652d4..f2cba8f1733b 100644 --- a/drivers/usb/gadget/function/u_data_ipa.c +++ b/drivers/usb/gadget/function/u_data_ipa.c @@ -396,7 +396,7 @@ static void ipa_data_connect_work(struct work_struct *w) unsigned long flags; bool is_ipa_disconnected = true; - pr_debug("%s: Connect workqueue started", __func__); + pr_debug("%s: Connect workqueue started\n", __func__); spin_lock_irqsave(&port->port_lock, flags); @@ -446,8 +446,14 @@ static void ipa_data_connect_work(struct work_struct *w) spin_unlock_irqrestore(&port->port_lock, flags); usb_bam_alloc_fifos(port->usb_bam_type, port->src_connection_idx); - spin_lock_irqsave(&port->port_lock, flags); + if (!port->port_usb || port->rx_req == NULL) { + spin_unlock_irqrestore(&port->port_lock, flags); + pr_err("%s: port_usb is NULL, or rx_req cleaned\n", + __func__); + goto out; + } + sps_params = MSM_SPS_MODE | MSM_DISABLE_WB | MSM_PRODUCER | port->src_pipe_idx; port->rx_req->length = 32*1024; @@ -459,8 +465,6 @@ static void ipa_data_connect_work(struct work_struct *w) if (ret) { pr_err("msm_ep_config() failed for OUT EP\n"); spin_unlock_irqrestore(&port->port_lock, flags); - usb_bam_free_fifos(port->usb_bam_type, - port->src_connection_idx); goto out; } } @@ -470,6 +474,12 @@ static void ipa_data_connect_work(struct work_struct *w) usb_bam_alloc_fifos(port->usb_bam_type, port->dst_connection_idx); spin_lock_irqsave(&port->port_lock, flags); + if (!port->port_usb || port->tx_req == NULL) { + spin_unlock_irqrestore(&port->port_lock, flags); + pr_err("%s: port_usb is NULL, or tx_req cleaned\n", + __func__); + goto unconfig_msm_ep_out; + } sps_params = MSM_SPS_MODE | MSM_DISABLE_WB | port->dst_pipe_idx; port->tx_req->length = 32*1024; @@ -538,6 +548,7 @@ static void ipa_data_connect_work(struct work_struct *w) spin_unlock_irqrestore(&port->port_lock, flags); goto disconnect_usb_bam_ipa_out; } + gport->ipa_consumer_ep = port->ipa_params.ipa_cons_ep_idx; } @@ -572,6 +583,7 @@ static void ipa_data_connect_work(struct work_struct *w) goto disconnect_usb_bam_ipa_out; } spin_lock_irqsave(&port->port_lock, flags); + is_ipa_disconnected = false; /* check if USB cable is disconnected or not */ if (!port->port_usb) { pr_debug("%s:%d: cable is disconnected.\n", @@ -581,7 +593,6 @@ static void ipa_data_connect_work(struct work_struct *w) } gport->ipa_producer_ep = port->ipa_params.ipa_prod_ep_idx; - is_ipa_disconnected = false; } spin_unlock_irqrestore(&port->port_lock, flags); @@ -612,7 +623,8 @@ static void ipa_data_connect_work(struct work_struct *w) return; } atomic_set(&port->pipe_connect_notified, 1); - } else { + } else if (port->func_type == USB_IPA_FUNC_RMNET || + port->func_type == USB_IPA_FUNC_DPL) { /* For RmNet and DPL need to update_ipa_pipes to qti */ enum qti_port_type qti_port_type = port->func_type == USB_IPA_FUNC_RMNET ? QTI_PORT_RMNET : QTI_PORT_DPL; @@ -675,13 +687,13 @@ unconfig_msm_ep_out: port->dst_connection_idx); spin_lock_irqsave(&port->port_lock, flags); /* check if USB cable is disconnected or not */ - if (port->port_usb && gport->out) { + if (port->port_usb && gport->out) msm_ep_unconfig(port->port_usb->out); - usb_bam_free_fifos(port->usb_bam_type, - port->src_connection_idx); - } spin_unlock_irqrestore(&port->port_lock, flags); out: + if (gport->out) + usb_bam_free_fifos(port->usb_bam_type, + port->src_connection_idx); spin_lock_irqsave(&port->port_lock, flags); port->is_connected = false; spin_unlock_irqrestore(&port->port_lock, flags); From 647124958fea6b0a6f29a073ce819c873eaadb4c Mon Sep 17 00:00:00 2001 From: Jin Fu Date: Tue, 13 Dec 2016 16:19:22 +0800 Subject: [PATCH 38/73] ARM: dts: msm: Add support for home hard key at QRD8998HB Configure the button under the display panel as a home key for QRD8998HB. CRs-Fixed: 1103939 Change-Id: I03e4a8e10452ef53d8e35e7cee44bdf51f53483b Signed-off-by: Jin Fu --- arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi index f60fd10b92f8..766d99ae5cf3 100644 --- a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi @@ -119,6 +119,15 @@ input-name = "gpio-keys"; status = "okay"; + home { + label = "home"; + gpios = <&pm8998_gpios 5 0x1>; + linux,input-type = <1>; + linux,code = <102>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + vol_up { label = "volume_up"; gpios = <&pm8998_gpios 6 0x1>; From 7227e027350242a33353f9b6dd089e79f24588d5 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 28 Nov 2016 23:04:47 +0530 Subject: [PATCH 39/73] ASoC: msm: add support for WCD interrupt config via LPI TLMM Configure LPI interrupt registers inorder to setup WCD interrupt triggered via LPI TLMM as direct apps interrupt. Change-Id: Ifd41990058f8bbce8ba488770ffbfcd9b6067ad6 Signed-off-by: Laxminath Kasam --- sound/soc/msm/msmfalcon-common.c | 4 ++ sound/soc/msm/msmfalcon-external.c | 76 ++++++++++++++++++++++++++++++ sound/soc/msm/msmfalcon-external.h | 4 ++ 3 files changed, 84 insertions(+) diff --git a/sound/soc/msm/msmfalcon-common.c b/sound/soc/msm/msmfalcon-common.c index e705fa8faf73..013127c48984 100644 --- a/sound/soc/msm/msmfalcon-common.c +++ b/sound/soc/msm/msmfalcon-common.c @@ -2797,6 +2797,8 @@ err: pdata->hph_en0_gpio = 0; } devm_kfree(&pdev->dev, pdata); + if (pdata->snd_card_val != INT_SND_CARD) + msm_ext_cdc_deinit(); return ret; } @@ -2807,6 +2809,8 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) if (pdata->snd_card_val == INT_SND_CARD) mutex_destroy(&pdata->cdc_int_mclk0_mutex); + else + msm_ext_cdc_deinit(); msm_free_auxdev_mem(pdev); gpio_free(pdata->us_euro_gpio); diff --git a/sound/soc/msm/msmfalcon-external.c b/sound/soc/msm/msmfalcon-external.c index 3934c50c48a9..ef0b23e2e51e 100644 --- a/sound/soc/msm/msmfalcon-external.c +++ b/sound/soc/msm/msmfalcon-external.c @@ -35,6 +35,22 @@ #define CODEC_EXT_CLK_RATE 9600000 #define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define TLMM_CENTER_MPM_WAKEUP_INT_EN_0 0x03596000 +#define LPI_GPIO_22_WAKEUP_VAL 0x00000002 + +#define TLMM_LPI_DIR_CONN_INTR1_CFG_APPS 0x0359D004 +#define LPI_GPIO_22_INTR1_CFG_VAL 0x01 +#define LPI_GPIO_22_INTR1_CFG_MASK 0x03 + +#define TLMM_LPI_GPIO_INTR_CFG1 0x0359B004 +#define LPI_GPIO_INTR_CFG1_VAL 0x00000113 + +#define TLMM_LPI_GPIO22_CFG 0x15078040 +#define LPI_GPIO22_CFG_VAL 0x0000009 + +#define TLMM_LPI_GPIO22_INOUT 0x15078044 +#define LPI_GPIO22_INOUT_VAL 0x00000000 + #define WSA8810_NAME_1 "wsa881x.20170211" #define WSA8810_NAME_2 "wsa881x.20170212" @@ -50,6 +66,16 @@ struct msm_asoc_wcd93xx_codec { static struct msm_asoc_wcd93xx_codec msm_codec_fn; static struct platform_device *spdev; +struct msm_snd_interrupt { + void __iomem *mpm_wakeup; + void __iomem *intr1_cfg_apps; + void __iomem *lpi_gpio_intr_cfg; + void __iomem *lpi_gpio_cfg; + void __iomem *lpi_gpio_inout; +}; + +static struct msm_snd_interrupt msm_snd_intr_lpi; + static bool is_initial_boot; static void *def_ext_mbhc_cal(void); @@ -1193,6 +1219,27 @@ static void msm_afe_clear_config(void) afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); } +static void msm_snd_interrupt_config(void) +{ + int val; + + val = ioread32(msm_snd_intr_lpi.mpm_wakeup); + val |= LPI_GPIO_22_WAKEUP_VAL; + iowrite32(val, msm_snd_intr_lpi.mpm_wakeup); + + val = ioread32(msm_snd_intr_lpi.intr1_cfg_apps); + val &= ~(LPI_GPIO_22_INTR1_CFG_MASK); + val |= LPI_GPIO_22_INTR1_CFG_VAL; + iowrite32(val, msm_snd_intr_lpi.intr1_cfg_apps); + + iowrite32(LPI_GPIO_INTR_CFG1_VAL, + msm_snd_intr_lpi.lpi_gpio_intr_cfg); + iowrite32(LPI_GPIO22_CFG_VAL, + msm_snd_intr_lpi.lpi_gpio_cfg); + iowrite32(LPI_GPIO22_INOUT_VAL, + msm_snd_intr_lpi.lpi_gpio_inout); +} + static int msm_adsp_power_up_config(struct snd_soc_codec *codec) { int ret = 0; @@ -1221,6 +1268,7 @@ static int msm_adsp_power_up_config(struct snd_soc_codec *codec) ret = -ETIMEDOUT; goto err_fail; } + msm_snd_interrupt_config(); ret = msm_afe_set_config(codec); if (ret) @@ -1759,7 +1807,35 @@ int msm_ext_cdc_init(struct platform_device *pdev, ret); ret = 0; } + msm_snd_intr_lpi.mpm_wakeup = + ioremap(TLMM_CENTER_MPM_WAKEUP_INT_EN_0, 4); + msm_snd_intr_lpi.intr1_cfg_apps = + ioremap(TLMM_LPI_DIR_CONN_INTR1_CFG_APPS, 4); + msm_snd_intr_lpi.lpi_gpio_intr_cfg = + ioremap(TLMM_LPI_GPIO_INTR_CFG1, 4); + msm_snd_intr_lpi.lpi_gpio_cfg = + ioremap(TLMM_LPI_GPIO22_CFG, 4); + msm_snd_intr_lpi.lpi_gpio_inout = + ioremap(TLMM_LPI_GPIO22_INOUT, 4); err: return ret; } EXPORT_SYMBOL(msm_ext_cdc_init); + +/** + * msm_ext_cdc_deinit - external codec machine specific deinit. + */ +void msm_ext_cdc_deinit(void) +{ + if (msm_snd_intr_lpi.mpm_wakeup) + iounmap(msm_snd_intr_lpi.mpm_wakeup); + if (msm_snd_intr_lpi.intr1_cfg_apps) + iounmap(msm_snd_intr_lpi.intr1_cfg_apps); + if (msm_snd_intr_lpi.lpi_gpio_intr_cfg) + iounmap(msm_snd_intr_lpi.lpi_gpio_intr_cfg); + if (msm_snd_intr_lpi.lpi_gpio_cfg) + iounmap(msm_snd_intr_lpi.lpi_gpio_cfg); + if (msm_snd_intr_lpi.lpi_gpio_inout) + iounmap(msm_snd_intr_lpi.lpi_gpio_inout); +} +EXPORT_SYMBOL(msm_ext_cdc_deinit); diff --git a/sound/soc/msm/msmfalcon-external.h b/sound/soc/msm/msmfalcon-external.h index 654cb70b9c84..fc82b628dfac 100644 --- a/sound/soc/msm/msmfalcon-external.h +++ b/sound/soc/msm/msmfalcon-external.h @@ -34,6 +34,7 @@ int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, int msm_ext_cdc_init(struct platform_device *, struct msm_asoc_mach_data *, struct snd_soc_card **, struct wcd_mbhc_config *); void msm_ext_register_audio_notifier(void); +void msm_ext_cdc_deinit(void); #else inline int msm_ext_cdc_init(struct platform_device *pdev, struct msm_asoc_mach_data *pdata, @@ -46,5 +47,8 @@ inline int msm_ext_cdc_init(struct platform_device *pdev, inline void msm_ext_register_audio_notifier(void) { } +inline void msm_ext_cdc_deinit(void) +{ +} #endif #endif From 1ee08ea3dd185eaba6d3bd812a7b9a1e57735200 Mon Sep 17 00:00:00 2001 From: Shrey Vijay Date: Wed, 14 Dec 2016 15:56:05 +0530 Subject: [PATCH 40/73] i2c-msm-v2:Synchronise runtime PM callback operations During system wakeup from suspend by connecting USB cable, runtime PM framework transitions from enabled to disabled state during i2c transaction. This causes asymmetric increment and decrement of device's usage counter which blocks runtime PM suspend callback. To avoid this, remove rumtime PM status check on suspend path to make it symmetric with the resume path. This takes care of unaccounted increment/decrement of device's usage counter. Change-Id: I47cfe2cd7d93ba5db57365cf250c600dac22bab1 Signed-off-by: Shrey Vijay --- drivers/i2c/busses/i2c-msm-v2.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-msm-v2.c b/drivers/i2c/busses/i2c-msm-v2.c index a510490d28d6..04b1b62f85c3 100644 --- a/drivers/i2c/busses/i2c-msm-v2.c +++ b/drivers/i2c/busses/i2c-msm-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, 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 @@ -2236,12 +2236,12 @@ static void i2c_msm_pm_xfer_end(struct i2c_msm_ctrl *ctrl) i2c_msm_dma_free_channels(ctrl); i2c_msm_pm_clk_disable_unprepare(ctrl); - if (pm_runtime_enabled(ctrl->dev)) { - pm_runtime_mark_last_busy(ctrl->dev); - pm_runtime_put_autosuspend(ctrl->dev); - } else { + + if (!pm_runtime_enabled(ctrl->dev)) i2c_msm_pm_suspend(ctrl->dev); - } + + pm_runtime_mark_last_busy(ctrl->dev); + pm_runtime_put_autosuspend(ctrl->dev); mutex_unlock(&ctrl->xfer.mtx); } From f095154643e1426b1838b5d8510e8241022b5dca Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Thu, 22 Dec 2016 14:36:54 +0530 Subject: [PATCH 41/73] ARM: dts: msm: Allocate memory for diag client for msmfalcon This patch enables allocation of 5MB for new diag client of memshare. CRs-Fixed: 1100632 Change-Id: Iab69062336966e61683117a17974f46cd8f513aa Signed-off-by: Manoj Prabhu B --- arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi index bde93bf4c314..9b8efdb3d52c 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi @@ -47,3 +47,7 @@ compatible = "qcom,msm-ssc-sensors"; }; }; + +&mem_client_3_size { + qcom,peripheral-size = <0x500000>; +}; From c2e31d922c522757be5275c591800f71b6210bc6 Mon Sep 17 00:00:00 2001 From: Chandana Kishori Chiluveru Date: Thu, 15 Dec 2016 19:43:30 +0530 Subject: [PATCH 42/73] usb: gadget: f_qc_rndis: Fix double-free in qcrndis_free_inst qcrndis_free_inst function can double free f_qc_rndis pointer. Hence fix this memory bug in qcrndis_free_inst function. Same bool RNDIS flag is used for USB_CONFIGFS_RNDIS and USB_CONFIGFS_QCRNDIS. Add bool Change in Kconfig to differentiate these two different configs. Change-Id: I8e7c4be090107618cd6cbac394a57f109f8a1ced Signed-off-by: Chandana Kishori Chiluveru --- drivers/usb/gadget/Kconfig | 2 +- drivers/usb/gadget/function/f_qc_rndis.c | 13 +------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 9d9eed2d5d68..b826f926b205 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -325,7 +325,7 @@ config USB_CONFIGFS_ECM_SUBSET a simple CDC subset is used, placing fewer demands on USB. config USB_CONFIGFS_QCRNDIS - bool "RNDIS" + bool "QCRNDIS" depends on USB_CONFIGFS depends on RNDIS_IPA depends on NET diff --git a/drivers/usb/gadget/function/f_qc_rndis.c b/drivers/usb/gadget/function/f_qc_rndis.c index eb306529981f..b8baa303f20b 100644 --- a/drivers/usb/gadget/function/f_qc_rndis.c +++ b/drivers/usb/gadget/function/f_qc_rndis.c @@ -1320,19 +1320,16 @@ static struct miscdevice rndis_qc_device = { static void qcrndis_free_inst(struct usb_function_instance *f) { - struct f_rndis_qc *rndis; struct f_rndis_qc_opts *opts = container_of(f, struct f_rndis_qc_opts, func_inst); unsigned long flags; - rndis = opts->rndis; misc_deregister(&rndis_qc_device); ipa_data_free(USB_IPA_FUNC_RNDIS); spin_lock_irqsave(&rndis_lock, flags); - kfree(rndis); - _rndis_qc = NULL; kfree(opts->rndis); + _rndis_qc = NULL; kfree(opts); spin_unlock_irqrestore(&rndis_lock, flags); } @@ -1414,13 +1411,6 @@ static struct usb_function_instance *qcrndis_alloc_inst(void) return &opts->func_inst; } -static void rndis_qc_cleanup(void) -{ - pr_info("rndis QC cleanup\n"); - - misc_deregister(&rndis_qc_device); -} - void *rndis_qc_get_ipa_rx_cb(void) { return rndis_ipa_params.ipa_rx_notify; @@ -1458,7 +1448,6 @@ static int __init usb_qcrndis_init(void) static void __exit usb_qcrndis_exit(void) { usb_function_unregister(&rndis_bamusb_func); - rndis_qc_cleanup(); } module_init(usb_qcrndis_init); From 90b10dc7003fae38c1a4c0dbf9df6266df9b47ad Mon Sep 17 00:00:00 2001 From: Amir Samuelov Date: Thu, 22 Dec 2016 13:06:48 +0200 Subject: [PATCH 43/73] spcom: abort any read() operation on SSR Abort any read() operation to unlock the channel mutex. On channel remote-disconnect notification, the local side should close the channel. However, open()/close()/read()/write() operations locks the channel mutex. The glink rx-abort notification happens only after the remote-disconnect notification, not as originally expected. Change-Id: I77f8e6de6f1b5c447a3516380c51db9c7129d2f3 Signed-off-by: Amir Samuelov --- drivers/soc/qcom/spcom.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/spcom.c b/drivers/soc/qcom/spcom.c index 5b3e6c36810e..e8ea99827403 100644 --- a/drivers/soc/qcom/spcom.c +++ b/drivers/soc/qcom/spcom.c @@ -272,6 +272,8 @@ static struct spcom_device *spcom_dev; static int spcom_create_channel_chardev(const char *name); static int spcom_open(struct spcom_channel *ch, unsigned int timeout_msec); static int spcom_close(struct spcom_channel *ch); +static void spcom_notify_rx_abort(void *handle, const void *priv, + const void *pkt_priv); /** * spcom_is_ready() - driver is initialized and ready. @@ -467,6 +469,13 @@ static void spcom_notify_state(void *handle, const void *priv, unsigned event) * This may happen upon remote SSR. */ pr_err("GLINK_REMOTE_DISCONNECTED, ch [%s].\n", ch->name); + + /* + * Abort any blocking read() operation. + * The glink notification might be after REMOTE_DISCONNECT. + */ + spcom_notify_rx_abort(NULL, ch, NULL); + /* * after glink_close(), * expecting notify GLINK_LOCAL_DISCONNECTED @@ -515,7 +524,7 @@ static void spcom_notify_rx_abort(void *handle, const void *priv, pr_debug("ch [%s] pending rx aborted.\n", ch->name); - if (spcom_is_channel_connected(ch)) { + if (spcom_is_channel_connected(ch) && (!ch->rx_abort)) { ch->rx_abort = true; complete_all(&ch->rx_done); } @@ -535,9 +544,9 @@ static void spcom_notify_tx_abort(void *handle, const void *priv, pr_debug("ch [%s] pending tx aborted.\n", ch->name); - if (spcom_is_channel_connected(ch)) { - complete_all(&ch->tx_done); + if (spcom_is_channel_connected(ch) && (!ch->tx_abort)) { ch->tx_abort = true; + complete_all(&ch->tx_done); } } From f9bf3dd7e9585bdd9e5b02f4552f328d1e9e176e Mon Sep 17 00:00:00 2001 From: Sandeep Panda Date: Tue, 20 Dec 2016 11:58:47 +0530 Subject: [PATCH 44/73] clk: qcom: add MDSS PLL support for msmfalcon Add the msmfalcon compatible string to MDSS PLL driver dt table list so that MDSS PLL driver initialization takes place for msmflacon platform. Change-Id: I806456737485dfcbca8a71d59db0927bbd843708 Signed-off-by: Sandeep Panda --- Documentation/devicetree/bindings/fb/mdss-pll.txt | 2 +- drivers/clk/qcom/mdss/mdss-pll.c | 5 +++++ drivers/clk/qcom/mdss/mdss-pll.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/fb/mdss-pll.txt b/Documentation/devicetree/bindings/fb/mdss-pll.txt index 945d79825695..e9e4a9af381b 100644 --- a/Documentation/devicetree/bindings/fb/mdss-pll.txt +++ b/Documentation/devicetree/bindings/fb/mdss-pll.txt @@ -15,7 +15,7 @@ Required properties: "qcom,mdss_hdmi_pll_8996_v2", "qcom,mdss_dsi_pll_8996_v2", "qcom,mdss_hdmi_pll_8996_v3", "qcom,mdss_hdmi_pll_8996_v3_1p8", "qcom,mdss_dsi_pll_8998", "qcom,mdss_dp_pll_8998", - "qcom,mdss_hdmi_pll_8998" + "qcom,mdss_hdmi_pll_8998", "qcom,mdss_dsi_pll_msmfalcon" - cell-index: Specifies the controller used - reg: offset and length of the register set for the device. - reg-names : names to refer to register sets related to this device diff --git a/drivers/clk/qcom/mdss/mdss-pll.c b/drivers/clk/qcom/mdss/mdss-pll.c index b4b73ea4211a..b51ab4f21561 100644 --- a/drivers/clk/qcom/mdss/mdss-pll.c +++ b/drivers/clk/qcom/mdss/mdss-pll.c @@ -133,6 +133,10 @@ static int mdss_pll_resource_parse(struct platform_device *pdev, pll_res->pll_interface_type = MDSS_DSI_PLL_8996; pll_res->target_id = MDSS_PLL_TARGET_8996; pll_res->revision = 2; + } else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_msmfalcon")) { + pll_res->pll_interface_type = MDSS_DSI_PLL_8996; + pll_res->target_id = MDSS_PLL_TARGET_MSMFALCON; + pll_res->revision = 2; } else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_8998")) { pll_res->pll_interface_type = MDSS_DSI_PLL_8998; } else if (!strcmp(compatible_stream, "qcom,mdss_dp_pll_8998")) { @@ -378,6 +382,7 @@ static const struct of_device_id mdss_pll_dt_match[] = { {.compatible = "qcom,mdss_hdmi_pll_8996_v3_1p8"}, {.compatible = "qcom,mdss_dp_pll_8998"}, {.compatible = "qcom,mdss_hdmi_pll_8998"}, + {.compatible = "qcom,mdss_dsi_pll_msmfalcon"}, {} }; diff --git a/drivers/clk/qcom/mdss/mdss-pll.h b/drivers/clk/qcom/mdss/mdss-pll.h index 3528dcfd0cb5..01664eaa815c 100644 --- a/drivers/clk/qcom/mdss/mdss-pll.h +++ b/drivers/clk/qcom/mdss/mdss-pll.h @@ -51,6 +51,7 @@ enum { enum { MDSS_PLL_TARGET_8996, + MDSS_PLL_TARGET_MSMFALCON, }; #define DFPS_MAX_NUM_OF_FRAME_RATES 20 From b2dcc0a3b1bfa5d44abadd5bf550b4a76d7c7491 Mon Sep 17 00:00:00 2001 From: Raviteja Tamatam Date: Wed, 14 Dec 2016 09:53:05 +0530 Subject: [PATCH 45/73] ARM: dts: msm: add mdss node for msmfalcon target Add mdss node for msmfalcon target which is used by display driver. Change-Id: I49efddea0228e3129d36eabc102d6df0fcd53d12 Signed-off-by: Raviteja Tamatam Signed-off-by: Sandeep Panda Signed-off-by: Vishnuvardhan Prodduturi --- arch/arm/boot/dts/qcom/msmfalcon-cdp.dtsi | 46 ++ .../boot/dts/qcom/msmfalcon-mdss-panels.dtsi | 83 +++ .../arm/boot/dts/qcom/msmfalcon-mdss-pll.dtsi | 82 +++ arch/arm/boot/dts/qcom/msmfalcon-mdss.dtsi | 579 ++++++++++++++++++ arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi | 46 ++ arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi | 53 ++ arch/arm/boot/dts/qcom/msmfalcon.dtsi | 3 + 7 files changed, 892 insertions(+) create mode 100644 arch/arm/boot/dts/qcom/msmfalcon-mdss-panels.dtsi create mode 100644 arch/arm/boot/dts/qcom/msmfalcon-mdss-pll.dtsi create mode 100644 arch/arm/boot/dts/qcom/msmfalcon-mdss.dtsi diff --git a/arch/arm/boot/dts/qcom/msmfalcon-cdp.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-cdp.dtsi index 9f057b9444c1..e1306bd78837 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-cdp.dtsi @@ -42,6 +42,52 @@ status = "ok"; }; +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + hw-config = "split_dsi"; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_truly_video>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,platform-reset-gpio = <&tlmm 53 0>; + qcom,platform-te-gpio = <&tlmm 59 0>; +}; + +&mdss_dsi1 { + qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_truly_video>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,platform-reset-gpio = <&tlmm 53 0>; + qcom,platform-te-gpio = <&tlmm 59 0>; +}; + +&pm2falcon_wled { + qcom,led-strings-list = [01 02]; +}; + +&dsi_dual_nt35597_truly_video { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + +&dsi_dual_nt35597_truly_cmd { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + &soc { qcom,msm-ssc-sensors { compatible = "qcom,msm-ssc-sensors"; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-mdss-panels.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-mdss-panels.dtsi new file mode 100644 index 000000000000..28e5f6ba8b45 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-mdss-panels.dtsi @@ -0,0 +1,83 @@ +/* Copyright (c) 2016, 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. + */ + +#include "dsi-panel-sim-video.dtsi" +#include "dsi-panel-sim-dualmipi-video.dtsi" +#include "dsi-panel-nt35597-truly-dualmipi-wqxga-video.dtsi" +#include "dsi-panel-nt35597-truly-dualmipi-wqxga-cmd.dtsi" + +&soc { + dsi_panel_pwr_supply: dsi_panel_pwr_supply { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "wqhd-vddio"; + qcom,supply-min-voltage = <1880000>; + qcom,supply-max-voltage = <1950000>; + qcom,supply-enable-load = <32000>; + qcom,supply-disable-load = <80>; + }; + + qcom,panel-supply-entry@1 { + reg = <1>; + qcom,supply-name = "lab"; + qcom,supply-min-voltage = <4600000>; + qcom,supply-max-voltage = <6000000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,panel-supply-entry@2 { + reg = <2>; + qcom,supply-name = "ibb"; + qcom,supply-min-voltage = <4600000>; + qcom,supply-max-voltage = <6000000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <10>; + }; + }; +}; + +&soc { + dsi_panel_pwr_supply_no_labibb: dsi_panel_pwr_supply_no_labibb { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "wqhd-vddio"; + qcom,supply-min-voltage = <1880000>; + qcom,supply-max-voltage = <1950000>; + qcom,supply-enable-load = <32000>; + qcom,supply-disable-load = <80>; + }; + }; +}; + +&dsi_dual_nt35597_truly_video { + qcom,mdss-dsi-panel-timings-8996 = [23 1e 07 08 05 03 04 a0 + 23 1e 07 08 05 03 04 a0 + 23 1e 07 08 05 03 04 a0 + 23 1e 07 08 05 03 04 a0 + 23 18 07 08 04 03 04 a0]; +}; + +&dsi_dual_nt35597_truly_cmd { + qcom,mdss-dsi-panel-timings-8996 = [23 1e 07 08 05 03 04 a0 + 23 1e 07 08 05 03 04 a0 + 23 1e 07 08 05 03 04 a0 + 23 1e 07 08 05 03 04 a0 + 23 18 07 08 04 03 04 a0]; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-mdss-pll.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-mdss-pll.dtsi new file mode 100644 index 000000000000..61baf6aff4b1 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-mdss-pll.dtsi @@ -0,0 +1,82 @@ +/* Copyright (c) 2016, 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. + */ + +&soc { + mdss_dsi0_pll: qcom,mdss_dsi_pll@c994400 { + compatible = "qcom,mdss_dsi_pll_msmfalcon"; + status = "ok"; + label = "MDSS DSI 0 PLL"; + cell-index = <0>; + #clock-cells = <1>; + + reg = <0xc994400 0x588>, + <0xc8c2300 0x8>; + reg-names = "pll_base", "gdsc_base"; + + gdsc-supply = <&gdsc_mdss>; + + clocks = <&clock_mmss MMSS_MDSS_AHB_CLK>; + clock-names = "iface_clk"; + clock-rate = <0>; + qcom,dsi-pll-ssc-en; + qcom,dsi-pll-ssc-mode = "down-spread"; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + + }; + }; + + mdss_dsi1_pll: qcom,mdss_dsi_pll@c996400 { + compatible = "qcom,mdss_dsi_pll_msmfalcon"; + status = "ok"; + label = "MDSS DSI 1 PLL"; + cell-index = <1>; + #clock-cells = <1>; + + reg = <0xc996400 0x588>, + <0xc8c2300 0x8>; + reg-names = "pll_base", "gdsc_base"; + + gdsc-supply = <&gdsc_mdss>; + + clocks = <&clock_mmss MMSS_MDSS_AHB_CLK>; + clock-names = "iface_clk"; + clock-rate = <0>; + qcom,dsi-pll-ssc-en; + qcom,dsi-pll-ssc-mode = "down-spread"; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-mdss.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-mdss.dtsi new file mode 100644 index 000000000000..f7e1b053dbb2 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-mdss.dtsi @@ -0,0 +1,579 @@ +/* Copyright (c) 2016, 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. + */ + +#include + +&soc { + mdss_mdp: qcom,mdss_mdp@c900000 { + compatible = "qcom,mdss_mdp"; + status = "ok"; + reg = <0x0c900000 0x90000>, + <0x0c9b0000 0x1040>; + reg-names = "mdp_phys", "vbif_phys"; + interrupts = <0 83 0>; + interrupt-controller; + #interrupt-cells = <1>; + vdd-supply = <&gdsc_mdss>; + + /* Bus Scale Settings */ + qcom,msm-bus,name = "mdss_mdp"; + qcom,msm-bus,num-cases = <3>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, <23 512 0 0>, + <22 512 0 6400000>, <23 512 0 6400000>, + <22 512 0 6400000>, <23 512 0 6400000>; + + /* Fudge factors */ + qcom,mdss-ab-factor = <1 1>; /* 1 time */ + qcom,mdss-ib-factor = <1 1>; /* 1 time */ + qcom,mdss-clk-factor = <105 100>; /* 1.05 times */ + + qcom,max-mixer-width = <2560>; + qcom,max-pipe-width = <2560>; + + qcom,max-dest-scaler-input-width = <2048>; + qcom,max-dest-scaler-output-width = <2560>; + + /* VBIF QoS remapper settings*/ + qcom,mdss-vbif-qos-rt-setting = <1 2 2 2>; + qcom,vbif-settings = <0x00ac 0x00000040>, + <0x00d0 0x00001010>; /* v1 only */ + + qcom,mdss-has-panic-ctrl; + qcom,mdss-per-pipe-panic-luts = <0x000f>, + <0xffff>, + <0xfffc>, + <0xff00>; + + qcom,mdss-mdp-reg-offset = <0x00001000>; + qcom,max-bandwidth-low-kbps = <6600000>; + qcom,max-bandwidth-high-kbps = <6600000>; + qcom,max-bandwidth-per-pipe-kbps = <3100000>; + qcom,max-clk-rate = <412500000>; + qcom,mdss-default-ot-rd-limit = <32>; + qcom,mdss-default-ot-wr-limit = <40>; + qcom,mdss-dram-channels = <2>; + + /* Bandwidth limit settings */ + qcom,max-bw-settings = <1 6600000>, /* Default */ + <2 4500000>; /* Camera */ + + qcom,mdss-pipe-vig-off = <0x00005000 0x00007000>; + qcom,mdss-pipe-dma-off = <0x00025000 0x00027000 + 0x00029000>; + qcom,mdss-pipe-cursor-off = <0x00035000>; + + qcom,mdss-pipe-vig-xin-id = <0 4>; + qcom,mdss-pipe-dma-xin-id = <1 5 9>; + qcom,mdss-pipe-cursor-xin-id = <2>; + + /* These Offsets are relative to + * "mdp_phys + mdp-reg-offset" address + */ + qcom,mdss-pipe-vig-clk-ctrl-offsets = <0x2ac 0 0>, + <0x2b4 0 0>; + qcom,mdss-pipe-dma-clk-ctrl-offsets = <0x2ac 8 12>, + <0x2b4 8 12>, + <0x2c4 8 12>; + qcom,mdss-pipe-cursor-clk-ctrl-offsets = <0x3a8 16 15>; + + qcom,mdss-ctl-off = <0x00002000 0x00002200 0x00002400 + 0x00002600 0x00002800>; + qcom,mdss-mixer-intf-off = <0x00045000 0x00046000 + 0x00047000 0x0004a000>; + qcom,mdss-dspp-off = <0x00055000 0x00057000>; + qcom,mdss-wb-off = <0x00066000>; + qcom,mdss-intf-off = <0x0006b000 0x0006b800 + 0x0006c000 0x0006c800>; + qcom,mdss-pingpong-off = <0x00071000 0x00071800 + 0x00072000 0x00072800>; + qcom,mdss-slave-pingpong-off = <0x00073000>; + qcom,mdss-ppb-ctl-off = <0x00000330 0x00000338 0x00000370 + 0x00000374> ; + qcom,mdss-ppb-cfg-off = <0x00000334 0x0000033C>; + qcom,mdss-has-pingpong-split; + qcom,mdss-has-separate-rotator; + + qcom,mdss-ad-off = <0x0079000 0x00079800>; + qcom,mdss-cdm-off = <0x0007a200>; + qcom,mdss-dsc-off = <0x00081000 0x00081400>; + qcom,mdss-wfd-mode = "intf"; + qcom,mdss-has-source-split; + qcom,mdss-highest-bank-bit = <0x1>; + qcom,mdss-has-decimation; + qcom,mdss-idle-power-collapse-enabled; + clocks = <&clock_mmss MMSS_MNOC_AHB_CLK>, + <&clock_mmss MMSS_MDSS_AHB_CLK>, + <&clock_mmss MMSS_MDSS_AXI_CLK>, + <&clock_mmss MDP_CLK_SRC>, + <&clock_mmss MMSS_MDSS_MDP_CLK>, + <&clock_mmss MMSS_MDSS_VSYNC_CLK>, + <&clock_mmss MDP_CLK_SRC>; + clock-names = "mnoc_clk", "iface_clk", "bus_clk", + "core_clk_src", "core_clk", "vsync_clk", + "lut_clk"; + + qcom,mdp-settings = <0x01190 0x00000000>, + <0x012ac 0xc0000ccc>, + <0x012b4 0xc0000ccc>, + <0x012bc 0x00cccccc>, + <0x012c4 0x000000cc>, + <0x013a8 0x0cccc0c0>, + <0x013b0 0xccccc0c0>, + <0x013b8 0xcccc0000>, + <0x013d0 0x00cc0000>, + <0x0506c 0x00000000>, + <0x0706c 0x00000000>, + <0x0906c 0x00000000>, + <0x0b06c 0x00000000>, + <0x1506c 0x00000000>, + <0x1706c 0x00000000>, + <0x1906c 0x00000000>, + <0x1b06c 0x00000000>, + <0x2506c 0x00000000>, + <0x2706c 0x00000000>; + + qcom,regs-dump-mdp = <0x01000 0x01458>, + <0x02000 0x02094>, + <0x02200 0x02294>, + <0x02400 0x02494>, + <0x02600 0x02694>, + <0x02800 0x02894>, + <0x05000 0x05154>, + <0x05a00 0x05b00>, + <0x07000 0x07154>, + <0x07a00 0x07b00>, + <0x25000 0x25184>, + <0x27000 0x27184>, + <0x29000 0x29184>, + <0x35000 0x35150>, + <0x45000 0x452bc>, + <0x46000 0x462bc>, + <0x47000 0x472bc>, + <0x4a000 0x4a2bc>, + <0x55000 0x5522c>, + <0x57000 0x5722c>, + <0x66000 0x662c0>, + <0x6b000 0x6b268>, + <0x6b800 0x6ba68>, + <0x6c000 0x6c268>, + <0x71000 0x710d4>, + <0x71800 0x718d4>, + <0x73000 0x730d4>, + <0x81000 0x81140>, + <0x81400 0x81540>; + + qcom,regs-dump-names-mdp = "MDP", + "CTL_0", "CTL_1", "CTL_2", "CTL_3", "CTL_4", + "VIG0_SSPP", "VIG0", "VIG1_SSPP", "VIG1", + "DMA0_SSPP", "DMA1_SSPP","DMA2_SSPP", + "CURSOR0_SSPP", + "LAYER_0", "LAYER_1", "LAYER_2", + "LAYER_5", + "DSPP_0", "DSPP_1", + "WB_2", + "INTF_0", "INTF_1", "INTF_2", + "PP_0", "PP_1", "PP_4", + "DSC_0", "DSC_1"; + + /* buffer parameters to calculate prefill bandwidth */ + qcom,mdss-prefill-outstanding-buffer-bytes = <0>; + qcom,mdss-prefill-y-buffer-bytes = <0>; + qcom,mdss-prefill-scaler-buffer-lines-bilinear = <2>; + qcom,mdss-prefill-scaler-buffer-lines-caf = <4>; + qcom,mdss-prefill-post-scaler-buffer-pixels = <2560>; + qcom,mdss-prefill-pingpong-buffer-pixels = <5120>; + + qcom,mdss-pp-offsets { + qcom,mdss-sspp-mdss-igc-lut-off = <0x2000>; + qcom,mdss-sspp-vig-pcc-off = <0x1b00>; + qcom,mdss-sspp-rgb-pcc-off = <0x380>; + qcom,mdss-sspp-dma-pcc-off = <0x380>; + qcom,mdss-lm-pgc-off = <0x3c0>; + qcom,mdss-dspp-gamut-off = <0x1600>; + qcom,mdss-dspp-pcc-off = <0x1700>; + qcom,mdss-dspp-pgc-off = <0x17c0>; + }; + + qcom,mdss-scaler-offsets { + qcom,mdss-vig-scaler-off = <0xa00>; + qcom,mdss-vig-scaler-lut-off = <0xb00>; + qcom,mdss-has-dest-scaler; + qcom,mdss-dest-block-off = <0x00061000>; + qcom,mdss-dest-scaler-off = <0x800 0x1000>; + qcom,mdss-dest-scaler-lut-off = <0x900 0x1100>; + }; + + smmu_mdp_unsec: qcom,smmu_mdp_unsec_cb { + compatible = "qcom,smmu_mdp_unsec"; + iommus = <&mmss_bimc_smmu 0>; + gdsc-mmagic-mdss-supply = <&gdsc_bimc_smmu>; + clocks = <&clock_rpmcc MMSSNOC_AXI_CLK>, + <&clock_mmss MMSS_MNOC_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>; + clock-names = "mmss_noc_axi_clk", + "mmss_noc_ahb_clk", + "mmss_smmu_ahb_clk", + "mmss_smmu_axi_clk"; + }; + + smmu_mdp_sec: qcom,smmu_mdp_sec_cb { + compatible = "qcom,smmu_mdp_sec"; + iommus = <&mmss_bimc_smmu 1>; + gdsc-mmagic-mdss-supply = <&gdsc_bimc_smmu>; + clocks = <&clock_rpmcc MMSSNOC_AXI_CLK>, + <&clock_mmss MMSS_MNOC_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>; + clock-names = "mmss_noc_axi_clk", + "mmss_noc_ahb_clk", + "mmss_smmu_ahb_clk", + "mmss_smmu_axi_clk"; + }; + + mdss_fb0: qcom,mdss_fb_primary { + cell-index = <0>; + compatible = "qcom,mdss-fb"; + }; + + mdss_fb1: qcom,mdss_fb_wfd { + cell-index = <1>; + compatible = "qcom,mdss-fb"; + }; + + mdss_fb2: qcom,mdss_fb_dp { + cell-index = <2>; + compatible = "qcom,mdss-fb"; + qcom,mdss-intf = <&mdss_dp_ctrl>; + }; + + }; + + mdss_dsi: qcom,mdss_dsi@0 { + compatible = "qcom,mdss-dsi"; + #address-cells = <1>; + #size-cells = <1>; + gdsc-supply = <&gdsc_mdss>; + vdda-1p2-supply = <&pmfalcon_l1>; + vdda-0p9-supply = <&pm2falcon_l1>; + ranges = <0xc994000 0xc994000 0x400 + 0xc994400 0xc994400 0x588 + 0xc828000 0xc828000 0xac + 0xc996000 0xc996000 0x400 + 0xc996400 0xc996400 0x588 + 0xc828000 0xc828000 0xac>; + + /* Bus Scale Settings */ + qcom,msm-bus,name = "mdss_dsi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 1000>; + + qcom,mmss-ulp-clamp-ctrl-offset = <0x14>; + + clocks = <&clock_mmss MMSS_MDSS_MDP_CLK>, + <&clock_mmss MMSS_MNOC_AHB_CLK>, + <&clock_mmss MMSS_MDSS_AHB_CLK>, + <&clock_mmss MMSS_MDSS_AXI_CLK>, + <&clock_mmss MMSS_MISC_AHB_CLK>, + <&mdss_dsi0_pll BYTE0_MUX_CLK>, + <&mdss_dsi1_pll BYTE1_MUX_CLK>, + <&mdss_dsi0_pll PIX0_MUX_CLK>, + <&mdss_dsi1_pll PIX1_MUX_CLK>; + clock-names = "mdp_core_clk", + "mnoc_clk", "iface_clk", + "bus_clk", "core_mmss_clk", + "ext_byte0_clk", "ext_byte1_clk", + "ext_pixel0_clk", "ext_pixel1_clk"; + + qcom,core-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,core-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda-1p2"; + qcom,supply-min-voltage = <1200000>; + qcom,supply-max-voltage = <1250000>; + qcom,supply-enable-load = <12560>; + qcom,supply-disable-load = <4>; + }; + }; + + qcom,phy-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,phy-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda-0p9"; + qcom,supply-min-voltage = <880000>; + qcom,supply-max-voltage = <925000>; + qcom,supply-enable-load = <73400>; + qcom,supply-disable-load = <32>; + }; + }; + + mdss_dsi0: qcom,mdss_dsi_ctrl0@c994000 { + compatible = "qcom,mdss-dsi-ctrl"; + label = "MDSS DSI CTRL->0"; + cell-index = <0>; + reg = <0xc994000 0x400>, + <0xc994400 0x588>, + <0xc828000 0xac>; + reg-names = "dsi_ctrl", "dsi_phy", "mmss_misc_phys"; + + qcom,timing-db-mode; + wqhd-vddio-supply = <&pmfalcon_l11>; + lab-supply = <&lcdb_ldo_vreg>; + ibb-supply = <&lcdb_ncp_vreg>; + qcom,mdss-mdp = <&mdss_mdp>; + qcom,mdss-fb-map = <&mdss_fb0>; + + clocks = <&clock_mmss MMSS_MDSS_BYTE0_CLK>, + <&clock_mmss MMSS_MDSS_PCLK0_CLK>, + <&clock_mmss MMSS_MDSS_ESC0_CLK>, + <&clock_mmss BYTE0_CLK_SRC>, + <&clock_mmss PCLK0_CLK_SRC>, + <&clock_mmss MMSS_MDSS_BYTE0_INTF_CLK>; + clock-names = "byte_clk", "pixel_clk", "core_clk", + "byte_clk_rcg", "pixel_clk_rcg", + "byte_intf_clk"; + + qcom,platform-strength-ctrl = [ff 06 + ff 06 + ff 06 + ff 06 + ff 00]; + qcom,platform-regulator-settings = [1d + 1d 1d 1d 1d]; + qcom,platform-lane-config = [00 00 10 0f + 00 00 10 0f + 00 00 10 0f + 00 00 10 0f + 00 00 10 8f]; + }; + + mdss_dsi1: qcom,mdss_dsi_ctrl1@c996000 { + compatible = "qcom,mdss-dsi-ctrl"; + label = "MDSS DSI CTRL->1"; + cell-index = <1>; + reg = <0xc996000 0x400>, + <0xc996400 0x588>, + <0xc828000 0xac>; + reg-names = "dsi_ctrl", "dsi_phy", "mmss_misc_phys"; + + qcom,timing-db-mode; + wqhd-vddio-supply = <&pmfalcon_l11>; + lab-supply = <&lcdb_ldo_vreg>; + ibb-supply = <&lcdb_ncp_vreg>; + qcom,mdss-mdp = <&mdss_mdp>; + qcom,mdss-fb-map = <&mdss_fb0>; + + clocks = <&clock_mmss MMSS_MDSS_BYTE1_CLK>, + <&clock_mmss MMSS_MDSS_PCLK1_CLK>, + <&clock_mmss MMSS_MDSS_ESC1_CLK>, + <&clock_mmss BYTE1_CLK_SRC>, + <&clock_mmss PCLK1_CLK_SRC>, + <&clock_mmss MMSS_MDSS_BYTE1_INTF_CLK>; + clock-names = "byte_clk", "pixel_clk", "core_clk", + "byte_clk_rcg", "pixel_clk_rcg", + "byte_intf_clk"; + + qcom,platform-strength-ctrl = [ff 06 + ff 06 + ff 06 + ff 06 + ff 00]; + qcom,platform-regulator-settings = [1d + 1d 1d 1d 1d]; + qcom,platform-lane-config = [00 00 10 0f + 00 00 10 0f + 00 00 10 0f + 00 00 10 0f + 00 00 10 8f]; + }; + }; + + qcom,mdss_wb_panel { + compatible = "qcom,mdss_wb"; + qcom,mdss_pan_res = <640 480>; + qcom,mdss_pan_bpp = <24>; + qcom,mdss-fb-map = <&mdss_fb1>; + }; + + msm_ext_disp: qcom,msm_ext_disp { + status = "disabled"; + compatible = "qcom,msm-ext-disp"; + + ext_disp_audio_codec: qcom,msm-ext-disp-audio-codec-rx { + compatible = "qcom,msm-ext-disp-audio-codec-rx"; + qcom,msm_ext_disp = <&msm_ext_disp>; + }; + }; + + mdss_dp_ctrl: qcom,dp_ctrl@c990000 { + status = "disabled"; + cell-index = <0>; + compatible = "qcom,mdss-dp"; + qcom,mdss-fb-map = <&mdss_fb2>; + + gdsc-supply = <&gdsc_mdss>; + vdda-1p2-supply = <&pmfalcon_l1>; + vdda-0p9-supply = <&pm2falcon_l1>; + + reg = <0xc990000 0xa84>, + <0xc011000 0x910>, + <0x1fcb200 0x050>, + <0xc8c2200 0x1a0>, + <0x780000 0x621c>, + <0xc9e1000 0x02c>; + reg-names = "dp_ctrl", "dp_phy", "tcsr_regs", "dp_mmss_cc", + "qfprom_physical","hdcp_physical"; + + qcom,msm_ext_disp = <&msm_ext_disp>; + + qcom,core-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,core-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda-1p2"; + qcom,supply-min-voltage = <1200000>; + qcom,supply-max-voltage = <1250000>; + qcom,supply-enable-load = <12560>; + qcom,supply-disable-load = <4>; + }; + }; + + qcom,phy-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,phy-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda-0p9"; + qcom,supply-min-voltage = <880000>; + qcom,supply-max-voltage = <925000>; + qcom,supply-enable-load = <73400>; + qcom,supply-disable-load = <32>; + }; + }; + }; + + mdss_rotator: qcom,mdss_rotator { + compatible = "qcom,sde_rotator"; + reg = <0x0c900000 0xab100>, + <0x0c9b0000 0x1040>; + reg-names = "mdp_phys", + "rot_vbif_phys"; + + qcom,mdss-rot-mode = <1>; + qcom,mdss-highest-bank-bit = <0x2>; + + /* Bus Scale Settings */ + qcom,msm-bus,name = "mdss_rotator"; + qcom,msm-bus,num-cases = <3>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 6400000>, + <22 512 0 6400000>; + + rot-vdd-supply = <&gdsc_mdss>; + qcom,supply-names = "rot-vdd"; + + clocks = <&clock_mmss MMSS_MNOC_AHB_CLK>, + <&clock_mmss MMSS_MDSS_AHB_CLK>, + <&clock_mmss ROT_CLK_SRC>, + <&clock_mmss MMSS_MDSS_ROT_CLK>, + <&clock_mmss MMSS_MDSS_AXI_CLK>; + clock-names = "mnoc_clk", + "iface_clk", "rot_core_clk", + "rot_clk", "axi_clk"; + + interrupt-parent = <&mdss_mdp>; + interrupts = <2 0>; + + /* VBIF QoS remapper settings*/ + qcom,mdss-rot-vbif-qos-setting = <1 1 1 1>; + + qcom,mdss-default-ot-rd-limit = <32>; + qcom,mdss-default-ot-wr-limit = <40>; + + smmu_rot_unsec: qcom,smmu_rot_unsec_cb { + compatible = "qcom,smmu_sde_rot_unsec"; + iommus = <&mmss_bimc_smmu 0xe00>; + gdsc-mdss-supply = <&gdsc_bimc_smmu>; + + clocks = <&clock_rpmcc MMSSNOC_AXI_CLK>, + <&clock_mmss MMSS_MNOC_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>; + clock-names = "mmss_noc_axi_clk", + "mmss_noc_ahb_clk", + "mmss_smmu_ahb_clk", + "mmss_smmu_axi_clk"; + }; + + smmu_rot_sec: qcom,smmu_rot_sec_cb { + compatible = "qcom,smmu_sde_rot_sec"; + iommus = <&mmss_bimc_smmu 0xe01>; + gdsc-mdss-supply = <&gdsc_bimc_smmu>; + + clocks = <&clock_rpmcc MMSSNOC_AXI_CLK>, + <&clock_mmss MMSS_MNOC_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>; + clock-names = "mmss_noc_axi_clk", + "mmss_noc_ahb_clk", + "mmss_smmu_ahb_clk", + "mmss_smmu_axi_clk"; + }; + }; + +}; + +#include "msmfalcon-mdss-panels.dtsi" diff --git a/arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi index bde93bf4c314..41d069dacf6b 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi @@ -42,6 +42,52 @@ status = "ok"; }; +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + hw-config = "split_dsi"; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_truly_video>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,platform-reset-gpio = <&tlmm 53 0>; + qcom,platform-te-gpio = <&tlmm 59 0>; +}; + +&mdss_dsi1 { + qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_truly_video>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,platform-reset-gpio = <&tlmm 53 0>; + qcom,platform-te-gpio = <&tlmm 59 0>; +}; + +&pm2falcon_wled { + qcom,led-strings-list = [01 02]; +}; + +&dsi_dual_nt35597_truly_video { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + +&dsi_dual_nt35597_truly_cmd { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + &soc { qcom,msm-ssc-sensors { compatible = "qcom,msm-ssc-sensors"; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi index d89293c63840..a54079413e7c 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi @@ -1196,6 +1196,59 @@ }; }; + pmx_mdss: pmx_mdss { + mdss_dsi_active: mdss_dsi_active { + mux { + pins = "gpio53"; + function = "gpio"; + }; + + config { + pins = "gpio53"; + drive-strength = <8>; /* 8 mA */ + bias-disable = <0>; /* no pull */ + }; + }; + mdss_dsi_suspend: mdss_dsi_suspend { + mux { + pins = "gpio53"; + function = "gpio"; + }; + + config { + pins = "gpio53"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + }; + + pmx_mdss_te { + mdss_te_active: mdss_te_active { + mux { + pins = "gpio59"; + function = "mdp_vsync_p"; + }; + config { + pins = "gpio59"; + drive-strength = <2>; /* 8 mA */ + bias-pull-down; /* pull down*/ + }; + }; + + mdss_te_suspend: mdss_te_suspend { + mux { + pins = "gpio59"; + function = "mdp_vsync_p"; + }; + config { + pins = "gpio59"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + }; + ts_mux { ts_active: ts_active { mux { diff --git a/arch/arm/boot/dts/qcom/msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmfalcon.dtsi index edea1eea6752..a69c8b7569f5 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon.dtsi @@ -2047,3 +2047,6 @@ }; }; }; + +#include "msmfalcon-mdss.dtsi" +#include "msmfalcon-mdss-pll.dtsi" From 2e89457a54d07a54e225ff2874eb265a7deb4f1d Mon Sep 17 00:00:00 2001 From: Santosh Mardi Date: Thu, 22 Dec 2016 15:02:11 +0530 Subject: [PATCH 46/73] ARM: dts: msm: add devfreq nodes to msmfalcon target Add devfreq DCVS nodes mincpu, cpubw, memlat to msmfalcon target. Change-Id: I29572841624c1cb96d85e2dcfe620b455867d41e Signed-off-by: Santosh Mardi --- arch/arm/boot/dts/qcom/msmfalcon.dtsi | 130 ++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmfalcon.dtsi index edea1eea6752..ead45db9a7db 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon.dtsi @@ -952,6 +952,136 @@ #clock-cells = <1>; }; + cpubw: qcom,cpubw { + compatible = "qcom,devbw"; + governor = "performance"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3143 /* 412 MHz */ >, + < 4173 /* 547 MHz */ >, + < 5195 /* 681 MHz */ >, + < 5859 /* 768 MHz */ >, + < 7759 /* 1017 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 10327 /* 1353 MHz */ >, + < 11863 /* 1555 MHz */ >, + < 13763 /* 1804 MHz */ >; + }; + + bwmon: qcom,cpu-bwmon { + compatible = "qcom,bimc-bwmon3"; + reg = <0x01008000 0x300>, <0x01001000 0x200>; + reg-names = "base", "global_base"; + interrupts = <0 183 4>; + qcom,mport = <0>; + qcom,target-dev = <&cpubw>; + }; + + mincpubw: qcom,mincpubw { + compatible = "qcom,devbw"; + governor = "powersave"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3143 /* 412 MHz */ >, + < 4173 /* 547 MHz */ >, + < 5195 /* 681 MHz */ >, + < 5859 /* 768 MHz */ >, + < 7759 /* 1017 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 10327 /* 1353 MHz */ >, + < 11863 /* 1555 MHz */ >, + < 13763 /* 1804 MHz */ >; + }; + + memlat_cpu0: qcom,memlat-cpu0 { + compatible = "qcom,devbw"; + governor = "powersave"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3143 /* 412 MHz */ >, + < 4173 /* 547 MHz */ >, + < 5195 /* 681 MHz */ >, + < 5859 /* 768 MHz */ >, + < 7759 /* 1017 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 10327 /* 1353 MHz */ >, + < 11863 /* 1555 MHz */ >, + < 13763 /* 1804 MHz */ >; + }; + + memlat_cpu4: qcom,memlat-cpu4 { + compatible = "qcom,devbw"; + governor = "powersave"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3143 /* 412 MHz */ >, + < 4173 /* 547 MHz */ >, + < 5195 /* 681 MHz */ >, + < 5859 /* 768 MHz */ >, + < 7759 /* 1017 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 10327 /* 1353 MHz */ >, + < 11863 /* 1555 MHz */ >, + < 13763 /* 1804 MHz */ >; + }; + + devfreq_memlat_0: qcom,arm-memlat-mon-0 { + compatible = "qcom,arm-memlat-mon"; + qcom,cpulist = <&CPU0 &CPU1 &CPU2 &CPU3>; + qcom,target-dev = <&memlat_cpu0>; + qcom,core-dev-table = + < 633600 1525 >, + < 1401600 4173 >, + < 1881600 7759 >; + }; + + devfreq_memlat_4: qcom,arm-memlat-mon-4 { + compatible = "qcom,arm-memlat-mon"; + qcom,cpulist = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,target-dev = <&memlat_cpu4>; + qcom,core-dev-table = + < 1113600 1525 >, + < 1401600 7759 >, + < 2150400 11863 >, + < 2457600 13763 >; + }; + + devfreq_cpufreq: devfreq-cpufreq { + mincpubw-cpufreq { + target-dev = <&mincpubw>; + cpu-to-dev-map-0 = + < 633600 1525 >, + < 1401600 3143 >, + < 1881600 5859 >; + cpu-to-dev-map-4 = + < 1113600 1525 >, + < 1401600 4173 >, + < 1747200 5859 >, + < 2150400 7759 >, + < 2457600 13763 >; + }; + }; + sdhc_1: sdhci@c0c4000 { compatible = "qcom,sdhci-msm-v5"; reg = <0xc0c4000 0x1000>, <0xc0c5000 0x1000>; From a088541fb552653e0417472c7463fc1856e6e565 Mon Sep 17 00:00:00 2001 From: Prakash Kamliya Date: Tue, 20 Dec 2016 17:45:41 +0530 Subject: [PATCH 47/73] msm: kgsl: Do a midframe sampling of power stats if enabled Currently we sample power stats at the expiry of cmdbatch. In cases where cmdbatch takes a long time to finish the job, it delays power stats sampling, in effect it delays DCVS decision for changing the frequency. Do a midframe power stats sampling and feed it to DCVS if it is enabled. Change-Id: I547d792b38649aa1d60525b0dc335791b37989fd Signed-off-by: Prakash Kamliya --- .../devicetree/bindings/gpu/adreno.txt | 6 ++ drivers/gpu/msm/adreno_dispatch.c | 10 +++ drivers/gpu/msm/kgsl_pwrctrl.c | 5 ++ drivers/gpu/msm/kgsl_pwrscale.c | 79 +++++++++++++++++++ drivers/gpu/msm/kgsl_pwrscale.h | 3 + 5 files changed, 103 insertions(+) diff --git a/Documentation/devicetree/bindings/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt index f5ae85d27692..453223dc195a 100644 --- a/Documentation/devicetree/bindings/gpu/adreno.txt +++ b/Documentation/devicetree/bindings/gpu/adreno.txt @@ -143,6 +143,12 @@ Optional Properties: Specify the name of GPU temperature sensor. This name will be used to get the temperature from the thermal driver API. +- qcom,enable-midframe-timer: + Boolean. Enables the use of midframe sampling timer. This timer + samples the GPU powerstats if the cmdbatch expiry takes longer than + the threshold set by KGSL_GOVERNOR_CALL_INTERVAL. Enable only if + target has NAP state enabled. + GPU Quirks: - qcom,gpu-quirk-two-pass-use-wfi: Signal the GPU to set Set TWOPASSUSEWFI bit in diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c index 18c05e930216..0d068e9c5805 100644 --- a/drivers/gpu/msm/adreno_dispatch.c +++ b/drivers/gpu/msm/adreno_dispatch.c @@ -604,6 +604,16 @@ static int sendcmd(struct adreno_device *adreno_dev, if (!test_and_set_bit(ADRENO_DISPATCHER_ACTIVE, &dispatcher->priv)) reinit_completion(&dispatcher->idle_gate); + + /* + * We update power stats generally at the expire of + * cmdbatch. In cases where the cmdbatch takes a long + * time to finish, it will delay power stats update, + * in effect it will delay DCVS decision. Start a + * timer to update power state on expire of this timer. + */ + kgsl_pwrscale_midframe_timer_restart(device); + } else { kgsl_active_count_put(device); clear_bit(ADRENO_DISPATCHER_POWER, &dispatcher->priv); diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c index 172de7406c26..cd9a82a9bf4a 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -2355,6 +2355,7 @@ static int _init(struct kgsl_device *device) case KGSL_STATE_ACTIVE: kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); del_timer_sync(&device->idle_timer); + kgsl_pwrscale_midframe_timer_cancel(device); device->ftbl->stop(device); /* fall through */ case KGSL_STATE_AWARE: @@ -2462,6 +2463,7 @@ _aware(struct kgsl_device *device) case KGSL_STATE_ACTIVE: kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); del_timer_sync(&device->idle_timer); + kgsl_pwrscale_midframe_timer_cancel(device); break; case KGSL_STATE_SLUMBER: status = kgsl_pwrctrl_enable(device); @@ -2486,6 +2488,8 @@ _nap(struct kgsl_device *device) return -EBUSY; } + kgsl_pwrscale_midframe_timer_cancel(device); + /* * Read HW busy counters before going to NAP state. * The data might be used by power scale governors @@ -2522,6 +2526,7 @@ _slumber(struct kgsl_device *device) /* fall through */ case KGSL_STATE_NAP: del_timer_sync(&device->idle_timer); + kgsl_pwrscale_midframe_timer_cancel(device); if (device->pwrctrl.thermal_cycle == CYCLE_ACTIVE) { device->pwrctrl.thermal_cycle = CYCLE_ENABLE; del_timer_sync(&device->pwrctrl.thermal_timer); diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c index 85cd29b5364e..413a3098b0ef 100644 --- a/drivers/gpu/msm/kgsl_pwrscale.c +++ b/drivers/gpu/msm/kgsl_pwrscale.c @@ -13,6 +13,7 @@ #include #include +#include #include "kgsl.h" #include "kgsl_pwrscale.h" @@ -37,6 +38,18 @@ static struct kgsl_popp popp_param[POPP_MAX] = { {0, 0}, }; +/** +* struct kgsl_midframe_info - midframe power stats sampling info +* @timer - midframe sampling timer +* @timer_check_ws - Updates powerstats on midframe expiry +* @device - pointer to kgsl_device +*/ +static struct kgsl_midframe_info { + struct hrtimer timer; + struct work_struct timer_check_ws; + struct kgsl_device *device; +} *kgsl_midframe = NULL; + static void do_devfreq_suspend(struct work_struct *work); static void do_devfreq_resume(struct work_struct *work); static void do_devfreq_notify(struct work_struct *work); @@ -183,9 +196,57 @@ void kgsl_pwrscale_update(struct kgsl_device *device) if (device->state != KGSL_STATE_SLUMBER) queue_work(device->pwrscale.devfreq_wq, &device->pwrscale.devfreq_notify_ws); + + kgsl_pwrscale_midframe_timer_restart(device); } EXPORT_SYMBOL(kgsl_pwrscale_update); +void kgsl_pwrscale_midframe_timer_restart(struct kgsl_device *device) +{ + if (kgsl_midframe) { + WARN_ON(!mutex_is_locked(&device->mutex)); + + /* If the timer is already running, stop it */ + if (hrtimer_active(&kgsl_midframe->timer)) + hrtimer_cancel( + &kgsl_midframe->timer); + + hrtimer_start(&kgsl_midframe->timer, + ns_to_ktime(KGSL_GOVERNOR_CALL_INTERVAL + * NSEC_PER_USEC), HRTIMER_MODE_REL); + } +} +EXPORT_SYMBOL(kgsl_pwrscale_midframe_timer_restart); + +void kgsl_pwrscale_midframe_timer_cancel(struct kgsl_device *device) +{ + if (kgsl_midframe) { + WARN_ON(!mutex_is_locked(&device->mutex)); + hrtimer_cancel(&kgsl_midframe->timer); + } +} +EXPORT_SYMBOL(kgsl_pwrscale_midframe_timer_cancel); + +static void kgsl_pwrscale_midframe_timer_check(struct work_struct *work) +{ + struct kgsl_device *device = kgsl_midframe->device; + + mutex_lock(&device->mutex); + if (device->state == KGSL_STATE_ACTIVE) + kgsl_pwrscale_update(device); + mutex_unlock(&device->mutex); +} + +static enum hrtimer_restart kgsl_pwrscale_midframe_timer(struct hrtimer *timer) +{ + struct kgsl_device *device = kgsl_midframe->device; + + queue_work(device->pwrscale.devfreq_wq, + &kgsl_midframe->timer_check_ws); + + return HRTIMER_NORESTART; +} + /* * kgsl_pwrscale_disable - temporarily disable the governor * @device: The device @@ -852,6 +913,17 @@ int kgsl_pwrscale_init(struct device *dev, const char *governor) data->bin.ctxt_aware_busy_penalty = 12000; } + if (of_property_read_bool(device->pdev->dev.of_node, + "qcom,enable-midframe-timer")) { + kgsl_midframe = kzalloc( + sizeof(struct kgsl_midframe_info), GFP_KERNEL); + hrtimer_init(&kgsl_midframe->timer, + CLOCK_MONOTONIC, HRTIMER_MODE_REL); + kgsl_midframe->timer.function = + kgsl_pwrscale_midframe_timer; + kgsl_midframe->device = device; + } + /* * If there is a separate GX power rail, allow * independent modification to its voltage through @@ -900,6 +972,9 @@ int kgsl_pwrscale_init(struct device *dev, const char *governor) INIT_WORK(&pwrscale->devfreq_suspend_ws, do_devfreq_suspend); INIT_WORK(&pwrscale->devfreq_resume_ws, do_devfreq_resume); INIT_WORK(&pwrscale->devfreq_notify_ws, do_devfreq_notify); + if (kgsl_midframe) + INIT_WORK(&kgsl_midframe->timer_check_ws, + kgsl_pwrscale_midframe_timer_check); pwrscale->next_governor_call = ktime_add_us(ktime_get(), KGSL_GOVERNOR_CALL_INTERVAL); @@ -940,9 +1015,13 @@ void kgsl_pwrscale_close(struct kgsl_device *device) pwrscale = &device->pwrscale; if (!pwrscale->devfreqptr) return; + + kgsl_pwrscale_midframe_timer_cancel(device); flush_workqueue(pwrscale->devfreq_wq); destroy_workqueue(pwrscale->devfreq_wq); devfreq_remove_device(device->pwrscale.devfreqptr); + kfree(kgsl_midframe); + kgsl_midframe = NULL; device->pwrscale.devfreqptr = NULL; srcu_cleanup_notifier_head(&device->pwrscale.nh); for (i = 0; i < KGSL_PWREVENT_MAX; i++) diff --git a/drivers/gpu/msm/kgsl_pwrscale.h b/drivers/gpu/msm/kgsl_pwrscale.h index 0756a4490f22..184bfd1a2692 100644 --- a/drivers/gpu/msm/kgsl_pwrscale.h +++ b/drivers/gpu/msm/kgsl_pwrscale.h @@ -122,6 +122,9 @@ void kgsl_pwrscale_busy(struct kgsl_device *device); void kgsl_pwrscale_sleep(struct kgsl_device *device); void kgsl_pwrscale_wake(struct kgsl_device *device); +void kgsl_pwrscale_midframe_timer_restart(struct kgsl_device *device); +void kgsl_pwrscale_midframe_timer_cancel(struct kgsl_device *device); + void kgsl_pwrscale_enable(struct kgsl_device *device); void kgsl_pwrscale_disable(struct kgsl_device *device, bool turbo); From 6d97e2ef40b749ac17a7e41fa4e7d7046f171f99 Mon Sep 17 00:00:00 2001 From: Girish Mahadevan Date: Tue, 26 Jul 2016 16:13:13 -0600 Subject: [PATCH 48/73] spi: spi_qsd: Don't restrict first transfer in FIFO mode In FIFO mode before putting the core in run state the driver currently only writes a word of data if the payload size is more than the FIFO size. Instead always write FIFO worth of data before moving the core to run state. Change-Id: I47db9f66c95846dbff882f631b915655c33c3d55 Signed-off-by: Mukesh Kumar Savaliya --- drivers/spi/spi_qsd.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/spi/spi_qsd.h b/drivers/spi/spi_qsd.h index fb906939c03a..393e59d4215f 100644 --- a/drivers/spi/spi_qsd.h +++ b/drivers/spi/spi_qsd.h @@ -515,10 +515,7 @@ static inline int msm_spi_prepare_for_write(struct msm_spi *dd) static inline void msm_spi_start_write(struct msm_spi *dd, u32 read_count) { - if (read_count <= dd->input_fifo_size) - msm_spi_write_rmn_to_fifo(dd); - else - msm_spi_write_word_to_fifo(dd); + msm_spi_write_rmn_to_fifo(dd); } static inline void msm_spi_set_write_count(struct msm_spi *dd, int val) From 5207bf3492f9e48c9e45fbe9cac65ae292bfe2ca Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Wed, 14 Dec 2016 15:05:22 -0800 Subject: [PATCH 49/73] power_supply: Add SOC_REPORTING_READY property Add SOC_REORTING_READY property to indicate if the SOC is ready to be reported. Change-Id: I53ac153ba9f7ae81bb0657b17e0e798fd3fe4f48 Signed-off-by: Subbaraman Narayanamurthy --- drivers/power/power_supply_sysfs.c | 1 + include/linux/power_supply.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index a4aee80798e4..83b75fcd257e 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -278,6 +278,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(parallel_percent), POWER_SUPPLY_ATTR(pe_start), POWER_SUPPLY_ATTR(set_ship_mode), + POWER_SUPPLY_ATTR(soc_reporting_ready), /* Local extensions of type int64_t */ POWER_SUPPLY_ATTR(charge_counter_ext), /* Properties of type `const char *' */ diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 9b6359241018..20280ff20e52 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -227,6 +227,7 @@ enum power_supply_property { POWER_SUPPLY_PROP_PARALLEL_PERCENT, POWER_SUPPLY_PROP_PE_START, POWER_SUPPLY_PROP_SET_SHIP_MODE, + POWER_SUPPLY_PROP_SOC_REPORTING_READY, /* Local extensions of type int64_t */ POWER_SUPPLY_PROP_CHARGE_COUNTER_EXT, /* Properties of type `const char *' */ From a38365351b82cc698a3144b70486aafe1c3e91eb Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Wed, 14 Dec 2016 15:10:15 -0800 Subject: [PATCH 50/73] power: qpnp-fg-gen3: add SOC_REPORTING_READY property Add SOC_REPORTING_READY property which indicates when the SOC reporting is ready from FG driver. This can be read by healthd daemon during its start. Change-Id: I415e322e99bacd61c4e9ac921643d87d3eec4b3e Signed-off-by: Subbaraman Narayanamurthy --- drivers/power/qcom-charger/fg-core.h | 1 + drivers/power/qcom-charger/qpnp-fg-gen3.c | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/power/qcom-charger/fg-core.h b/drivers/power/qcom-charger/fg-core.h index d8b6754a465f..6f8266a3161c 100644 --- a/drivers/power/qcom-charger/fg-core.h +++ b/drivers/power/qcom-charger/fg-core.h @@ -335,6 +335,7 @@ struct fg_chip { bool recharge_soc_adjusted; bool ki_coeff_dischg_en; bool esr_fcc_ctrl_en; + bool soc_reporting_ready; struct completion soc_update; struct completion soc_ready; struct delayed_work profile_load_work; diff --git a/drivers/power/qcom-charger/qpnp-fg-gen3.c b/drivers/power/qcom-charger/qpnp-fg-gen3.c index 22025ac27ffa..7c1ece431beb 100644 --- a/drivers/power/qcom-charger/qpnp-fg-gen3.c +++ b/drivers/power/qcom-charger/qpnp-fg-gen3.c @@ -2050,6 +2050,7 @@ done: fg_notify_charger(chip); chip->profile_loaded = true; + chip->soc_reporting_ready = true; fg_dbg(chip, FG_STATUS, "profile loaded successfully"); out: vote(chip->awake_votable, PROFILE_LOAD, false, 0); @@ -2386,6 +2387,9 @@ static int fg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: rc = fg_get_time_to_empty(chip, &pval->intval); break; + case POWER_SUPPLY_PROP_SOC_REPORTING_READY: + pval->intval = chip->soc_reporting_ready; + break; default: pr_err("unsupported property %d\n", psp); rc = -EINVAL; @@ -2483,6 +2487,7 @@ static enum power_supply_property fg_psy_props[] = { POWER_SUPPLY_PROP_CHARGE_COUNTER, POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, + POWER_SUPPLY_PROP_SOC_REPORTING_READY, }; static const struct power_supply_desc fg_psy_desc = { @@ -2773,9 +2778,11 @@ static irqreturn_t fg_batt_missing_irq_handler(int irq, void *data) chip->profile_available = false; chip->profile_loaded = false; clear_cycle_counter(chip); + chip->soc_reporting_ready = false; } else { rc = fg_get_batt_profile(chip); if (rc < 0) { + chip->soc_reporting_ready = true; pr_err("Error in getting battery profile, rc:%d\n", rc); return IRQ_HANDLED; } @@ -3213,9 +3220,11 @@ static int fg_parse_dt(struct fg_chip *chip) chip->rradc_base = base; rc = fg_get_batt_profile(chip); - if (rc < 0) + if (rc < 0) { + chip->soc_reporting_ready = true; pr_warn("profile for batt_id=%dKOhms not found..using OTP, rc:%d\n", chip->batt_id_ohms / 1000, rc); + } /* Read all the optional properties below */ rc = of_property_read_u32(node, "qcom,fg-cutoff-voltage", &temp); From c9153d1ae836f4509f9e9347289d8b9cd0aed2b9 Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Mon, 31 Oct 2016 12:51:26 -0700 Subject: [PATCH 51/73] qseecom: support listener request for smcinvoke Add a new kernel API to support listener service for smcinvoke. Change-Id: Ifeed957b99d2becd986629f60e145d6fdb717244 Signed-off-by: Zhen Kong --- drivers/misc/qseecom.c | 34 ++++++++++++++++++++++++++++++++++ drivers/misc/qseecom_kernel.h | 2 ++ 2 files changed, 36 insertions(+) diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index 3402a1b581cf..97e69d1ae9e9 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -4361,6 +4361,40 @@ int qseecom_set_bandwidth(struct qseecom_handle *handle, bool high) } EXPORT_SYMBOL(qseecom_set_bandwidth); +int qseecom_process_listener_from_smcinvoke(struct scm_desc *desc) +{ + struct qseecom_registered_app_list dummy_app_entry = { {0} }; + struct qseecom_dev_handle dummy_private_data = {0}; + struct qseecom_command_scm_resp resp; + int ret = 0; + + if (!desc) { + pr_err("desc is NULL\n"); + return -EINVAL; + } + + resp.result = desc->ret[0]; /*req_cmd*/ + resp.resp_type = desc->ret[1]; /*app_id*/ + resp.data = desc->ret[2]; /*listener_id*/ + + dummy_private_data.client.app_id = desc->ret[1]; + dummy_app_entry.app_id = desc->ret[1]; + + mutex_lock(&app_access_lock); + ret = __qseecom_process_reentrancy(&resp, &dummy_app_entry, + &dummy_private_data); + mutex_unlock(&app_access_lock); + if (ret) + pr_err("Failed to req cmd %d lsnr %d on app %d, ret = %d\n", + (int)desc->ret[0], (int)desc->ret[2], + (int)desc->ret[1], ret); + desc->ret[0] = resp.result; + desc->ret[1] = resp.resp_type; + desc->ret[2] = resp.data; + return ret; +} +EXPORT_SYMBOL(qseecom_process_listener_from_smcinvoke); + static int qseecom_send_resp(void) { qseecom.send_resp_flag = 1; diff --git a/drivers/misc/qseecom_kernel.h b/drivers/misc/qseecom_kernel.h index ca0205560875..8f981903c3a1 100644 --- a/drivers/misc/qseecom_kernel.h +++ b/drivers/misc/qseecom_kernel.h @@ -14,6 +14,7 @@ #define __QSEECOM_KERNEL_H_ #include +#include #define QSEECOM_ALIGN_SIZE 0x40 #define QSEECOM_ALIGN_MASK (QSEECOM_ALIGN_SIZE - 1) @@ -38,5 +39,6 @@ int qseecom_shutdown_app(struct qseecom_handle **handle); int qseecom_send_command(struct qseecom_handle *handle, void *send_buf, uint32_t sbuf_len, void *resp_buf, uint32_t rbuf_len); int qseecom_set_bandwidth(struct qseecom_handle *handle, bool high); +int qseecom_process_listener_from_smcinvoke(struct scm_desc *desc); #endif /* __QSEECOM_KERNEL_H_ */ From 6f19ae882800a436555935925d0db9549ec2082e Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Tue, 22 Nov 2016 14:57:35 -0800 Subject: [PATCH 52/73] smcinvoke: support listener service request Make change to support listener service request from mink object. Change-Id: I9a707d953a85c16c9c5be82fd36960b49da36e3c Signed-off-by: Zhen Kong --- drivers/soc/qcom/smcinvoke.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/soc/qcom/smcinvoke.c b/drivers/soc/qcom/smcinvoke.c index a1344f0780b0..a55d1a9b95b7 100644 --- a/drivers/soc/qcom/smcinvoke.c +++ b/drivers/soc/qcom/smcinvoke.c @@ -22,6 +22,8 @@ #include #include #include "smcinvoke_object.h" +#include +#include "../../misc/qseecom_kernel.h" #define SMCINVOKE_TZ_PARAM_ID 0x224 #define SMCINVOKE_TZ_CMD 0x32000600 @@ -198,6 +200,12 @@ static int prepare_send_scm_msg(const uint8_t *in_buf, size_t in_buf_len, dmac_flush_range(out_buf, out_buf + outbuf_flush_size); ret = scm_call2(SMCINVOKE_TZ_CMD, &desc); + + /* process listener request */ + if (!ret && (desc.ret[0] == QSEOS_RESULT_INCOMPLETE || + desc.ret[0] == QSEOS_RESULT_BLOCKED_ON_LISTENER)) + ret = qseecom_process_listener_from_smcinvoke(&desc); + *smcinvoke_result = (int32_t)desc.ret[1]; if (ret || desc.ret[1] || desc.ret[2] || desc.ret[0]) { pr_err("SCM call failed with ret val = %d %d %d %d\n", From 0e39e5e314a49f210182688a0d91d51d7849d4d2 Mon Sep 17 00:00:00 2001 From: Srinivas Ramana Date: Thu, 22 Dec 2016 16:13:55 +0530 Subject: [PATCH 53/73] ARM: dts: msm: set rcu_expedited for msmfalcon and msmtriton The commit b093be62e8246ece ("ARM: dts: msm: set rcu_expedited for msm chisets") enables rcu_expedited to mitigate performance issues. Enable this for msmfalcon and msmtriton as well. Change-Id: Ic64d89b960c5effada93118d67a30cc051640be2 Signed-off-by: Srinivas Ramana --- arch/arm/boot/dts/qcom/msmfalcon.dtsi | 1 + arch/arm/boot/dts/qcom/msmtriton.dtsi | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmfalcon.dtsi index edea1eea6752..a8e6c3aa0625 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon.dtsi @@ -32,6 +32,7 @@ chosen { stdout-path = "serial0"; + bootargs = "rcupdate.rcu_expedited=1"; }; psci { diff --git a/arch/arm/boot/dts/qcom/msmtriton.dtsi b/arch/arm/boot/dts/qcom/msmtriton.dtsi index ed58d5d3c683..9a7aac72de38 100644 --- a/arch/arm/boot/dts/qcom/msmtriton.dtsi +++ b/arch/arm/boot/dts/qcom/msmtriton.dtsi @@ -30,6 +30,7 @@ chosen { stdout-path = "serial0"; + bootargs = "rcupdate.rcu_expedited=1"; }; psci { From d2d4c446285d23cc01cd9414cbbdefee01e5639b Mon Sep 17 00:00:00 2001 From: Liangliang Lu Date: Fri, 23 Dec 2016 14:05:33 +0800 Subject: [PATCH 54/73] RM: dts: Update SD card Detect GPIO for msmfalcon Update SD card detect gpio for msmfalcon. Remove wrong pin mux on GPIO_54 and change cd-gpios to GPIO_95. CRs-Fixed: 1100528 Change-Id: I1fd7b7e7324b79544608a9d9ce73aa53608d1f3e Signed-off-by: Liangliang Lu --- ...msm8998-v2.1-interposer-msmfalcon-qrd.dtsi | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi index dcfb851cd116..512b996f638b 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi @@ -72,30 +72,6 @@ status = "ok"; }; -&sdc2_cd_on { - mux { - pins = "gpio54"; - }; - - config { - pins = "gpio54"; - /delete-property/ bias-pull-up; - bias-disable; - }; -}; - -&sdc2_cd_off { - mux { - pins = "gpio54"; - }; - - config { - pins = "gpio54"; - /delete-property/ bias-pull-up; - bias-disable; - }; -}; - &sdhc_2 { vdd-supply = <&pm2falcon_l5>; qcom,vdd-voltage-level = <2950000 2950000>; @@ -113,7 +89,7 @@ 50000000 100000000 200000000>; qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104"; - cd-gpios = <&tlmm 54 0x0>; + cd-gpios = <&tlmm 95 0x0>; status = "ok"; }; From 73b5dafa887a528bdc6ece4f495b8c9f8ae28de8 Mon Sep 17 00:00:00 2001 From: Vevek Venkatesan Date: Fri, 23 Dec 2016 11:34:32 +0530 Subject: [PATCH 55/73] input: misc: fix heap overflow issue in hbtp_input.c Add the boundary check for ABS code before setting ABS params, to avoid heap overflow. Change-Id: I6aad9916c92d2f775632406374dbb803063148de Signed-off-by: Vevek Venkatesan --- drivers/input/misc/hbtp_input.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/input/misc/hbtp_input.c b/drivers/input/misc/hbtp_input.c index 05cd1edefb7f..1df5d8812991 100644 --- a/drivers/input/misc/hbtp_input.c +++ b/drivers/input/misc/hbtp_input.c @@ -208,9 +208,13 @@ static int hbtp_input_create_input_dev(struct hbtp_input_absinfo *absinfo) input_mt_init_slots(input_dev, HBTP_MAX_FINGER, 0); for (i = 0; i <= ABS_MT_LAST - ABS_MT_FIRST; i++) { abs = absinfo + i; - if (abs->active) - input_set_abs_params(input_dev, abs->code, + if (abs->active) { + if (abs->code >= 0 && abs->code < ABS_CNT) + input_set_abs_params(input_dev, abs->code, abs->minimum, abs->maximum, 0, 0); + else + pr_err("%s: ABS code out of bound\n", __func__); + } } if (hbtp->override_disp_coords) { From cd753f0c135a32ece6d6c07fc405db16beb8b558 Mon Sep 17 00:00:00 2001 From: Sarada Prasanna Garnayak Date: Thu, 1 Dec 2016 18:51:56 +0530 Subject: [PATCH 56/73] ARM: dts: msm: update icnss device node for msm8998-interposer 1. Status enabled for icnss platform driver probe. 2. Added smmu sid for wlan copy engine. 3. Added vadc and adc_tm voltage regulator entry for wlan calibration data. CRs-Fixed: 1104976 Change-Id: Ic8c9657752271026d796ecd6c3b9f9f46f831f37 Signed-off-by: Sarada Prasanna Garnayak --- arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi index 5b4dda445ff3..347b924749fd 100644 --- a/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi @@ -2886,7 +2886,6 @@ }; qcom,icnss@18800000 { - status = "disabled"; compatible = "qcom,icnss"; reg = <0x18800000 0x800000>, <0x10AC000 0x20>, @@ -2894,6 +2893,8 @@ <0xb0000000 0x10000>; reg-names = "membase", "mpm_config", "smmu_iova_base", "smmu_iova_ipa"; + iommus = <&anoc2_smmu 0x1900>, + <&anoc2_smmu 0x1901>; interrupts = <0 413 0 /* CE0 */ >, <0 414 0 /* CE1 */ >, <0 415 0 /* CE2 */ >, @@ -2907,6 +2908,8 @@ <0 424 0 /* CE10 */ >, <0 425 0 /* CE11 */ >; qcom,wlan-msa-memory = <0x100000>; + qcom,icnss-vadc = <&pmfalcon_vadc>; + qcom,icnss-adc_tm = <&pmfalcon_adc_tm>; }; tspp: msm_tspp@0c1e7000 { From babcc512ba6b3091e64f509dddccc2c60a2de0ba Mon Sep 17 00:00:00 2001 From: Ashay Jaiswal Date: Thu, 22 Dec 2016 23:09:46 +0530 Subject: [PATCH 57/73] ARM: dts: msm: add support of PM3FALCON based MSMFALCON platform MSMFALCON platform can support either PM2FALCON or PM3FALCON PMICs, add support for the same. CRs-Fixed: 1104886 Change-Id: Ic44359e224e0f9070238748bd9b16eed35974ba6 Signed-off-by: Ashay Jaiswal --- arch/arm/boot/dts/qcom/Makefile | 22 ++- arch/arm/boot/dts/qcom/apqfalcon-cdp.dts | 4 +- arch/arm/boot/dts/qcom/apqfalcon-mtp.dts | 4 +- .../boot/dts/qcom/apqfalcon-pm3falcon-cdp.dts | 25 +++ .../boot/dts/qcom/apqfalcon-pm3falcon-mtp.dts | 25 +++ .../boot/dts/qcom/apqfalcon-pm3falcon-rcm.dts | 25 +++ arch/arm/boot/dts/qcom/apqfalcon-rcm.dts | 4 +- arch/arm/boot/dts/qcom/msmfalcon-cdp.dts | 4 +- .../dts/qcom/msmfalcon-internal-codec-cdp.dts | 4 +- .../dts/qcom/msmfalcon-internal-codec-mtp.dts | 4 +- ...msmfalcon-internal-codec-pm3falcon-cdp.dts | 25 +++ ...msmfalcon-internal-codec-pm3falcon-mtp.dts | 25 +++ ...msmfalcon-internal-codec-pm3falcon-rcm.dts | 25 +++ .../dts/qcom/msmfalcon-internal-codec-rcm.dts | 4 +- arch/arm/boot/dts/qcom/msmfalcon-mtp.dts | 4 +- .../boot/dts/qcom/msmfalcon-pm3falcon-cdp.dts | 25 +++ .../boot/dts/qcom/msmfalcon-pm3falcon-mtp.dts | 25 +++ .../boot/dts/qcom/msmfalcon-pm3falcon-qrd.dts | 25 +++ .../boot/dts/qcom/msmfalcon-pm3falcon-rcm.dts | 25 +++ .../dts/qcom/msmfalcon-pm3falcon-rumi.dts | 146 ++++++++++++++++++ .../boot/dts/qcom/msmfalcon-pm3falcon-sim.dts | 111 +++++++++++++ arch/arm/boot/dts/qcom/msmfalcon-qrd.dts | 4 +- arch/arm/boot/dts/qcom/msmfalcon-rcm.dts | 4 +- arch/arm/boot/dts/qcom/msmfalcon-rumi.dts | 4 +- arch/arm/boot/dts/qcom/msmfalcon-sim.dts | 4 +- 25 files changed, 560 insertions(+), 17 deletions(-) create mode 100644 arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-cdp.dts create mode 100644 arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-mtp.dts create mode 100644 arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-rcm.dts create mode 100644 arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-cdp.dts create mode 100644 arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-mtp.dts create mode 100644 arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-rcm.dts create mode 100644 arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-cdp.dts create mode 100644 arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-mtp.dts create mode 100644 arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-qrd.dts create mode 100644 arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-rcm.dts create mode 100644 arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-rumi.dts create mode 100644 arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-sim.dts diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile index 4293b1929794..ed676188102b 100644 --- a/arch/arm/boot/dts/qcom/Makefile +++ b/arch/arm/boot/dts/qcom/Makefile @@ -135,17 +135,29 @@ dtb-$(CONFIG_ARCH_MSM8998) += msm8998-sim.dtb \ dtb-$(CONFIG_ARCH_MSMHAMSTER) += msmhamster-rumi.dtb dtb-$(CONFIG_ARCH_MSMFALCON) += msmfalcon-sim.dtb \ - msmfalcon-rumi.dtb \ - msmfalcon-cdp.dtb \ msmfalcon-internal-codec-cdp.dtb \ - msmfalcon-mtp.dtb \ msmfalcon-internal-codec-mtp.dtb \ - msmfalcon-rcm.dtb \ msmfalcon-internal-codec-rcm.dtb \ + msmfalcon-cdp.dtb \ + msmfalcon-mtp.dtb \ msmfalcon-qrd.dtb \ + msmfalcon-rcm.dtb \ + msmfalcon-rumi.dtb \ + msmfalcon-pm3falcon-cdp.dtb \ + msmfalcon-pm3falcon-mtp.dtb \ + msmfalcon-pm3falcon-qrd.dtb \ + msmfalcon-pm3falcon-rcm.dtb \ + msmfalcon-pm3falcon-rumi.dtb \ + msmfalcon-internal-codec-pm3falcon-cdp.dtb \ + msmfalcon-internal-codec-pm3falcon-mtp.dtb \ + msmfalcon-internal-codec-pm3falcon-rcm.dtb \ + msmfalcon-pm3falcon-sim.dtb \ apqfalcon-cdp.dtb \ apqfalcon-mtp.dtb \ - apqfalcon-rcm.dtb + apqfalcon-rcm.dtb \ + apqfalcon-pm3falcon-cdp.dtb \ + apqfalcon-pm3falcon-mtp.dtb \ + apqfalcon-pm3falcon-rcm.dtb dtb-$(CONFIG_ARCH_MSMTRITON) += msmtriton-rumi.dtb diff --git a/arch/arm/boot/dts/qcom/apqfalcon-cdp.dts b/arch/arm/boot/dts/qcom/apqfalcon-cdp.dts index 9ed26e5ff0aa..fc449860da0d 100644 --- a/arch/arm/boot/dts/qcom/apqfalcon-cdp.dts +++ b/arch/arm/boot/dts/qcom/apqfalcon-cdp.dts @@ -17,7 +17,9 @@ #include "msmfalcon-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ FALCON CDP"; + model = "Qualcomm Technologies, Inc. APQ FALCON PMFALCON + PM2FALCON CDP"; compatible = "qcom,apqfalcon-cdp", "qcom,apqfalcon", "qcom,cdp"; qcom,board-id = <1 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/apqfalcon-mtp.dts b/arch/arm/boot/dts/qcom/apqfalcon-mtp.dts index 74e4fc8154a9..c4f6e9fb30b9 100644 --- a/arch/arm/boot/dts/qcom/apqfalcon-mtp.dts +++ b/arch/arm/boot/dts/qcom/apqfalcon-mtp.dts @@ -17,7 +17,9 @@ #include "msmfalcon-mtp.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ FALCON MTP"; + model = "Qualcomm Technologies, Inc. APQ FALCON PMFALCON + PM2FALCON MTP"; compatible = "qcom,apqfalcon-mtp", "qcom,apqfalcon", "qcom,mtp"; qcom,board-id = <8 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-cdp.dts b/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-cdp.dts new file mode 100644 index 000000000000..851533931a61 --- /dev/null +++ b/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-cdp.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, 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. + */ + + +/dts-v1/; + +#include "apqfalcon.dtsi" +#include "msmfalcon-cdp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. APQ FALCON PMFALCON + PM3FALCON CDP"; + compatible = "qcom,apqfalcon-cdp", "qcom,apqfalcon", "qcom,cdp"; + qcom,board-id = <1 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-mtp.dts b/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-mtp.dts new file mode 100644 index 000000000000..e7e8aeb9c2aa --- /dev/null +++ b/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-mtp.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, 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. + */ + + +/dts-v1/; + +#include "apqfalcon.dtsi" +#include "msmfalcon-mtp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. APQ FALCON PMFALCON + PM3FALCON MTP"; + compatible = "qcom,apqfalcon-mtp", "qcom,apqfalcon", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-rcm.dts b/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-rcm.dts new file mode 100644 index 000000000000..68c4bd724ccd --- /dev/null +++ b/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-rcm.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, 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. + */ + + +/dts-v1/; + +#include "apqfalcon.dtsi" +#include "msmfalcon-cdp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. APQ FALCON PMFALCON + PM3FALCON RCM"; + compatible = "qcom,apqfalcon-cdp", "qcom,apqfalcon", "qcom,cdp"; + qcom,board-id = <21 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/apqfalcon-rcm.dts b/arch/arm/boot/dts/qcom/apqfalcon-rcm.dts index 52ff518f4ce4..8f4b164c55ca 100644 --- a/arch/arm/boot/dts/qcom/apqfalcon-rcm.dts +++ b/arch/arm/boot/dts/qcom/apqfalcon-rcm.dts @@ -17,7 +17,9 @@ #include "msmfalcon-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ FALCON RCM"; + model = "Qualcomm Technologies, Inc. APQ FALCON PMFALCON + PM2FALCON RCM"; compatible = "qcom,apqfalcon-cdp", "qcom,apqfalcon", "qcom,cdp"; qcom,board-id = <21 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-cdp.dts b/arch/arm/boot/dts/qcom/msmfalcon-cdp.dts index 76fa0bbc0fe8..ddcea8653983 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-cdp.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-cdp.dts @@ -17,7 +17,9 @@ #include "msmfalcon-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON CDP"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON CDP"; compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; qcom,board-id = <1 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-cdp.dts b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-cdp.dts index 108328bd91f0..101408b594db 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-cdp.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-cdp.dts @@ -17,7 +17,9 @@ #include "msmfalcon-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON Int. Audio Codec CDP"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON Int. Audio Codec CDP"; compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; qcom,board-id = <1 1>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-mtp.dts b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-mtp.dts index 3697ee8f97a0..d642648004fc 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-mtp.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-mtp.dts @@ -17,7 +17,9 @@ #include "msmfalcon-mtp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON Int. Audio Codec MTP"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON Int. Audio Codec MTP"; compatible = "qcom,msmfalcon-mtp", "qcom,msmfalcon", "qcom,mtp"; qcom,board-id = <8 1>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-cdp.dts b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-cdp.dts new file mode 100644 index 000000000000..fe91109a4a07 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-cdp.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, 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. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-cdp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON Int. Audio Codec CDP"; + compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; + qcom,board-id = <1 1>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-mtp.dts b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-mtp.dts new file mode 100644 index 000000000000..0653e898ec7d --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-mtp.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, 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. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-mtp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON Int. Audio Codec MTP"; + compatible = "qcom,msmfalcon-mtp", "qcom,msmfalcon", "qcom,mtp"; + qcom,board-id = <8 1>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-rcm.dts b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-rcm.dts new file mode 100644 index 000000000000..cb2b2239588d --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-rcm.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, 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. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-cdp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON Int. Audio Codec RCM"; + compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; + qcom,board-id = <21 1>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-rcm.dts b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-rcm.dts index bbdc41b97574..6bc9a3c7738f 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-rcm.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-rcm.dts @@ -17,7 +17,9 @@ #include "msmfalcon-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON Int. Audio Codec RCM"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON Int. Audio Codec RCM"; compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; qcom,board-id = <21 1>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-mtp.dts b/arch/arm/boot/dts/qcom/msmfalcon-mtp.dts index 1d4aaa2333cb..cefe0d7c275b 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-mtp.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-mtp.dts @@ -17,7 +17,9 @@ #include "msmfalcon-mtp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON MTP"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON MTP"; compatible = "qcom,msmfalcon-mtp", "qcom,msmfalcon", "qcom,mtp"; qcom,board-id = <8 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-cdp.dts b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-cdp.dts new file mode 100644 index 000000000000..3d3f8682941f --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-cdp.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, 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. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-cdp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON CDP"; + compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; + qcom,board-id = <1 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-mtp.dts b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-mtp.dts new file mode 100644 index 000000000000..4e6bb7336f2b --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-mtp.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, 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. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-mtp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON MTP"; + compatible = "qcom,msmfalcon-mtp", "qcom,msmfalcon", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-qrd.dts b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-qrd.dts new file mode 100644 index 000000000000..e2d45f0d151e --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-qrd.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, 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. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-qrd.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON QRD"; + compatible = "qcom,msmfalcon-qrd", "qcom,msmfalcon", "qcom,qrd"; + qcom,board-id = <0x1000b 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-rcm.dts b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-rcm.dts new file mode 100644 index 000000000000..c48124120d61 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-rcm.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, 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. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-cdp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON RCM"; + compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; + qcom,board-id = <21 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-rumi.dts b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-rumi.dts new file mode 100644 index 000000000000..b81a92a4aa7c --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-rumi.dts @@ -0,0 +1,146 @@ +/* Copyright (c) 2016, 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. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-pinctrl.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON RUMI"; + compatible = "qcom,msmfalcon-rumi", "qcom,msmfalcon", "qcom,rumi"; + qcom,board-id = <15 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; + + chosen { + bootargs = "lpm_levels.sleep_disabled=1"; + }; +}; + +&usb3 { + /delete-property/ USB3_GDSC-supply; + /delete-property/ extcon; + dwc3@a800000 { + maximum-speed = "high-speed"; + }; +}; + +&ssphy { + compatible = "usb-nop-xceiv"; +}; + +&qusb_phy0 { + reg = <0x0a928000 0x8000>, + <0x0a8f8800 0x400>, + <0x0a920000 0x100>; + reg-names = "qusb_phy_base", + "qscratch_base", + "emu_phy_base"; + qcom,emulation; + qcom,qusb-phy-init-seq = <0x19 0x1404 + 0x20 0x1414 + 0x79 0x1410 + 0x00 0x1418 + 0x99 0x1404 + 0x04 0x1408 + 0xd9 0x1404>; + qcom,emu-dcm-reset-seq = <0x100000 0x20 + 0x0 0x20 + 0x1a0 0x20 + 0x5 0x14>; +}; + +&uartblsp1dm1 { + status = "ok"; + pinctrl-names = "default"; + pinctrl-0 = <&uart_console_active>; +}; + +&sdhc_1 { + /* device core power supply */ + vdd-supply = <&pm2falcon_l4>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 570000>; + + /* device communication power supply */ + vdd-io-supply = <&pmfalcon_l8>; + qcom,vdd-io-always-on; + qcom,vdd-io-lpm-sup; + qcom,vdd-io-voltage-level = <1800000 1800000>; + qcom,vdd-io-current-level = <200 325000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>; + + qcom,clk-rates = <400000 20000000 25000000 50000000 192000000 + 384000000>; + + qcom,nonremovable; + qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v"; + + status = "ok"; +}; + +&clock_gcc { + compatible = "qcom,dummycc"; + clock-output-names = "gcc_clocks"; +}; + +&pmfalcon_charger { + status = "disabled"; +}; + +&pmfalcon_fg { + status = "disabled"; +}; + +&clock_gfx { + compatible = "qcom,dummycc"; + clock-output-names = "gfx_clocks"; +}; + +&pmfalcon_pdphy { + status = "disabled"; +}; + +&clock_mmss { + compatible = "qcom,dummycc"; + clock-output-names = "mmss_clocks"; +}; + +&ufsphy1 { + vdda-phy-supply = <&pm2falcon_l1>; + vdda-pll-supply = <&pmfalcon_l10>; + vddp-ref-clk-supply = <&pmfalcon_l1>; + vdda-phy-max-microamp = <51400>; + vdda-pll-max-microamp = <14200>; + vddp-ref-clk-max-microamp = <100>; + vddp-ref-clk-always-on; +}; + +&ufs1 { + vdd-hba-supply = <&gdsc_ufs>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm2falcon_l4>; + vccq2-supply = <&pmfalcon_l8>; + vcc-max-microamp = <500000>; + vccq2-max-microamp = <600000>; + qcom,disable-lpm; +}; + +&clock_debug { + compatible = "qcom,dummycc"; + clock-output-names = "debug_clocks"; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-sim.dts b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-sim.dts new file mode 100644 index 000000000000..b47c1d328201 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-sim.dts @@ -0,0 +1,111 @@ +/* Copyright (c) 2016, 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. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-pinctrl.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON SIM"; + compatible = "qcom,msmfalcon-sim", "qcom,msmfalcon", "qcom,sim"; + qcom,board-id = <16 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; + + chosen { + bootargs = "lpm_levels.sleep_disabled=1"; + }; +}; + +&usb3 { + reg = <0xa800000 0xfc000>; + reg-names = "core_base"; + /delete-property/ extcon; + dwc3@a800000 { + maximum-speed = "high-speed"; + }; +}; + +&ssphy { + compatible = "usb-nop-xceiv"; +}; + +&qusb_phy0 { + compatible = "usb-nop-xceiv"; +}; + +&uartblsp1dm1 { + status = "ok"; + pinctrl-names = "default"; + pinctrl-0 = <&uart_console_active>; +}; + +&sdhc_1 { + /* device core power supply */ + vdd-supply = <&pm2falcon_l4>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 570000>; + + /* device communication power supply */ + vdd-io-supply = <&pmfalcon_l8>; + qcom,vdd-io-always-on; + qcom,vdd-io-lpm-sup; + qcom,vdd-io-voltage-level = <1800000 1800000>; + qcom,vdd-io-current-level = <200 325000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>; + + qcom,clk-rates = <400000 20000000 25000000 50000000 192000000 + 384000000>; + + qcom,nonremovable; + qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v"; + + status = "ok"; +}; + +&pmfalcon_charger { + status = "disabled"; +}; + +&pmfalcon_fg { + status = "disabled"; +}; + +&pmfalcon_pdphy { + status = "disabled"; +}; + +&ufsphy1 { + vdda-phy-supply = <&pm2falcon_l1>; + vdda-pll-supply = <&pmfalcon_l10>; + vddp-ref-clk-supply = <&pmfalcon_l1>; + vdda-phy-max-microamp = <51400>; + vdda-pll-max-microamp = <14200>; + vddp-ref-clk-max-microamp = <100>; + vddp-ref-clk-always-on; + status = "ok"; +}; + +&ufs1 { + vdd-hba-supply = <&gdsc_ufs>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm2falcon_l4>; + vccq2-supply = <&pmfalcon_l8>; + vcc-max-microamp = <500000>; + vccq2-max-microamp = <600000>; + status = "ok"; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-qrd.dts b/arch/arm/boot/dts/qcom/msmfalcon-qrd.dts index 229676f17456..b97fdd18e229 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-qrd.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-qrd.dts @@ -17,7 +17,9 @@ #include "msmfalcon-qrd.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON QRD"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON QRD"; compatible = "qcom,msmfalcon-qrd", "qcom,msmfalcon", "qcom,qrd"; qcom,board-id = <0x1000b 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-rcm.dts b/arch/arm/boot/dts/qcom/msmfalcon-rcm.dts index 140be9311e8a..e4f59c735e70 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-rcm.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-rcm.dts @@ -17,7 +17,9 @@ #include "msmfalcon-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON RCM"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON RCM"; compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; qcom,board-id = <21 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts b/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts index eed69d178fa3..c371ddeda563 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts @@ -17,9 +17,11 @@ #include "msmfalcon-pinctrl.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON RUMI"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON RUMI"; compatible = "qcom,msmfalcon-rumi", "qcom,msmfalcon", "qcom,rumi"; qcom,board-id = <15 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; chosen { bootargs = "lpm_levels.sleep_disabled=1"; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-sim.dts b/arch/arm/boot/dts/qcom/msmfalcon-sim.dts index 80772bab86e4..596aae818fab 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-sim.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-sim.dts @@ -17,9 +17,11 @@ #include "msmfalcon-pinctrl.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON SIM"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON SIM"; compatible = "qcom,msmfalcon-sim", "qcom,msmfalcon", "qcom,sim"; qcom,board-id = <16 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; chosen { bootargs = "lpm_levels.sleep_disabled=1"; From e4aff446e0d448c3350e4ec4a9a4b7da5a7e12a1 Mon Sep 17 00:00:00 2001 From: Xiaogang Cui Date: Thu, 22 Dec 2016 12:16:00 +0800 Subject: [PATCH 58/73] ARM: dts: msm: Add initial support for msm8998 QRD SKUK EVT3 board Add initial device trees for msm8998 QRD SKUK EVT3 board. Change-Id: I476397d88e0f9d2b32ae375afc6f15eca4b9ec95 Signed-off-by: Xiaogang Cui --- arch/arm/boot/dts/qcom/Makefile | 1 + .../dts/qcom/msm8998-v2-qrd-skuk-evt3.dts | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile index 4293b1929794..2fd84d46035a 100644 --- a/arch/arm/boot/dts/qcom/Makefile +++ b/arch/arm/boot/dts/qcom/Makefile @@ -116,6 +116,7 @@ dtb-$(CONFIG_ARCH_MSM8998) += msm8998-sim.dtb \ msm8998-v2-qrd-skuk.dtb \ msm8998-qrd-vr1.dtb \ msm8998-v2-qrd-vr1.dtb \ + msm8998-v2-qrd-skuk-evt3.dtb \ apq8998-mtp.dtb \ apq8998-cdp.dtb \ apq8998-v2-mtp.dtb \ diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts new file mode 100644 index 000000000000..51ff3888bc3d --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts @@ -0,0 +1,23 @@ +/* Copyright (c) 2016, 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. + */ + + +/dts-v1/; + +#include "msm8998-v2.dtsi" +#include "msm8998-qrd-skuk.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8998 V2 SKUK EVT3"; + compatible = "qcom,msm8998-qrd", "qcom,msm8998", "qcom,qrd"; + qcom,board-id = <0x02000b 0x10>; +}; From 485a3c90cd3dd6391ff4a5ed0e2d456872ccc73e Mon Sep 17 00:00:00 2001 From: Tirupathi Reddy Date: Wed, 2 Nov 2016 15:12:10 +0530 Subject: [PATCH 59/73] regulator: cpr4-mmss: Add mmss CPR platform specific driver for msmfalcon The MMSS CPR in msmfalcon requires a slightly different configuration than the existing cpr3 based MMSS CPR instances. Create a new platform specific mmss cpr file for capturing the falcon specific configuration. CRs-Fixed: 1068294 Change-Id: I779074d0aba35827e1a8264385149967cb9973f3 Signed-off-by: Tirupathi Reddy --- .../regulator/cpr4-mmss-ldo-regulator.txt | 321 ++++++++ drivers/regulator/Kconfig | 11 + drivers/regulator/Makefile | 1 + drivers/regulator/cpr4-mmss-ldo-regulator.c | 722 ++++++++++++++++++ 4 files changed, 1055 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/cpr4-mmss-ldo-regulator.txt create mode 100644 drivers/regulator/cpr4-mmss-ldo-regulator.c diff --git a/Documentation/devicetree/bindings/regulator/cpr4-mmss-ldo-regulator.txt b/Documentation/devicetree/bindings/regulator/cpr4-mmss-ldo-regulator.txt new file mode 100644 index 000000000000..41cec67b7627 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/cpr4-mmss-ldo-regulator.txt @@ -0,0 +1,321 @@ +Qualcomm Technologies, Inc. CPR4 Regulator - MMSS LDO Specific Bindings + +MMSS LDO CPR4 controllers each support one CPR thread that monitors the voltage +of the graphics processor (MMSS) supply regulator. The CPR open-loop voltages +are stored in hardware fuses for MMSS CPR4 controllers. However, the CPR target +quotients must be defined in device tree. + +This document describes the MMSS LDO specific CPR4 bindings. + +======================= +Required Node Structure +======================= + +CPR3 regulators must be described in three levels of devices nodes. The first +level describes the CPR3 controller. The second level describes exacly one +hardware thread managed by the controller. The third level describes one or +more logical regulators handled by the CPR thread. + +All platform independent cpr3-regulator binding guidelines defined in +cpr3-regulator.txt also apply to cpr4-mmss-ldo-regulator devices. + +==================================== +First Level Nodes - CPR3 Controllers +==================================== + +MMSS LDO specific properties: +- compatible + Usage: required + Value type: + Definition: should be the following: + "qcom,cpr4-msmfalcon-mmss-ldo-regulator". + +- clocks + Usage: required + Value type: + Definition: Array of clock tuples in which each tuple consists of a + phandle to a clock device and a clock ID number. The + following clocks must be specified: MMSS RBCPR and MMSS + RBCPR AHB. + +- clock-names + Usage: required + Value type: + Definition: Clock names. This list must match up 1-to-1 with the clocks + specified in the 'clocks' property. "core_clk", and "bus_clk" + must be specified. + +- qcom,cpr-step-quot-fixed + Usage: Optional + Value type: + Definition: Fixed step quotient value used by controller for applying + the SDELTA margin adjustments on the programmed target + quotient values. The step quotient is the number of + additional ring oscillator ticks observed for each + qcom,voltage-step increase in vdd-supply output voltage. + Supported values: 0 - 63. + +================================================= +Second Level Nodes - CPR Threads for a Controller +================================================= + +MMSS specific properties: +N/A + +=============================================== +Third Level Nodes - CPR Regulators for a Thread +=============================================== + +MMSS specific properties: +- qcom,cpr-fuse-corners + Usage: required + Value type: + Definition: Specifies the number of fuse corners. This value must be 6 + for msmfalcon GFX LDO. These fuse corners are: MinSVS, + LowSVS, SVS, SVSP, NOM and NOMP. The open-loop voltage fuses + are allocated for LowSVS, SVS, NOM and NOMP corners. The + open-loop voltages for MinSVS and SVSP are derived by + applying fixed offset from LowSVS and NOM open-loop voltages + respectively. The closed-loop offset voltage fuses are + allocated for LowSVS, SVS, NOM and NOMP corners. The MinSVS + and SVSP corners use the closed-loop offset voltage fuses of + LowSVS and NOM corners respectively. + +- qcom,cpr-fuse-combos + Usage: required + Value type: + Definition: Specifies the number of fuse combinations being supported by + the device. This value is utilized by several other + properties. Supported values are 1 up to the maximum + possible for a given regulator type. For MMSS the maximum + supported value is 8. These combos correspond to CPR + revision fuse values from 0 to 7 in order. + +- qcom,mem-acc-voltage + Usage: required if mem-acc-supply is specified for the CPR3 controller + containing this CPR3 regulator + Value type: + Definition: A list of integer tuples which each define the mem-acc-supply + corner for each voltage corner in order from lowest to highest. + + The list must contain qcom,cpr-fuse-combos number of tuples + in which case the tuples are matched to fuse combinations + 1-to-1 or qcom,cpr-speed-bins number of tuples in which case + the tuples are matched to speed bins 1-to-1 or exactly 1 + tuple which is used regardless of the fuse combination and + speed bin found on a given chip. + + Each tuple must be of the length defined in the + corresponding element of the qcom,cpr-corners property or + the qcom,cpr-speed-bins property. A single tuple may only + be specified if all of the corner counts in qcom,cpr-corners + are the same. + +- qcom,cpr-target-quotients + Usage: required + Value type: + Definition: A grouping of integer tuple lists. Each tuple defines the + CPR target quotient for each ring oscillator (RO) for a + given corner. Since CPR3 supports exactly 16 ROs, each + tuple must contain 16 elements corresponding to RO0 through + RO15 in order. If a given RO is unused for a corner, then + its target quotient should be specified as 0. + + Each tuple list in the grouping must meet the same size + requirements as those specified for qcom,mem-acc-voltage + above. The tuples in a given list are ordered from the + lowest corner to the highest corner. + +- qcom,cpr-ro-scaling-factor + Usage: required if qcom,cpr-closed-loop-voltage-adjustment is + specified + Value type: + Definition: The common definition of this property in cpr3-regulator.txt + is accurate for MMSS CPR3 controllers except for this + modification: + + Each tuple list must contain the number of tuples defined in + the corresponding element of the qcom,cpr-corners property + or the qcom,cpr-speed-bins property as opposed to the value + of the qcom,cpr-fuse-corners property. + +- qcom,cpr-fused-closed-loop-voltage-adjustment-map + Usage: optional + Value type: + Definition: A list of integer tuples which each define the CPR fused + corner closed-loop offset adjustment fuse to utilize for + each voltage corner in order from lowest to highest. + + The list must contain qcom,cpr-fuse-combos number of tuples + in which case the tuples are matched to fuse combinations + 1-to-1 or qcom,cpr-speed-bins number of tuples in which case + the tuples are matched to speed bins 1-to-1 or exactly 1 + tuple which is used regardless of the fuse combination and + speed bin found on a given chip. + + Each tuple must be of the length defined in the + corresponding element of the qcom,cpr-corners property or + the qcom,cpr-speed-bins property. A single tuple may only + be specified if all of the corner counts in qcom,cpr-corners + are the same. + + Each tuple element must be either 0 or in the range 1 to + qcom,cpr-fuse-corners. A value of 0 signifies that no fuse + based adjustment should be applied to the fuse corner. + Values 1 to qcom,cpr-fuse-corners denote the specific fuse + corner that should be used by a given voltage corner. + +- qcom,cpr-corner-allow-ldo-mode + Usage: optional + Value type: + Definition: A list of integer tuples which each define the LDO mode + allowed state for each voltage corner in order from lowest + to highest. Each element in the tuple should be either + 0 (LDO mode not allowed) or 1 (LDO mode allowed). + + The list must contain qcom,cpr-fuse-combos number of tuples + in which case the tuples are matched to fuse combinations + 1-to-1 or qcom,cpr-speed-bins number of tuples in which case + the tuples are matched to speed bins 1-to-1 or exactly 1 + tuple which is used regardless of the fuse combination and + speed bin found on a given chip. + + Each tuple must be of the length defined in the + corresponding element of the qcom,cpr-corners property or + the qcom,cpr-speed-bin-corners property. A single tuple may + only be specified if all of the corner counts in + qcom,cpr-corners are the same. + +- qcom,cpr-corner-allow-closed-loop + Usage: optional + Value type: + Definition: A list of integer tuples which each define the CPR + closed-loop operation allowed state for each voltage corner + in order from lowest to highest. Each element in the tuple + should be either 0 (CPR closed-loop operation not allowed) + or 1 (CPR closed-loop operation allowed). + + The list must contain qcom,cpr-fuse-combos number of tuples + in which case the tuples are matched to fuse combinations + 1-to-1 or qcom,cpr-speed-bins number of tuples in which case + the tuples are matched to speed bins 1-to-1 or exactly 1 + tuple which is used regardless of the fuse combination and + speed bin found on a given chip. + + Each tuple must be of the length defined in the + corresponding element of the qcom,cpr-corners property or + the qcom,cpr-speed-bin-corners property. A single tuple may + only be specified if all of the corner counts in + qcom,cpr-corners are the same. + +Note that the qcom,cpr-closed-loop-voltage-fuse-adjustment property is not +meaningful for MMSS LDO CPR3 regulator nodes since target quotients are not +defined in fuses. + +======= +Example +======= + +gfx_cpr: cpr4-ctrl@05061000 { + compatible = "qcom,cpr4-msmfalcon-mmss-ldo-regulator"; + reg = <0x05061000 0x4000>, <0x00784000 0x1000>; + reg-names = "cpr_ctrl", "fuse_base"; + interrupts = ; + interrupt-names = "cpr"; + qcom,cpr-ctrl-name = "gfx"; + + qcom,cpr-sensor-time = <1000>; + qcom,cpr-loop-time = <5000000>; + qcom,cpr-idle-cycles = <15>; + qcom,cpr-step-quot-init-min = <8>; + qcom,cpr-step-quot-init-max = <12>; + qcom,cpr-count-mode = <0>; /* All at once */ + + vdd-supply = <&gfx_stub_vreg>; + mem-acc-supply = <&gfx_mem_acc_vreg>; + system-supply = <&pm2falcon_s3_level>; /* vdd_cx */ + qcom,voltage-step = <5000>; + vdd-thread0-ldo-supply = <&gfx_ldo_vreg>; + + qcom,cpr-enable; + + thread@0 { + qcom,cpr-thread-id = <0>; + qcom,cpr-consecutive-up = <0>; + qcom,cpr-consecutive-down = <2>; + qcom,cpr-up-threshold = <0>; + qcom,cpr-down-threshold = <2>; + + gfx_vreg_corner: regulator { + regulator-name = "gfx_corner"; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + + qcom,cpr-fuse-corners = <6>; + qcom,cpr-fuse-combos = <8>; + qcom,cpr-corners = <7>; + + qcom,cpr-corner-fmax-map = <1 2 3 4 5 6>; + + qcom,cpr-voltage-ceiling = + <584000 644000 724000 788000 + 868000 924000 1068000>; + qcom,cpr-voltage-floor = + <504000 504000 596000 652000 + 712000 744000 1068000>; + + qcom,mem-acc-voltage = <1 1 1 2 2 2 2>; + qcom,system-voltage = + , + , + , + , + , + , + ; + + qcom,corner-frequencies = + <160000000 266000000 370000000 + 465000000 588000000 647000000 + 800000000>; + + qcom,cpr-target-quotients = + <0 0 0 0 0 0 185 179 + 291 299 304 319 0 0 0 0>, + <0 0 0 0 0 0 287 273 + 425 426 443 453 0 0 0 0>, + <0 0 0 0 0 0 414 392 + 584 576 608 612 0 0 0 0>, + <0 0 0 0 0 0 459 431 + 684 644 692 679 0 0 0 0>, + <0 0 0 0 0 0 577 543 + 798 768 823 810 0 0 0 0>, + <0 0 0 0 0 0 669 629 + 886 864 924 911 0 0 0 0>, + <0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0>; + + qcom,cpr-ro-scaling-factor = + < 0 0 0 0 0 0 2035 1917 + 1959 2131 2246 2253 0 0 0 0>, + < 0 0 0 0 0 0 2035 1917 + 1959 2131 2246 2253 0 0 0 0>, + < 0 0 0 0 0 0 2035 1917 + 1959 2131 2246 2253 0 0 0 0>, + < 0 0 0 0 0 0 2035 1917 + 1959 2131 2246 2253 0 0 0 0>, + < 0 0 0 0 0 0 2035 1917 + 1959 2131 2246 2253 0 0 0 0>, + < 0 0 0 0 0 0 2035 1917 + 1959 2131 2246 2253 0 0 0 0>, + < 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0>; + + qcom,cpr-scaled-open-loop-voltage-as-ceiling; + qcom,cpr-corner-ldo-mode-allowed = + <1 1 1 1 1 1 0>; + qcom,cpr-corner-use-closed-loop = + <1 1 1 1 1 1 0>; + }; + }; +}; diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index ba1bf3b5f492..bd2c1a8e7540 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -925,6 +925,17 @@ config REGULATOR_CPRH_KBSS independent voltage supplies. This driver reads both initial voltage and CPR target quotient values out of hardware fuses. +config REGULATOR_CPR4_MMSS_LDO + bool "RBCPR3 regulator for MMSS LDO" + depends on OF + select REGULATOR_CPR3 + help + This driver supports Qualcomm Technologies, Inc. MMSS graphics + processor specific features. The MMSS CPR3 controller only uses one + thread to monitor the MMSS LDO voltage requirements. This driver reads + initial voltage values out of hardware fuses and CPR target quotient + values out of device tree. + config REGULATOR_KRYO bool "Kryo regulator driver" depends on OF diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 79a203418a0b..abd116d3d8af 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -114,6 +114,7 @@ obj-$(CONFIG_REGULATOR_CPR3_HMSS) += cpr3-hmss-regulator.o obj-$(CONFIG_REGULATOR_CPR3_MMSS) += cpr3-mmss-regulator.o obj-$(CONFIG_REGULATOR_CPR4_APSS) += cpr4-apss-regulator.o obj-$(CONFIG_REGULATOR_CPRH_KBSS) += cprh-kbss-regulator.o +obj-$(CONFIG_REGULATOR_CPR4_MMSS_LDO) += cpr4-mmss-ldo-regulator.o obj-$(CONFIG_REGULATOR_QPNP_LABIBB) += qpnp-labibb-regulator.o obj-$(CONFIG_REGULATOR_QPNP_LCDB) += qpnp-lcdb-regulator.o obj-$(CONFIG_REGULATOR_STUB) += stub-regulator.o diff --git a/drivers/regulator/cpr4-mmss-ldo-regulator.c b/drivers/regulator/cpr4-mmss-ldo-regulator.c new file mode 100644 index 000000000000..9fa5c309b02a --- /dev/null +++ b/drivers/regulator/cpr4-mmss-ldo-regulator.c @@ -0,0 +1,722 @@ +/* + * Copyright (c) 2016, 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. + */ + +#define pr_fmt(fmt) "%s: " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cpr3-regulator.h" + +#define MSMFALCON_MMSS_FUSE_CORNERS 6 + +/** + * struct cpr4_msmfalcon_mmss_fuses - MMSS specific fuse data for MSMFALCON + * @init_voltage: Initial (i.e. open-loop) voltage fuse parameter value + * for each fuse corner (raw, not converted to a voltage) + * @offset_voltage: The closed-loop voltage margin adjustment fuse parameter + * value for each fuse corner (raw, not converted to a + * voltage) + * @cpr_fusing_rev: CPR fusing revision fuse parameter value + * @ldo_enable: The ldo enable fuse parameter for each fuse corner + * indicates that VDD_GFX can be configured to LDO mode in + * the corresponding fuse corner. + * @ldo_cpr_cl_enable: A fuse parameter indicates that GFX CPR can be + * configured to operate in closed-loop mode when VDD_GFX + * is configured for LDO sub-regulated mode. + * + * This struct holds the values for all of the fuses read from memory. + */ +struct cpr4_msmfalcon_mmss_fuses { + u64 init_voltage[MSMFALCON_MMSS_FUSE_CORNERS]; + u64 offset_voltage[MSMFALCON_MMSS_FUSE_CORNERS]; + u64 cpr_fusing_rev; + u64 ldo_enable[MSMFALCON_MMSS_FUSE_CORNERS]; + u64 ldo_cpr_cl_enable; +}; + +/* Fuse combos 0 - 7 map to CPR fusing revision 0 - 7 */ +#define CPR4_MSMFALCON_MMSS_FUSE_COMBO_COUNT 8 + +/* + * MSMFALCON MMSS fuse parameter locations: + * + * Structs are organized with the following dimensions: + * Outer: 0 to 3 for fuse corners from lowest to highest corner + * Inner: large enough to hold the longest set of parameter segments which + * fully defines a fuse parameter, +1 (for NULL termination). + * Each segment corresponds to a contiguous group of bits from a + * single fuse row. These segments are concatentated together in + * order to form the full fuse parameter value. The segments for + * a given parameter may correspond to different fuse rows. + */ +static const struct cpr3_fuse_param +msmfalcon_mmss_init_voltage_param[MSMFALCON_MMSS_FUSE_CORNERS][2] = { + {{65, 39, 43}, {} }, + {{65, 39, 43}, {} }, + {{65, 34, 38}, {} }, + {{65, 34, 38}, {} }, + {{65, 29, 33}, {} }, + {{65, 24, 28}, {} }, +}; + +static const struct cpr3_fuse_param msmfalcon_cpr_fusing_rev_param[] = { + {71, 34, 36}, + {}, +}; + +static const struct cpr3_fuse_param +msmfalcon_mmss_offset_voltage_param[MSMFALCON_MMSS_FUSE_CORNERS][2] = { + {{} }, + {{} }, + {{} }, + {{65, 52, 55}, {} }, + {{65, 48, 51}, {} }, + {{65, 44, 47}, {} }, +}; + +static const struct cpr3_fuse_param +msmfalcon_mmss_ldo_enable_param[MSMFALCON_MMSS_FUSE_CORNERS][2] = { + {{73, 62, 62}, {} }, + {{73, 61, 61}, {} }, + {{73, 60, 60}, {} }, + {{73, 59, 59}, {} }, + {{73, 58, 58}, {} }, + {{73, 57, 57}, {} }, +}; + +static const struct cpr3_fuse_param msmfalcon_ldo_cpr_cl_enable_param[] = { + {71, 38, 38}, + {}, +}; + +/* Additional MSMFALCON specific data: */ + +/* Open loop voltage fuse reference voltages in microvolts */ +static const int msmfalcon_mmss_fuse_ref_volt[MSMFALCON_MMSS_FUSE_CORNERS] = { + 584000, + 644000, + 724000, + 788000, + 868000, + 924000, +}; + +#define MSMFALCON_MMSS_FUSE_STEP_VOLT 10000 +#define MSMFALCON_MMSS_OFFSET_FUSE_STEP_VOLT 10000 +#define MSMFALCON_MMSS_VOLTAGE_FUSE_SIZE 5 + +#define MSMFALCON_MMSS_CPR_SENSOR_COUNT 11 + +#define MSMFALCON_MMSS_CPR_CLOCK_RATE 19200000 + +/** + * cpr4_msmfalcon_mmss_read_fuse_data() - load MMSS specific fuse parameter + * values + * @vreg: Pointer to the CPR3 regulator + * + * This function allocates a cpr4_msmfalcon_mmss_fuses struct, fills it with + * values read out of hardware fuses, and finally copies common fuse values + * into the regulator struct. + * + * Return: 0 on success, errno on failure + */ +static int cpr4_msmfalcon_mmss_read_fuse_data(struct cpr3_regulator *vreg) +{ + void __iomem *base = vreg->thread->ctrl->fuse_base; + struct cpr4_msmfalcon_mmss_fuses *fuse; + int i, rc; + + fuse = devm_kzalloc(vreg->thread->ctrl->dev, sizeof(*fuse), GFP_KERNEL); + if (!fuse) + return -ENOMEM; + + rc = cpr3_read_fuse_param(base, msmfalcon_cpr_fusing_rev_param, + &fuse->cpr_fusing_rev); + if (rc) { + cpr3_err(vreg, "Unable to read CPR fusing revision fuse, rc=%d\n", + rc); + return rc; + } + cpr3_info(vreg, "CPR fusing revision = %llu\n", fuse->cpr_fusing_rev); + + rc = cpr3_read_fuse_param(base, msmfalcon_ldo_cpr_cl_enable_param, + &fuse->ldo_cpr_cl_enable); + if (rc) { + cpr3_err(vreg, "Unable to read ldo cpr closed-loop enable fuse, rc=%d\n", + rc); + return rc; + } + + for (i = 0; i < MSMFALCON_MMSS_FUSE_CORNERS; i++) { + rc = cpr3_read_fuse_param(base, + msmfalcon_mmss_init_voltage_param[i], + &fuse->init_voltage[i]); + if (rc) { + cpr3_err(vreg, "Unable to read fuse-corner %d initial voltage fuse, rc=%d\n", + i, rc); + return rc; + } + + rc = cpr3_read_fuse_param(base, + msmfalcon_mmss_offset_voltage_param[i], + &fuse->offset_voltage[i]); + if (rc) { + cpr3_err(vreg, "Unable to read fuse-corner %d offset voltage fuse, rc=%d\n", + i, rc); + return rc; + } + + rc = cpr3_read_fuse_param(base, + msmfalcon_mmss_ldo_enable_param[i], + &fuse->ldo_enable[i]); + if (rc) { + cpr3_err(vreg, "Unable to read fuse-corner %d ldo enable fuse, rc=%d\n", + i, rc); + return rc; + } + } + + vreg->fuse_combo = fuse->cpr_fusing_rev; + if (vreg->fuse_combo >= CPR4_MSMFALCON_MMSS_FUSE_COMBO_COUNT) { + cpr3_err(vreg, "invalid CPR fuse combo = %d found, not in range 0 - %d\n", + vreg->fuse_combo, + CPR4_MSMFALCON_MMSS_FUSE_COMBO_COUNT - 1); + return -EINVAL; + } + + vreg->cpr_rev_fuse = fuse->cpr_fusing_rev; + vreg->fuse_corner_count = MSMFALCON_MMSS_FUSE_CORNERS; + vreg->platform_fuses = fuse; + + return 0; +} + +/** + * cpr3_msmfalcon_mmss_calculate_open_loop_voltages() - calculate the open-loop + * voltage for each corner of a CPR3 regulator + * @vreg: Pointer to the CPR3 regulator + * + * Return: 0 on success, errno on failure + */ +static int cpr4_msmfalcon_mmss_calculate_open_loop_voltages( + struct cpr3_regulator *vreg) +{ + struct cpr4_msmfalcon_mmss_fuses *fuse = vreg->platform_fuses; + int i, rc = 0; + const int *ref_volt; + int *fuse_volt; + + fuse_volt = kcalloc(vreg->fuse_corner_count, sizeof(*fuse_volt), + GFP_KERNEL); + if (!fuse_volt) + return -ENOMEM; + + ref_volt = msmfalcon_mmss_fuse_ref_volt; + for (i = 0; i < vreg->fuse_corner_count; i++) { + fuse_volt[i] = cpr3_convert_open_loop_voltage_fuse(ref_volt[i], + MSMFALCON_MMSS_FUSE_STEP_VOLT, fuse->init_voltage[i], + MSMFALCON_MMSS_VOLTAGE_FUSE_SIZE); + cpr3_info(vreg, "fuse_corner[%d] open-loop=%7d uV\n", + i, fuse_volt[i]); + } + + rc = cpr3_adjust_fused_open_loop_voltages(vreg, fuse_volt); + if (rc) { + cpr3_err(vreg, "fused open-loop voltage adjustment failed, rc=%d\n", + rc); + goto done; + } + + for (i = 1; i < vreg->fuse_corner_count; i++) { + if (fuse_volt[i] < fuse_volt[i - 1]) { + cpr3_debug(vreg, "fuse corner %d voltage=%d uV < fuse corner %d voltage=%d uV; overriding: fuse corner %d voltage=%d\n", + i, fuse_volt[i], i - 1, fuse_volt[i - 1], + i, fuse_volt[i - 1]); + fuse_volt[i] = fuse_volt[i - 1]; + } + } + + for (i = 0; i < vreg->corner_count; i++) + vreg->corner[i].open_loop_volt + = fuse_volt[vreg->corner[i].cpr_fuse_corner]; + + cpr3_debug(vreg, "unadjusted per-corner open-loop voltages:\n"); + for (i = 0; i < vreg->corner_count; i++) + cpr3_debug(vreg, "open-loop[%2d] = %d uV\n", i, + vreg->corner[i].open_loop_volt); + + rc = cpr3_adjust_open_loop_voltages(vreg); + if (rc) + cpr3_err(vreg, "open-loop voltage adjustment failed, rc=%d\n", + rc); + +done: + kfree(fuse_volt); + return rc; +} + +/** + * cpr4_mmss_parse_ldo_mode_data() - Parse the LDO mode enable state for each + * corner of a CPR3 regulator + * @vreg: Pointer to the CPR3 regulator + * + * This function considers 2 sets of data: one set from device node and other + * set from fuses and applies set intersection to decide the final LDO mode + * enable state of each corner. If the device node configuration is not + * specified, then the function applies LDO mode disable for all corners. + * + * Return: 0 on success, errno on failure + */ +static int cpr4_mmss_parse_ldo_mode_data(struct cpr3_regulator *vreg) +{ + struct cpr4_msmfalcon_mmss_fuses *fuse = vreg->platform_fuses; + int i, rc = 0; + u32 *ldo_allowed; + char *prop_str = "qcom,cpr-corner-allow-ldo-mode"; + + if (!of_find_property(vreg->of_node, prop_str, NULL)) { + cpr3_debug(vreg, "%s property is missing. LDO mode is disabled for all corners\n", + prop_str); + return 0; + } + + ldo_allowed = kcalloc(vreg->corner_count, sizeof(*ldo_allowed), + GFP_KERNEL); + if (!ldo_allowed) + return -ENOMEM; + + rc = cpr3_parse_corner_array_property(vreg, prop_str, 1, ldo_allowed); + if (rc) { + cpr3_err(vreg, "%s read failed, rc=%d\n", prop_str, rc); + goto done; + } + + for (i = 0; i < vreg->corner_count; i++) + vreg->corner[i].ldo_mode_allowed + = (ldo_allowed[i] && fuse->ldo_enable[i]); + +done: + kfree(ldo_allowed); + return rc; +} + +/** + * cpr4_mmss_parse_corner_operating_mode() - Parse the CPR closed-loop operation + * enable state for each corner of a CPR3 regulator + * @vreg: Pointer to the CPR3 regulator + * + * This function ensures that closed-loop operation is enabled only for LDO + * mode allowed corners. + * + * Return: 0 on success, errno on failure + */ +static int cpr4_mmss_parse_corner_operating_mode(struct cpr3_regulator *vreg) +{ + struct cpr4_msmfalcon_mmss_fuses *fuse = vreg->platform_fuses; + int i, rc = 0; + u32 *use_closed_loop; + char *prop_str = "qcom,cpr-corner-allow-closed-loop"; + + if (!of_find_property(vreg->of_node, prop_str, NULL)) { + cpr3_debug(vreg, "%s property is missing. Use open-loop for all corners\n", + prop_str); + for (i = 0; i < vreg->corner_count; i++) + vreg->corner[i].use_open_loop = true; + + return 0; + } + + use_closed_loop = kcalloc(vreg->corner_count, sizeof(*use_closed_loop), + GFP_KERNEL); + if (!use_closed_loop) + return -ENOMEM; + + rc = cpr3_parse_corner_array_property(vreg, prop_str, 1, + use_closed_loop); + if (rc) { + cpr3_err(vreg, "%s read failed, rc=%d\n", prop_str, rc); + goto done; + } + + for (i = 0; i < vreg->corner_count; i++) + vreg->corner[i].use_open_loop + = !(fuse->ldo_cpr_cl_enable && use_closed_loop[i] + && vreg->corner[i].ldo_mode_allowed); + +done: + kfree(use_closed_loop); + return rc; +} + +/** + * cpr4_mmss_parse_corner_data() - parse MMSS corner data from device tree + * properties of the regulator's device node + * @vreg: Pointer to the CPR3 regulator + * + * Return: 0 on success, errno on failure + */ +static int cpr4_mmss_parse_corner_data(struct cpr3_regulator *vreg) +{ + int i, rc; + u32 *temp; + + rc = cpr3_parse_common_corner_data(vreg); + if (rc) { + cpr3_err(vreg, "error reading corner data, rc=%d\n", rc); + return rc; + } + + temp = kcalloc(vreg->corner_count * CPR3_RO_COUNT, sizeof(*temp), + GFP_KERNEL); + if (!temp) + return -ENOMEM; + + rc = cpr3_parse_corner_array_property(vreg, "qcom,cpr-target-quotients", + CPR3_RO_COUNT, temp); + if (rc) { + cpr3_err(vreg, "could not load target quotients, rc=%d\n", rc); + goto done; + } + + for (i = 0; i < vreg->corner_count; i++) + memcpy(vreg->corner[i].target_quot, &temp[i * CPR3_RO_COUNT], + sizeof(*temp) * CPR3_RO_COUNT); + +done: + kfree(temp); + return rc; +} + +/** + * cpr4_mmss_print_settings() - print out MMSS CPR configuration settings into + * the kernel log for debugging purposes + * @vreg: Pointer to the CPR3 regulator + */ +static void cpr4_mmss_print_settings(struct cpr3_regulator *vreg) +{ + struct cpr3_corner *corner; + int i; + + cpr3_debug(vreg, "Corner: Frequency (Hz), Fuse Corner, Floor (uV), Open-Loop (uV), Ceiling (uV)\n"); + for (i = 0; i < vreg->corner_count; i++) { + corner = &vreg->corner[i]; + cpr3_debug(vreg, "%3d: %10u, %2d, %7d, %7d, %7d\n", + i, corner->proc_freq, corner->cpr_fuse_corner, + corner->floor_volt, corner->open_loop_volt, + corner->ceiling_volt); + } +} + +/** + * cpr4_mmss_init_thread() - perform all steps necessary to initialize the + * configuration data for a CPR3 thread + * @thread: Pointer to the CPR3 thread + * + * Return: 0 on success, errno on failure + */ +static int cpr4_mmss_init_thread(struct cpr3_thread *thread) +{ + struct cpr3_controller *ctrl = thread->ctrl; + struct cpr3_regulator *vreg = &thread->vreg[0]; + int rc; + + rc = cpr3_parse_common_thread_data(thread); + if (rc) { + cpr3_err(vreg, "unable to read CPR thread data from device tree, rc=%d\n", + rc); + return rc; + } + + if (!of_find_property(ctrl->dev->of_node, "vdd-thread0-ldo-supply", + NULL)) { + cpr3_err(vreg, "ldo supply regulator is not specified\n"); + return -EINVAL; + } + + vreg->ldo_regulator = devm_regulator_get(ctrl->dev, "vdd-thread0-ldo"); + if (IS_ERR(vreg->ldo_regulator)) { + rc = PTR_ERR(vreg->ldo_regulator); + if (rc != -EPROBE_DEFER) + cpr3_err(vreg, "unable to request vdd-thread0-ldo regulator, rc=%d\n", + rc); + return rc; + } + + vreg->ldo_mode_allowed = !of_property_read_bool(vreg->of_node, + "qcom,ldo-disable"); + vreg->ldo_regulator_bypass = BHS_MODE; + vreg->ldo_type = CPR3_LDO300; + + rc = cpr4_msmfalcon_mmss_read_fuse_data(vreg); + if (rc) { + cpr3_err(vreg, "unable to read CPR fuse data, rc=%d\n", rc); + return rc; + } + + rc = cpr4_mmss_parse_corner_data(vreg); + if (rc) { + cpr3_err(vreg, "unable to read CPR corner data from device tree, rc=%d\n", + rc); + return rc; + } + + rc = cpr4_msmfalcon_mmss_calculate_open_loop_voltages(vreg); + if (rc) { + cpr3_err(vreg, "unable to calculate open-loop voltages, rc=%d\n", + rc); + return rc; + } + + rc = cpr3_limit_open_loop_voltages(vreg); + if (rc) { + cpr3_err(vreg, "unable to limit open-loop voltages, rc=%d\n", + rc); + return rc; + } + + cpr3_open_loop_voltage_as_ceiling(vreg); + + rc = cpr3_limit_floor_voltages(vreg); + if (rc) { + cpr3_err(vreg, "unable to limit floor voltages, rc=%d\n", rc); + return rc; + } + + rc = cpr4_mmss_parse_ldo_mode_data(vreg); + if (rc) { + cpr3_err(vreg, "unable to parse ldo mode data, rc=%d\n", rc); + return rc; + } + + rc = cpr4_mmss_parse_corner_operating_mode(vreg); + if (rc) { + cpr3_err(vreg, "unable to parse closed-loop operating mode data, rc=%d\n", + rc); + return rc; + } + + cpr4_mmss_print_settings(vreg); + + return 0; +} + +/** + * cpr4_mmss_init_controller() - perform MMSS CPR4 controller specific + * initializations + * @ctrl: Pointer to the CPR3 controller + * + * Return: 0 on success, errno on failure + */ +static int cpr4_mmss_init_controller(struct cpr3_controller *ctrl) +{ + int rc; + + rc = cpr3_parse_common_ctrl_data(ctrl); + if (rc) { + if (rc != -EPROBE_DEFER) + cpr3_err(ctrl, "unable to parse common controller data, rc=%d\n", + rc); + return rc; + } + + ctrl->sensor_count = MSMFALCON_MMSS_CPR_SENSOR_COUNT; + + /* + * MMSS only has one thread (0) so the zeroed array does not need + * further modification. + */ + ctrl->sensor_owner = devm_kcalloc(ctrl->dev, ctrl->sensor_count, + sizeof(*ctrl->sensor_owner), GFP_KERNEL); + if (!ctrl->sensor_owner) + return -ENOMEM; + + ctrl->cpr_clock_rate = MSMFALCON_MMSS_CPR_CLOCK_RATE; + ctrl->ctrl_type = CPR_CTRL_TYPE_CPR4; + ctrl->support_ldo300_vreg = true; + + /* + * Use fixed step quotient if specified otherwise use dynamic + * calculated per RO step quotient + */ + of_property_read_u32(ctrl->dev->of_node, + "qcom,cpr-step-quot-fixed", + &ctrl->step_quot_fixed); + ctrl->use_dynamic_step_quot = !ctrl->step_quot_fixed; + + /* iface_clk is optional for msmfalcon */ + ctrl->iface_clk = NULL; + ctrl->bus_clk = devm_clk_get(ctrl->dev, "bus_clk"); + if (IS_ERR(ctrl->bus_clk)) { + rc = PTR_ERR(ctrl->bus_clk); + if (rc != -EPROBE_DEFER) + cpr3_err(ctrl, "unable request bus clock, rc=%d\n", + rc); + return rc; + } + + return 0; +} + +static int cpr4_mmss_regulator_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct cpr3_controller *ctrl; + int rc; + + if (!dev->of_node) { + dev_err(dev, "Device tree node is missing\n"); + return -EINVAL; + } + + ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); + if (!ctrl) + return -ENOMEM; + + ctrl->dev = dev; + /* Set to false later if anything precludes CPR operation. */ + ctrl->cpr_allowed_hw = true; + + rc = of_property_read_string(dev->of_node, "qcom,cpr-ctrl-name", + &ctrl->name); + if (rc) { + cpr3_err(ctrl, "unable to read qcom,cpr-ctrl-name, rc=%d\n", + rc); + return rc; + } + + rc = cpr3_map_fuse_base(ctrl, pdev); + if (rc) { + cpr3_err(ctrl, "could not map fuse base address\n"); + return rc; + } + + rc = cpr3_allocate_threads(ctrl, 0, 0); + if (rc) { + cpr3_err(ctrl, "failed to allocate CPR thread array, rc=%d\n", + rc); + return rc; + } + + if (ctrl->thread_count != 1) { + cpr3_err(ctrl, "expected 1 thread but found %d\n", + ctrl->thread_count); + return -EINVAL; + } else if (ctrl->thread[0].vreg_count != 1) { + cpr3_err(ctrl, "expected 1 regulator but found %d\n", + ctrl->thread[0].vreg_count); + return -EINVAL; + } + + rc = cpr4_mmss_init_controller(ctrl); + if (rc) { + if (rc != -EPROBE_DEFER) + cpr3_err(ctrl, "failed to initialize CPR controller parameters, rc=%d\n", + rc); + return rc; + } + + rc = cpr4_mmss_init_thread(&ctrl->thread[0]); + if (rc) { + cpr3_err(&ctrl->thread[0].vreg[0], "thread initialization failed, rc=%d\n", + rc); + return rc; + } + + rc = cpr3_mem_acc_init(&ctrl->thread[0].vreg[0]); + if (rc) { + cpr3_err(ctrl, "failed to initialize mem-acc configuration, rc=%d\n", + rc); + return rc; + } + + platform_set_drvdata(pdev, ctrl); + + return cpr3_regulator_register(pdev, ctrl); +} + +static int cpr4_mmss_regulator_remove(struct platform_device *pdev) +{ + struct cpr3_controller *ctrl = platform_get_drvdata(pdev); + + return cpr3_regulator_unregister(ctrl); +} + +static int cpr4_mmss_regulator_suspend(struct platform_device *pdev, + pm_message_t state) +{ + struct cpr3_controller *ctrl = platform_get_drvdata(pdev); + + return cpr3_regulator_suspend(ctrl); +} + +static int cpr4_mmss_regulator_resume(struct platform_device *pdev) +{ + struct cpr3_controller *ctrl = platform_get_drvdata(pdev); + + return cpr3_regulator_resume(ctrl); +} + +/* Data corresponds to the SoC revision */ +static const struct of_device_id cpr4_mmss_regulator_match_table[] = { + { + .compatible = "qcom,cpr4-msmfalcon-mmss-ldo-regulator", + .data = (void *)NULL, + }, +}; + +static struct platform_driver cpr4_mmss_regulator_driver = { + .driver = { + .name = "qcom,cpr4-mmss-ldo-regulator", + .of_match_table = cpr4_mmss_regulator_match_table, + .owner = THIS_MODULE, + }, + .probe = cpr4_mmss_regulator_probe, + .remove = cpr4_mmss_regulator_remove, + .suspend = cpr4_mmss_regulator_suspend, + .resume = cpr4_mmss_regulator_resume, +}; + +static int cpr_regulator_init(void) +{ + return platform_driver_register(&cpr4_mmss_regulator_driver); +} + +static void cpr_regulator_exit(void) +{ + platform_driver_unregister(&cpr4_mmss_regulator_driver); +} + +MODULE_DESCRIPTION("CPR4 MMSS LDO regulator driver"); +MODULE_LICENSE("GPL v2"); + +arch_initcall(cpr_regulator_init); +module_exit(cpr_regulator_exit); From d78eb55dee7f5707e4834378bd89f94f9c6b88a0 Mon Sep 17 00:00:00 2001 From: Tirupathi Reddy Date: Fri, 23 Dec 2016 15:12:48 +0530 Subject: [PATCH 60/73] defconfig: Compile GFX LDO regulator driver for msmfalcon GFX LDO regulator driver powers GPU subsystem in msmfalcon. This LDO regulator is CPR managed. Enable GFX LDO regulator and platform specific MMSS CPR regulator to be compiled for msmfalcon. CRs-Fixed: 1068294 Change-Id: I2111fe55c9335d57ac91f18f4a4fb3689d80660d Signed-off-by: Tirupathi Reddy --- arch/arm/configs/msmfalcon-perf_defconfig | 2 ++ arch/arm/configs/msmfalcon_defconfig | 2 ++ arch/arm64/configs/msmfalcon-perf_defconfig | 2 ++ arch/arm64/configs/msmfalcon_defconfig | 2 ++ 4 files changed, 8 insertions(+) diff --git a/arch/arm/configs/msmfalcon-perf_defconfig b/arch/arm/configs/msmfalcon-perf_defconfig index 37b44ff5358f..211ec1c6cabc 100644 --- a/arch/arm/configs/msmfalcon-perf_defconfig +++ b/arch/arm/configs/msmfalcon-perf_defconfig @@ -348,6 +348,7 @@ CONFIG_WCD9335_CODEC=y CONFIG_WCD934X_CODEC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_MSM_GFX_LDO=y CONFIG_REGULATOR_RPM_SMD=y CONFIG_REGULATOR_QPNP=y CONFIG_REGULATOR_QPNP_LABIBB=y @@ -355,6 +356,7 @@ CONFIG_REGULATOR_SPM=y CONFIG_REGULATOR_CPR3_HMSS=y CONFIG_REGULATOR_CPR3_MMSS=y CONFIG_REGULATOR_CPRH_KBSS=y +CONFIG_REGULATOR_CPR4_MMSS_LDO=y CONFIG_REGULATOR_MEM_ACC=y CONFIG_REGULATOR_PROXY_CONSUMER=y CONFIG_REGULATOR_STUB=y diff --git a/arch/arm/configs/msmfalcon_defconfig b/arch/arm/configs/msmfalcon_defconfig index 058a1b3ddd24..752057554012 100644 --- a/arch/arm/configs/msmfalcon_defconfig +++ b/arch/arm/configs/msmfalcon_defconfig @@ -346,6 +346,7 @@ CONFIG_WCD9335_CODEC=y CONFIG_WCD934X_CODEC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_MSM_GFX_LDO=y CONFIG_REGULATOR_RPM_SMD=y CONFIG_REGULATOR_QPNP=y CONFIG_REGULATOR_QPNP_LABIBB=y @@ -354,6 +355,7 @@ CONFIG_REGULATOR_SPM=y CONFIG_REGULATOR_CPR3_HMSS=y CONFIG_REGULATOR_CPR3_MMSS=y CONFIG_REGULATOR_CPRH_KBSS=y +CONFIG_REGULATOR_CPR4_MMSS_LDO=y CONFIG_REGULATOR_MEM_ACC=y CONFIG_REGULATOR_PROXY_CONSUMER=y CONFIG_REGULATOR_STUB=y diff --git a/arch/arm64/configs/msmfalcon-perf_defconfig b/arch/arm64/configs/msmfalcon-perf_defconfig index 6f1e987e6d0c..698eac19ebb7 100644 --- a/arch/arm64/configs/msmfalcon-perf_defconfig +++ b/arch/arm64/configs/msmfalcon-perf_defconfig @@ -346,6 +346,7 @@ CONFIG_WCD9335_CODEC=y CONFIG_WCD934X_CODEC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_MSM_GFX_LDO=y CONFIG_REGULATOR_RPM_SMD=y CONFIG_REGULATOR_QPNP=y CONFIG_REGULATOR_QPNP_LABIBB=y @@ -354,6 +355,7 @@ CONFIG_REGULATOR_SPM=y CONFIG_REGULATOR_CPR3_HMSS=y CONFIG_REGULATOR_CPR3_MMSS=y CONFIG_REGULATOR_CPRH_KBSS=y +CONFIG_REGULATOR_CPR4_MMSS_LDO=y CONFIG_REGULATOR_MEM_ACC=y CONFIG_REGULATOR_PROXY_CONSUMER=y CONFIG_REGULATOR_STUB=y diff --git a/arch/arm64/configs/msmfalcon_defconfig b/arch/arm64/configs/msmfalcon_defconfig index c83e8427389e..7807f7ef71f8 100644 --- a/arch/arm64/configs/msmfalcon_defconfig +++ b/arch/arm64/configs/msmfalcon_defconfig @@ -348,6 +348,7 @@ CONFIG_WCD9335_CODEC=y CONFIG_WCD934X_CODEC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_MSM_GFX_LDO=y CONFIG_REGULATOR_RPM_SMD=y CONFIG_REGULATOR_QPNP=y CONFIG_REGULATOR_QPNP_LABIBB=y @@ -356,6 +357,7 @@ CONFIG_REGULATOR_SPM=y CONFIG_REGULATOR_CPR3_HMSS=y CONFIG_REGULATOR_CPR3_MMSS=y CONFIG_REGULATOR_CPRH_KBSS=y +CONFIG_REGULATOR_CPR4_MMSS_LDO=y CONFIG_REGULATOR_MEM_ACC=y CONFIG_REGULATOR_PROXY_CONSUMER=y CONFIG_REGULATOR_STUB=y From b90c988fe992c73ba86d067cddf053e54296f7e4 Mon Sep 17 00:00:00 2001 From: Xiaogang Cui Date: Wed, 21 Dec 2016 16:38:59 +0800 Subject: [PATCH 61/73] ARM: dts: msm: Add initial support for msm8998 QRD SKUK HDK board Add initial device trees for msm8998 QRD SKUK HDK board. Change-Id: Ib089e7ddd38d0d15285ed65c8a29039451cfc3c5 Signed-off-by: Xiaogang Cui --- arch/arm/boot/dts/qcom/Makefile | 1 + .../boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile index 2fd84d46035a..3b2586c45a5d 100644 --- a/arch/arm/boot/dts/qcom/Makefile +++ b/arch/arm/boot/dts/qcom/Makefile @@ -117,6 +117,7 @@ dtb-$(CONFIG_ARCH_MSM8998) += msm8998-sim.dtb \ msm8998-qrd-vr1.dtb \ msm8998-v2-qrd-vr1.dtb \ msm8998-v2-qrd-skuk-evt3.dtb \ + msm8998-v2-qrd-skuk-hdk.dtb \ apq8998-mtp.dtb \ apq8998-cdp.dtb \ apq8998-v2-mtp.dtb \ diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts new file mode 100644 index 000000000000..c2b70224ed2c --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts @@ -0,0 +1,23 @@ +/* Copyright (c) 2016, 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. + */ + + +/dts-v1/; + +#include "msm8998-v2.dtsi" +#include "msm8998-qrd-skuk.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8998 SKUK HDK"; + compatible = "qcom,msm8998-qrd", "qcom,msm8998", "qcom,qrd"; + qcom,board-id = <0x06000b 0x10>; +}; From 83f20c061222d2b59f940ad83660484877d2cfec Mon Sep 17 00:00:00 2001 From: Odelu Kukatla Date: Wed, 21 Dec 2016 13:25:52 +0530 Subject: [PATCH 62/73] clk: qcom: Add voltage voting for MSM8996 GCC driver Global Clock Controller(GCC) needs to vote for volatge level on rail for the clock frequencies, so add voltage voting in GCC. Also clean up clock flags and parent info for few clocks. Change-Id: Ib4cc69afb32a7654bbdd98f2efff901729c4d3da Signed-off-by: Odelu Kukatla --- drivers/clk/qcom/gcc-msm8996.c | 195 ++++++-- drivers/clk/qcom/vdd-level-8996.h | 95 ++++ include/dt-bindings/clock/qcom,gcc-msm8996.h | 463 ++++++++++--------- 3 files changed, 479 insertions(+), 274 deletions(-) create mode 100644 drivers/clk/qcom/vdd-level-8996.h diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c index 0f39bf278cd4..51c85e08372c 100644 --- a/drivers/clk/qcom/gcc-msm8996.c +++ b/drivers/clk/qcom/gcc-msm8996.c @@ -31,9 +31,12 @@ #include "clk-rcg.h" #include "clk-branch.h" #include "reset.h" +#include "vdd-level-8996.h" #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } +static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner); + enum { P_XO, P_GPLL0, @@ -89,7 +92,7 @@ static const struct parent_map gcc_xo_gpll0_gpll4_map[] = { static const char * const gcc_xo_gpll0_gpll4[] = { "xo", "gpll0", - "gpll4" + "gpll4_early" }; static const struct parent_map gcc_xo_gpll0_aud_ref_clk_map[] = { @@ -128,7 +131,7 @@ static const struct parent_map gcc_xo_gpll0_gpll4_gpll0_early_div_map[] = { static const char * const gcc_xo_gpll0_gpll4_gpll0_early_div[] = { "xo", "gpll0", - "gpll4", + "gpll4_early", "gpll0_early_div" }; @@ -162,7 +165,7 @@ static const char * const gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_d "gpll0", "gpll1_early_div", "gpll1", - "gpll4", + "gpll4_early", "gpll0_early_div" }; @@ -202,10 +205,24 @@ static const char * const gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll4_gpll0_early_div[] "gpll2", "gpll3", "gpll1", - "gpll4", + "gpll4_early", "gpll0_early_div" }; +static struct clk_fixed_factor gcc_ce1_ahb_m_clk = { + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_ahb_m_clk", + .ops = &clk_dummy_ops, + }, +}; + +static struct clk_fixed_factor gcc_ce1_axi_m_clk = { + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_axi_m_clk", + .ops = &clk_dummy_ops, + }, +}; + static struct clk_fixed_factor xo = { .mult = 1, .div = 1, @@ -294,6 +311,8 @@ static struct clk_rcg2 usb30_master_clk_src = { .parent_names = gcc_xo_gpll0_gpll0_early_div, .num_parents = 3, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 60000000, LOW, 120000000, + NOMINAL, 150000000), }, }; @@ -312,6 +331,7 @@ static struct clk_rcg2 usb30_mock_utmi_clk_src = { .parent_names = gcc_xo_gpll0_gpll0_early_div, .num_parents = 3, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 40000000, LOW, 60000000), }, }; @@ -330,6 +350,7 @@ static struct clk_rcg2 usb3_phy_aux_clk_src = { .parent_names = gcc_xo_sleep_clk, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP1(LOWER, 1200000), }, }; @@ -349,6 +370,8 @@ static struct clk_rcg2 usb20_master_clk_src = { .parent_names = gcc_xo_gpll0_gpll0_early_div, .num_parents = 3, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 60000000, + NOMINAL, 120000000), }, }; @@ -362,6 +385,7 @@ static struct clk_rcg2 usb20_mock_utmi_clk_src = { .parent_names = gcc_xo_gpll0_gpll0_early_div, .num_parents = 3, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 60000000), }, }; @@ -388,6 +412,8 @@ static struct clk_rcg2 sdcc1_apps_clk_src = { .parent_names = gcc_xo_gpll0_gpll4_gpll0_early_div, .num_parents = 4, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 200000000, + NOMINAL, 400000000), }, }; @@ -408,6 +434,8 @@ static struct clk_rcg2 sdcc1_ice_core_clk_src = { .parent_names = gcc_xo_gpll0_gpll4_gpll0_early_div, .num_parents = 4, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 150000000, + NOMINAL, 300000000), }, }; @@ -433,6 +461,8 @@ static struct clk_rcg2 sdcc2_apps_clk_src = { .parent_names = gcc_xo_gpll0_gpll4, .num_parents = 3, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 100000000, + NOMINAL, 200000000), }, }; @@ -447,6 +477,8 @@ static struct clk_rcg2 sdcc3_apps_clk_src = { .parent_names = gcc_xo_gpll0_gpll4, .num_parents = 3, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 100000000, + NOMINAL, 200000000), }, }; @@ -471,6 +503,8 @@ static struct clk_rcg2 sdcc4_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 50000000, + NOMINAL, 100000000), }, }; @@ -496,6 +530,8 @@ static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -515,6 +551,7 @@ static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -548,6 +585,8 @@ static struct clk_rcg2 blsp1_uart1_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -562,6 +601,8 @@ static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -575,6 +616,7 @@ static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -589,6 +631,8 @@ static struct clk_rcg2 blsp1_uart2_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -603,6 +647,8 @@ static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -616,6 +662,7 @@ static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -630,6 +677,8 @@ static struct clk_rcg2 blsp1_uart3_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -644,6 +693,8 @@ static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -657,6 +708,7 @@ static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -671,6 +723,8 @@ static struct clk_rcg2 blsp1_uart4_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -685,6 +739,8 @@ static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -698,6 +754,7 @@ static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -712,6 +769,8 @@ static struct clk_rcg2 blsp1_uart5_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -726,6 +785,8 @@ static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -739,6 +800,7 @@ static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -753,6 +815,8 @@ static struct clk_rcg2 blsp1_uart6_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -767,6 +831,8 @@ static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -780,6 +846,7 @@ static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -794,6 +861,8 @@ static struct clk_rcg2 blsp2_uart1_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -808,6 +877,8 @@ static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -821,6 +892,7 @@ static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -835,6 +907,8 @@ static struct clk_rcg2 blsp2_uart2_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -849,6 +923,8 @@ static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -862,6 +938,7 @@ static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -876,6 +953,8 @@ static struct clk_rcg2 blsp2_uart3_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -890,6 +969,8 @@ static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -903,6 +984,7 @@ static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -917,6 +999,8 @@ static struct clk_rcg2 blsp2_uart4_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -931,6 +1015,8 @@ static struct clk_rcg2 blsp2_qup5_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -944,6 +1030,7 @@ static struct clk_rcg2 blsp2_qup5_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -958,6 +1045,8 @@ static struct clk_rcg2 blsp2_uart5_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -972,6 +1061,8 @@ static struct clk_rcg2 blsp2_qup6_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -985,6 +1076,7 @@ static struct clk_rcg2 blsp2_qup6_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -999,6 +1091,8 @@ static struct clk_rcg2 blsp2_uart6_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -1017,6 +1111,7 @@ static struct clk_rcg2 pdm2_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 60000000), }, }; @@ -1036,6 +1131,7 @@ static struct clk_rcg2 tsif_ref_clk_src = { .parent_names = gcc_xo_gpll0_aud_ref_clk, .num_parents = 3, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP1(LOWER, 19200000), }, }; @@ -1082,6 +1178,8 @@ static struct clk_rcg2 gp1_clk_src = { .parent_names = gcc_xo_gpll0_sleep_clk_gpll0_early_div, .num_parents = 4, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 50000000, LOW, 100000000, + NOMINAL, 200000000), }, }; @@ -1096,6 +1194,8 @@ static struct clk_rcg2 gp2_clk_src = { .parent_names = gcc_xo_gpll0_sleep_clk_gpll0_early_div, .num_parents = 4, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 50000000, LOW, 100000000, + NOMINAL, 200000000), }, }; @@ -1110,6 +1210,8 @@ static struct clk_rcg2 gp3_clk_src = { .parent_names = gcc_xo_gpll0_sleep_clk_gpll0_early_div, .num_parents = 4, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 50000000, LOW, 100000000, + NOMINAL, 200000000), }, }; @@ -1129,6 +1231,7 @@ static struct clk_rcg2 pcie_aux_clk_src = { .parent_names = gcc_xo_sleep_clk, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP1(LOWER, 1011000), }, }; @@ -1150,6 +1253,8 @@ static struct clk_rcg2 ufs_axi_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP4(LOWER, 19200000, LOW, 100000000, + NOMINAL, 200000000, HIGH, 240000000), }, }; @@ -1170,6 +1275,8 @@ static struct clk_rcg2 ufs_ice_core_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 150000000, + NOMINAL, 300000000), }, }; @@ -1191,6 +1298,8 @@ static struct clk_rcg2 qspi_ser_clk_src = { .parent_names = gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div, .num_parents = 6, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 80200000, LOW, 160400000, + NOMINAL, 320000000), }, }; @@ -1321,6 +1430,18 @@ static struct clk_branch gcc_usb3_phy_aux_clk = { }, }; +static struct clk_gate2 gpll0_out_msscc_clk = { + .udelay = 1, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gpll0_out_msscc_clk", + .ops = &clk_gate2_ops, + }, + }, +}; + static struct clk_gate2 gcc_usb3_phy_pipe_clk = { .udelay = 50, .clkr = { @@ -1333,18 +1454,6 @@ static struct clk_gate2 gcc_usb3_phy_pipe_clk = { }, }; -static struct clk_gate2 gpll0_out_msscc = { - .udelay = 1, - .clkr = { - .enable_reg = 0x5200c, - .enable_mask = BIT(2), - .hw.init = &(struct clk_init_data){ - .name = "gpll0_out_msscc", - .ops = &clk_gate2_ops, - }, - }, -}; - static struct clk_branch gcc_usb20_master_clk = { .halt_reg = 0x12004, .clkr = { @@ -1826,6 +1935,7 @@ static struct clk_branch gcc_blsp2_ahb_clk = { .enable_mask = BIT(15), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_ahb_clk", + .flags = CLK_ENABLE_HAND_OFF, .ops = &clk_branch2_ops, }, }, @@ -2728,18 +2838,6 @@ static struct clk_branch gcc_smmu_aggre0_ahb_clk = { }, }; -static struct clk_branch gcc_aggre1_pnoc_ahb_clk = { - .halt_reg = 0x82014, - .clkr = { - .enable_reg = 0x82014, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_aggre1_pnoc_ahb_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_aggre2_ufs_axi_clk = { .halt_reg = 0x83014, .clkr = { @@ -2995,11 +3093,13 @@ static struct clk_branch gcc_mmss_gpll0_div_clk = { }; static struct clk_hw *gcc_msm8996_hws[] = { - &xo.hw, - &gpll0_early_div.hw, - &ufs_tx_cfg_clk_src.hw, - &ufs_rx_cfg_clk_src.hw, - &ufs_ice_core_postdiv_clk_src.hw, + [GCC_XO] = &xo.hw, + [GCC_CE1_AHB_M_CLK] = &gcc_ce1_ahb_m_clk.hw, + [GCC_CE1_AXI_M_CLK] = &gcc_ce1_axi_m_clk.hw, + [GCC_GPLL0_EARLY_DIV] = &gpll0_early_div.hw, + [GCC_UFS_TX_CFG_CLK_SRC] = &ufs_tx_cfg_clk_src.hw, + [GCC_UFS_RX_CFG_CLK_SRC] = &ufs_rx_cfg_clk_src.hw, + [GCC_UFS_ICE_CORE_PDIV_CLK_SRC] = &ufs_ice_core_postdiv_clk_src.hw, }; static struct clk_regmap *gcc_msm8996_clocks[] = { @@ -3170,7 +3270,6 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { [GCC_AGGRE0_CNOC_AHB_CLK] = &gcc_aggre0_cnoc_ahb_clk.clkr, [GCC_SMMU_AGGRE0_AXI_CLK] = &gcc_smmu_aggre0_axi_clk.clkr, [GCC_SMMU_AGGRE0_AHB_CLK] = &gcc_smmu_aggre0_ahb_clk.clkr, - [GCC_AGGRE1_PNOC_AHB_CLK] = &gcc_aggre1_pnoc_ahb_clk.clkr, [GCC_AGGRE2_UFS_AXI_CLK] = &gcc_aggre2_ufs_axi_clk.clkr, [GCC_AGGRE2_USB3_AXI_CLK] = &gcc_aggre2_usb3_axi_clk.clkr, [GCC_QSPI_AHB_CLK] = &gcc_qspi_ahb_clk.clkr, @@ -3192,10 +3291,10 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr, [GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr, - [GCC_DCC_AHB_ALK] = &gcc_dcc_ahb_clk.clkr, + [GCC_DCC_AHB_CLK] = &gcc_dcc_ahb_clk.clkr, [GCC_AGGRE0_NOC_MPU_CFG_AHB_CLK] = &gcc_aggre0_noc_mpu_cfg_ahb_clk.clkr, [GCC_MMSS_GPLL0_DIV_CLK] = &gcc_mmss_gpll0_div_clk.clkr, - [GPLL0_OUT_MSSCC] = &gpll0_out_msscc.clkr, + [GPLL0_OUT_MSSCC_CLK] = &gpll0_out_msscc_clk.clkr, }; static const struct qcom_reset_map gcc_msm8996_resets[] = { @@ -3317,6 +3416,8 @@ static const struct regmap_config gcc_msm8996_regmap_config = { static const struct qcom_cc_desc gcc_msm8996_desc = { .config = &gcc_msm8996_regmap_config, .clks = gcc_msm8996_clocks, + .hwclks = gcc_msm8996_hws, + .num_hwclks = ARRAY_SIZE(gcc_msm8996_hws), .num_clks = ARRAY_SIZE(gcc_msm8996_clocks), .resets = gcc_msm8996_resets, .num_resets = ARRAY_SIZE(gcc_msm8996_resets), @@ -3330,9 +3431,7 @@ MODULE_DEVICE_TABLE(of, gcc_msm8996_match_table); static int gcc_msm8996_probe(struct platform_device *pdev) { - struct clk *clk; - struct device *dev = &pdev->dev; - int i, ret = 0; + int ret = 0; struct regmap *regmap; regmap = qcom_cc_map(pdev, &gcc_msm8996_desc); @@ -3342,10 +3441,14 @@ static int gcc_msm8996_probe(struct platform_device *pdev) /* Set the HMSS_AHB_CLK_ENA bit to enable the hmss_ahb_clk */ regmap_update_bits(regmap, 0x52004, BIT(21), BIT(21)); - for (i = 0; i < ARRAY_SIZE(gcc_msm8996_hws); i++) { - clk = devm_clk_register(dev, gcc_msm8996_hws[i]); - if (IS_ERR(clk)) - return PTR_ERR(clk); + vdd_dig.vdd_uv[1] = RPM_REGULATOR_CORNER_SVS_KRAIT; + + vdd_dig.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_dig"); + if (IS_ERR(vdd_dig.regulator[0])) { + if (!(PTR_ERR(vdd_dig.regulator[0]) == -EPROBE_DEFER)) + dev_err(&pdev->dev, + "Unable to get vdd_dig regulator!"); + return PTR_ERR(vdd_dig.regulator[0]); } ret = qcom_cc_really_probe(pdev, &gcc_msm8996_desc, regmap); @@ -3358,6 +3461,12 @@ static int gcc_msm8996_probe(struct platform_device *pdev) /* This clock is used for all MMSS register access */ clk_prepare_enable(gcc_mmss_noc_cfg_ahb_clk.clkr.hw.clk); + /* + * Keep the core memory settings enabled at all times for + * gcc_mmss_bimc_gfx_clk. + */ + clk_set_flags(gcc_mmss_bimc_gfx_clk.clkr.hw.clk, CLKFLAG_RETAIN_MEM); + dev_info(&pdev->dev, "Registered GCC clocks\n"); return ret; diff --git a/drivers/clk/qcom/vdd-level-8996.h b/drivers/clk/qcom/vdd-level-8996.h new file mode 100644 index 000000000000..f93dd1638b1b --- /dev/null +++ b/drivers/clk/qcom/vdd-level-8996.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + */ + +#ifndef __QCOM_VDD_LEVEL_8996_H__ +#define __QCOM_VDD_LEVEL_8996_H__ + +#include +#include + +#define VDD_DIG_FMAX_MAP1(l1, f1) \ + .vdd_class = &vdd_dig, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + }, \ + .num_rate_max = VDD_DIG_NUM + +#define VDD_DIG_FMAX_MAP2(l1, f1, l2, f2) \ + .vdd_class = &vdd_dig, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + [VDD_DIG_##l2] = (f2), \ + }, \ + .num_rate_max = VDD_DIG_NUM + +#define VDD_DIG_FMAX_MAP3(l1, f1, l2, f2, l3, f3) \ + .vdd_class = &vdd_dig, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + [VDD_DIG_##l2] = (f2), \ + [VDD_DIG_##l3] = (f3), \ + }, \ + .num_rate_max = VDD_DIG_NUM + +#define VDD_DIG_FMAX_MAP4(l1, f1, l2, f2, l3, f3, l4, f4) \ + .vdd_class = &vdd_dig, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + [VDD_DIG_##l2] = (f2), \ + [VDD_DIG_##l3] = (f3), \ + [VDD_DIG_##l4] = (f4), \ + }, \ + .num_rate_max = VDD_DIG_NUM + +#define VDD_MMPLL4_FMAX_MAP1(l1, f1) \ + .vdd_class = &vdd_mmpll4, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + }, \ + .num_rate_max = VDD_DIG_NUM + +#define VDD_MMPLL4_FMAX_MAP2(l1, f1, l2, f2) \ + .vdd_class = &vdd_mmpll4, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + [VDD_DIG_##l2] = (f2), \ + }, \ + .num_rate_max = VDD_DIG_NUM + +#define VDD_MMPLL4_FMAX_MAP3(l1, f1, l2, f2, l3, f3) \ + .vdd_class = &vdd_mmpll4, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + [VDD_DIG_##l2] = (f2), \ + [VDD_DIG_##l3] = (f3), \ + }, \ + .num_rate_max = VDD_DIG_NUM + +enum vdd_dig_levels { + VDD_DIG_NONE, + VDD_DIG_LOWER, /* SVS2 */ + VDD_DIG_LOW, /* SVS */ + VDD_DIG_NOMINAL, /* NOMINAL */ + VDD_DIG_HIGH, /* Turbo */ + VDD_DIG_NUM +}; + +static int vdd_corner[] = { + RPM_REGULATOR_CORNER_NONE, /* VDD_DIG_NONE */ + RPM_REGULATOR_CORNER_SVS_SOC, /* SVS2 is remapped to SVS */ + RPM_REGULATOR_CORNER_SVS_SOC, /* VDD_DIG_SVS */ + RPM_REGULATOR_CORNER_NORMAL, /* VDD_DIG_NOMINAL */ + RPM_REGULATOR_CORNER_SUPER_TURBO, /* VDD_DIG_TURBO */ +}; + +#endif diff --git a/include/dt-bindings/clock/qcom,gcc-msm8996.h b/include/dt-bindings/clock/qcom,gcc-msm8996.h index f66264a2beb4..efed312fe914 100644 --- a/include/dt-bindings/clock/qcom,gcc-msm8996.h +++ b/include/dt-bindings/clock/qcom,gcc-msm8996.h @@ -14,238 +14,239 @@ #ifndef _DT_BINDINGS_CLK_MSM_GCC_8996_H #define _DT_BINDINGS_CLK_MSM_GCC_8996_H -#define GPLL0_EARLY 0 -#define GPLL0 1 -#define GPLL1_EARLY 2 -#define GPLL1 3 -#define GPLL2_EARLY 4 -#define GPLL2 5 -#define GPLL3_EARLY 6 -#define GPLL3 7 -#define GPLL4_EARLY 8 -#define GPLL4 9 -#define SYSTEM_NOC_CLK_SRC 10 -#define CONFIG_NOC_CLK_SRC 11 -#define PERIPH_NOC_CLK_SRC 12 -#define MMSS_BIMC_GFX_CLK_SRC 13 -#define USB30_MASTER_CLK_SRC 14 -#define USB30_MOCK_UTMI_CLK_SRC 15 -#define USB3_PHY_AUX_CLK_SRC 16 -#define USB20_MASTER_CLK_SRC 17 -#define USB20_MOCK_UTMI_CLK_SRC 18 -#define SDCC1_APPS_CLK_SRC 19 -#define SDCC1_ICE_CORE_CLK_SRC 20 -#define SDCC2_APPS_CLK_SRC 21 -#define SDCC3_APPS_CLK_SRC 22 -#define SDCC4_APPS_CLK_SRC 23 -#define BLSP1_QUP1_SPI_APPS_CLK_SRC 24 -#define BLSP1_QUP1_I2C_APPS_CLK_SRC 25 -#define BLSP1_UART1_APPS_CLK_SRC 26 -#define BLSP1_QUP2_SPI_APPS_CLK_SRC 27 -#define BLSP1_QUP2_I2C_APPS_CLK_SRC 28 -#define BLSP1_UART2_APPS_CLK_SRC 29 -#define BLSP1_QUP3_SPI_APPS_CLK_SRC 30 -#define BLSP1_QUP3_I2C_APPS_CLK_SRC 31 -#define BLSP1_UART3_APPS_CLK_SRC 32 -#define BLSP1_QUP4_SPI_APPS_CLK_SRC 33 -#define BLSP1_QUP4_I2C_APPS_CLK_SRC 34 -#define BLSP1_UART4_APPS_CLK_SRC 35 -#define BLSP1_QUP5_SPI_APPS_CLK_SRC 36 -#define BLSP1_QUP5_I2C_APPS_CLK_SRC 37 -#define BLSP1_UART5_APPS_CLK_SRC 38 -#define BLSP1_QUP6_SPI_APPS_CLK_SRC 39 -#define BLSP1_QUP6_I2C_APPS_CLK_SRC 40 -#define BLSP1_UART6_APPS_CLK_SRC 41 -#define BLSP2_QUP1_SPI_APPS_CLK_SRC 42 -#define BLSP2_QUP1_I2C_APPS_CLK_SRC 43 -#define BLSP2_UART1_APPS_CLK_SRC 44 -#define BLSP2_QUP2_SPI_APPS_CLK_SRC 45 -#define BLSP2_QUP2_I2C_APPS_CLK_SRC 46 -#define BLSP2_UART2_APPS_CLK_SRC 47 -#define BLSP2_QUP3_SPI_APPS_CLK_SRC 48 -#define BLSP2_QUP3_I2C_APPS_CLK_SRC 49 -#define BLSP2_UART3_APPS_CLK_SRC 50 -#define BLSP2_QUP4_SPI_APPS_CLK_SRC 51 -#define BLSP2_QUP4_I2C_APPS_CLK_SRC 52 -#define BLSP2_UART4_APPS_CLK_SRC 53 -#define BLSP2_QUP5_SPI_APPS_CLK_SRC 54 -#define BLSP2_QUP5_I2C_APPS_CLK_SRC 55 -#define BLSP2_UART5_APPS_CLK_SRC 56 -#define BLSP2_QUP6_SPI_APPS_CLK_SRC 57 -#define BLSP2_QUP6_I2C_APPS_CLK_SRC 58 -#define BLSP2_UART6_APPS_CLK_SRC 59 -#define PDM2_CLK_SRC 60 -#define TSIF_REF_CLK_SRC 61 -#define CE1_CLK_SRC 62 -#define GCC_SLEEP_CLK_SRC 63 -#define BIMC_CLK_SRC 64 -#define HMSS_AHB_CLK_SRC 65 -#define BIMC_HMSS_AXI_CLK_SRC 66 -#define HMSS_RBCPR_CLK_SRC 67 -#define HMSS_GPLL0_CLK_SRC 68 -#define GP1_CLK_SRC 69 -#define GP2_CLK_SRC 70 -#define GP3_CLK_SRC 71 -#define PCIE_AUX_CLK_SRC 72 -#define UFS_AXI_CLK_SRC 73 -#define UFS_ICE_CORE_CLK_SRC 74 -#define QSPI_SER_CLK_SRC 75 -#define GCC_SYS_NOC_AXI_CLK 76 -#define GCC_SYS_NOC_HMSS_AHB_CLK 77 -#define GCC_SNOC_CNOC_AHB_CLK 78 -#define GCC_SNOC_PNOC_AHB_CLK 79 -#define GCC_SYS_NOC_AT_CLK 80 -#define GCC_SYS_NOC_USB3_AXI_CLK 81 -#define GCC_SYS_NOC_UFS_AXI_CLK 82 -#define GCC_CFG_NOC_AHB_CLK 83 -#define GCC_PERIPH_NOC_AHB_CLK 84 -#define GCC_PERIPH_NOC_USB20_AHB_CLK 85 -#define GCC_TIC_CLK 86 -#define GCC_IMEM_AXI_CLK 87 -#define GCC_MMSS_SYS_NOC_AXI_CLK 88 -#define GCC_MMSS_NOC_CFG_AHB_CLK 89 -#define GCC_MMSS_BIMC_GFX_CLK 90 -#define GCC_USB30_MASTER_CLK 91 -#define GCC_USB30_SLEEP_CLK 92 -#define GCC_USB30_MOCK_UTMI_CLK 93 -#define GCC_USB3_PHY_AUX_CLK 94 -#define GCC_USB3_PHY_PIPE_CLK 95 -#define GCC_USB20_MASTER_CLK 96 -#define GCC_USB20_SLEEP_CLK 97 -#define GCC_USB20_MOCK_UTMI_CLK 98 -#define GCC_USB_PHY_CFG_AHB2PHY_CLK 99 -#define GCC_SDCC1_APPS_CLK 100 -#define GCC_SDCC1_AHB_CLK 101 -#define GCC_SDCC1_ICE_CORE_CLK 102 -#define GCC_SDCC2_APPS_CLK 103 -#define GCC_SDCC2_AHB_CLK 104 -#define GCC_SDCC3_APPS_CLK 105 -#define GCC_SDCC3_AHB_CLK 106 -#define GCC_SDCC4_APPS_CLK 107 -#define GCC_SDCC4_AHB_CLK 108 -#define GCC_BLSP1_AHB_CLK 109 -#define GCC_BLSP1_SLEEP_CLK 110 -#define GCC_BLSP1_QUP1_SPI_APPS_CLK 111 -#define GCC_BLSP1_QUP1_I2C_APPS_CLK 112 -#define GCC_BLSP1_UART1_APPS_CLK 113 -#define GCC_BLSP1_QUP2_SPI_APPS_CLK 114 -#define GCC_BLSP1_QUP2_I2C_APPS_CLK 115 -#define GCC_BLSP1_UART2_APPS_CLK 116 -#define GCC_BLSP1_QUP3_SPI_APPS_CLK 117 -#define GCC_BLSP1_QUP3_I2C_APPS_CLK 118 -#define GCC_BLSP1_UART3_APPS_CLK 119 -#define GCC_BLSP1_QUP4_SPI_APPS_CLK 120 -#define GCC_BLSP1_QUP4_I2C_APPS_CLK 121 -#define GCC_BLSP1_UART4_APPS_CLK 122 -#define GCC_BLSP1_QUP5_SPI_APPS_CLK 123 -#define GCC_BLSP1_QUP5_I2C_APPS_CLK 124 -#define GCC_BLSP1_UART5_APPS_CLK 125 -#define GCC_BLSP1_QUP6_SPI_APPS_CLK 126 -#define GCC_BLSP1_QUP6_I2C_APPS_CLK 127 -#define GCC_BLSP1_UART6_APPS_CLK 128 -#define GCC_BLSP2_AHB_CLK 129 -#define GCC_BLSP2_SLEEP_CLK 130 -#define GCC_BLSP2_QUP1_SPI_APPS_CLK 131 -#define GCC_BLSP2_QUP1_I2C_APPS_CLK 132 -#define GCC_BLSP2_UART1_APPS_CLK 133 -#define GCC_BLSP2_QUP2_SPI_APPS_CLK 134 -#define GCC_BLSP2_QUP2_I2C_APPS_CLK 135 -#define GCC_BLSP2_UART2_APPS_CLK 136 -#define GCC_BLSP2_QUP3_SPI_APPS_CLK 137 -#define GCC_BLSP2_QUP3_I2C_APPS_CLK 138 -#define GCC_BLSP2_UART3_APPS_CLK 139 -#define GCC_BLSP2_QUP4_SPI_APPS_CLK 140 -#define GCC_BLSP2_QUP4_I2C_APPS_CLK 141 -#define GCC_BLSP2_UART4_APPS_CLK 142 -#define GCC_BLSP2_QUP5_SPI_APPS_CLK 143 -#define GCC_BLSP2_QUP5_I2C_APPS_CLK 144 -#define GCC_BLSP2_UART5_APPS_CLK 145 -#define GCC_BLSP2_QUP6_SPI_APPS_CLK 146 -#define GCC_BLSP2_QUP6_I2C_APPS_CLK 147 -#define GCC_BLSP2_UART6_APPS_CLK 148 -#define GCC_PDM_AHB_CLK 149 -#define GCC_PDM_XO4_CLK 150 -#define GCC_PDM2_CLK 151 -#define GCC_PRNG_AHB_CLK 152 -#define GCC_TSIF_AHB_CLK 153 -#define GCC_TSIF_REF_CLK 154 -#define GCC_TSIF_INACTIVITY_TIMERS_CLK 155 -#define GCC_TCSR_AHB_CLK 156 -#define GCC_BOOT_ROM_AHB_CLK 157 -#define GCC_MSG_RAM_AHB_CLK 158 -#define GCC_TLMM_AHB_CLK 159 -#define GCC_TLMM_CLK 160 -#define GCC_MPM_AHB_CLK 161 -#define GCC_SPMI_SER_CLK 162 -#define GCC_SPMI_CNOC_AHB_CLK 163 -#define GCC_CE1_CLK 164 -#define GCC_CE1_AXI_CLK 165 -#define GCC_CE1_AHB_CLK 166 -#define GCC_BIMC_HMSS_AXI_CLK 167 -#define GCC_BIMC_GFX_CLK 168 -#define GCC_HMSS_AHB_CLK 169 -#define GCC_HMSS_SLV_AXI_CLK 170 -#define GCC_HMSS_MSTR_AXI_CLK 171 -#define GCC_HMSS_RBCPR_CLK 172 -#define GCC_GP1_CLK 173 -#define GCC_GP2_CLK 174 -#define GCC_GP3_CLK 175 -#define GCC_PCIE_0_SLV_AXI_CLK 176 -#define GCC_PCIE_0_MSTR_AXI_CLK 177 -#define GCC_PCIE_0_CFG_AHB_CLK 178 -#define GCC_PCIE_0_AUX_CLK 179 -#define GCC_PCIE_0_PIPE_CLK 180 -#define GCC_PCIE_1_SLV_AXI_CLK 181 -#define GCC_PCIE_1_MSTR_AXI_CLK 182 -#define GCC_PCIE_1_CFG_AHB_CLK 183 -#define GCC_PCIE_1_AUX_CLK 184 -#define GCC_PCIE_1_PIPE_CLK 185 -#define GCC_PCIE_2_SLV_AXI_CLK 186 -#define GCC_PCIE_2_MSTR_AXI_CLK 187 -#define GCC_PCIE_2_CFG_AHB_CLK 188 -#define GCC_PCIE_2_AUX_CLK 189 -#define GCC_PCIE_2_PIPE_CLK 190 -#define GCC_PCIE_PHY_CFG_AHB_CLK 191 -#define GCC_PCIE_PHY_AUX_CLK 192 -#define GCC_UFS_AXI_CLK 193 -#define GCC_UFS_AHB_CLK 194 -#define GCC_UFS_TX_CFG_CLK 195 -#define GCC_UFS_RX_CFG_CLK 196 -#define GCC_UFS_TX_SYMBOL_0_CLK 197 -#define GCC_UFS_RX_SYMBOL_0_CLK 198 -#define GCC_UFS_RX_SYMBOL_1_CLK 199 -#define GCC_UFS_UNIPRO_CORE_CLK 200 -#define GCC_UFS_ICE_CORE_CLK 201 -#define GCC_UFS_SYS_CLK_CORE_CLK 202 -#define GCC_UFS_TX_SYMBOL_CLK_CORE_CLK 203 -#define GCC_AGGRE0_SNOC_AXI_CLK 204 -#define GCC_AGGRE0_CNOC_AHB_CLK 205 -#define GCC_SMMU_AGGRE0_AXI_CLK 206 -#define GCC_SMMU_AGGRE0_AHB_CLK 207 -#define GCC_AGGRE1_PNOC_AHB_CLK 208 -#define GCC_AGGRE2_UFS_AXI_CLK 209 -#define GCC_AGGRE2_USB3_AXI_CLK 210 -#define GCC_QSPI_AHB_CLK 211 -#define GCC_QSPI_SER_CLK 212 -#define GCC_USB3_CLKREF_CLK 213 -#define GCC_HDMI_CLKREF_CLK 214 -#define GCC_UFS_CLKREF_CLK 215 -#define GCC_PCIE_CLKREF_CLK 216 -#define GCC_RX2_USB2_CLKREF_CLK 217 -#define GCC_RX1_USB2_CLKREF_CLK 218 -#define GCC_AGGRE0_NOC_QOSGEN_EXTREF_CLK 219 -#define GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK 220 -#define GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK 221 -#define GCC_EDP_CLKREF_CLK 222 -#define GCC_MSS_CFG_AHB_CLK 223 -#define GCC_MSS_Q6_BIMC_AXI_CLK 224 -#define GCC_MSS_SNOC_AXI_CLK 225 -#define GCC_MSS_MNOC_BIMC_AXI_CLK 226 -#define GCC_DCC_AHB_ALK 227 -#define GCC_AGGRE0_NOC_MPU_CFG_AHB_CLK 228 -#define GCC_MMSS_GPLL0_DIV_CLK 229 -#define GPLL0_OUT_MSSCC 230 +/* Hardware/Dummy/Voter clocks */ +#define GCC_XO 0 +#define GCC_CE1_AHB_M_CLK 1 +#define GCC_CE1_AXI_M_CLK 2 +#define GCC_GPLL0_EARLY_DIV 3 +#define GCC_UFS_TX_CFG_CLK_SRC 4 +#define GCC_UFS_RX_CFG_CLK_SRC 5 +#define GCC_UFS_ICE_CORE_PDIV_CLK_SRC 6 +/* RCGs and Branches */ +#define GPLL0_EARLY 7 +#define GPLL0 8 +#define GPLL4_EARLY 9 +#define GPLL4 10 +#define SYSTEM_NOC_CLK_SRC 11 +#define CONFIG_NOC_CLK_SRC 12 +#define PERIPH_NOC_CLK_SRC 13 +#define MMSS_BIMC_GFX_CLK_SRC 14 +#define USB30_MASTER_CLK_SRC 15 +#define USB30_MOCK_UTMI_CLK_SRC 16 +#define USB3_PHY_AUX_CLK_SRC 17 +#define USB20_MASTER_CLK_SRC 18 +#define USB20_MOCK_UTMI_CLK_SRC 19 +#define SDCC1_APPS_CLK_SRC 20 +#define SDCC1_ICE_CORE_CLK_SRC 21 +#define SDCC2_APPS_CLK_SRC 22 +#define SDCC3_APPS_CLK_SRC 23 +#define SDCC4_APPS_CLK_SRC 24 +#define BLSP1_QUP1_SPI_APPS_CLK_SRC 25 +#define BLSP1_QUP1_I2C_APPS_CLK_SRC 26 +#define BLSP1_UART1_APPS_CLK_SRC 27 +#define BLSP1_QUP2_SPI_APPS_CLK_SRC 28 +#define BLSP1_QUP2_I2C_APPS_CLK_SRC 29 +#define BLSP1_UART2_APPS_CLK_SRC 30 +#define BLSP1_QUP3_SPI_APPS_CLK_SRC 31 +#define BLSP1_QUP3_I2C_APPS_CLK_SRC 32 +#define BLSP1_UART3_APPS_CLK_SRC 33 +#define BLSP1_QUP4_SPI_APPS_CLK_SRC 34 +#define BLSP1_QUP4_I2C_APPS_CLK_SRC 35 +#define BLSP1_UART4_APPS_CLK_SRC 36 +#define BLSP1_QUP5_SPI_APPS_CLK_SRC 37 +#define BLSP1_QUP5_I2C_APPS_CLK_SRC 38 +#define BLSP1_UART5_APPS_CLK_SRC 39 +#define BLSP1_QUP6_SPI_APPS_CLK_SRC 40 +#define BLSP1_QUP6_I2C_APPS_CLK_SRC 41 +#define BLSP1_UART6_APPS_CLK_SRC 42 +#define BLSP2_QUP1_SPI_APPS_CLK_SRC 43 +#define BLSP2_QUP1_I2C_APPS_CLK_SRC 44 +#define BLSP2_UART1_APPS_CLK_SRC 45 +#define BLSP2_QUP2_SPI_APPS_CLK_SRC 46 +#define BLSP2_QUP2_I2C_APPS_CLK_SRC 47 +#define BLSP2_UART2_APPS_CLK_SRC 48 +#define BLSP2_QUP3_SPI_APPS_CLK_SRC 49 +#define BLSP2_QUP3_I2C_APPS_CLK_SRC 50 +#define BLSP2_UART3_APPS_CLK_SRC 51 +#define BLSP2_QUP4_SPI_APPS_CLK_SRC 52 +#define BLSP2_QUP4_I2C_APPS_CLK_SRC 53 +#define BLSP2_UART4_APPS_CLK_SRC 54 +#define BLSP2_QUP5_SPI_APPS_CLK_SRC 55 +#define BLSP2_QUP5_I2C_APPS_CLK_SRC 56 +#define BLSP2_UART5_APPS_CLK_SRC 57 +#define BLSP2_QUP6_SPI_APPS_CLK_SRC 58 +#define BLSP2_QUP6_I2C_APPS_CLK_SRC 59 +#define BLSP2_UART6_APPS_CLK_SRC 60 +#define PDM2_CLK_SRC 61 +#define TSIF_REF_CLK_SRC 62 +#define CE1_CLK_SRC 63 +#define GCC_SLEEP_CLK_SRC 64 +#define BIMC_CLK_SRC 65 +#define HMSS_AHB_CLK_SRC 66 +#define BIMC_HMSS_AXI_CLK_SRC 67 +#define HMSS_RBCPR_CLK_SRC 68 +#define HMSS_GPLL0_CLK_SRC 69 +#define GP1_CLK_SRC 70 +#define GP2_CLK_SRC 71 +#define GP3_CLK_SRC 72 +#define PCIE_AUX_CLK_SRC 73 +#define UFS_AXI_CLK_SRC 74 +#define UFS_ICE_CORE_CLK_SRC 75 +#define QSPI_SER_CLK_SRC 76 +#define GCC_SYS_NOC_AXI_CLK 77 +#define GCC_SYS_NOC_HMSS_AHB_CLK 78 +#define GCC_SNOC_CNOC_AHB_CLK 79 +#define GCC_SNOC_PNOC_AHB_CLK 80 +#define GCC_SYS_NOC_AT_CLK 81 +#define GCC_SYS_NOC_USB3_AXI_CLK 82 +#define GCC_SYS_NOC_UFS_AXI_CLK 83 +#define GCC_CFG_NOC_AHB_CLK 84 +#define GCC_PERIPH_NOC_AHB_CLK 85 +#define GCC_PERIPH_NOC_USB20_AHB_CLK 86 +#define GCC_TIC_CLK 87 +#define GCC_IMEM_AXI_CLK 88 +#define GCC_MMSS_SYS_NOC_AXI_CLK 89 +#define GCC_MMSS_NOC_CFG_AHB_CLK 90 +#define GCC_MMSS_BIMC_GFX_CLK 91 +#define GCC_USB30_MASTER_CLK 92 +#define GCC_USB30_SLEEP_CLK 93 +#define GCC_USB30_MOCK_UTMI_CLK 94 +#define GCC_USB3_PHY_AUX_CLK 95 +#define GCC_USB3_PHY_PIPE_CLK 96 +#define GCC_USB20_MASTER_CLK 97 +#define GCC_USB20_SLEEP_CLK 98 +#define GCC_USB20_MOCK_UTMI_CLK 99 +#define GCC_USB_PHY_CFG_AHB2PHY_CLK 100 +#define GCC_SDCC1_APPS_CLK 101 +#define GCC_SDCC1_AHB_CLK 102 +#define GCC_SDCC1_ICE_CORE_CLK 103 +#define GCC_SDCC2_APPS_CLK 104 +#define GCC_SDCC2_AHB_CLK 105 +#define GCC_SDCC3_APPS_CLK 106 +#define GCC_SDCC3_AHB_CLK 107 +#define GCC_SDCC4_APPS_CLK 108 +#define GCC_SDCC4_AHB_CLK 109 +#define GCC_BLSP1_AHB_CLK 110 +#define GCC_BLSP1_SLEEP_CLK 111 +#define GCC_BLSP1_QUP1_SPI_APPS_CLK 112 +#define GCC_BLSP1_QUP1_I2C_APPS_CLK 113 +#define GCC_BLSP1_UART1_APPS_CLK 114 +#define GCC_BLSP1_QUP2_SPI_APPS_CLK 115 +#define GCC_BLSP1_QUP2_I2C_APPS_CLK 116 +#define GCC_BLSP1_UART2_APPS_CLK 117 +#define GCC_BLSP1_QUP3_SPI_APPS_CLK 118 +#define GCC_BLSP1_QUP3_I2C_APPS_CLK 119 +#define GCC_BLSP1_UART3_APPS_CLK 120 +#define GCC_BLSP1_QUP4_SPI_APPS_CLK 121 +#define GCC_BLSP1_QUP4_I2C_APPS_CLK 122 +#define GCC_BLSP1_UART4_APPS_CLK 123 +#define GCC_BLSP1_QUP5_SPI_APPS_CLK 124 +#define GCC_BLSP1_QUP5_I2C_APPS_CLK 125 +#define GCC_BLSP1_UART5_APPS_CLK 126 +#define GCC_BLSP1_QUP6_SPI_APPS_CLK 127 +#define GCC_BLSP1_QUP6_I2C_APPS_CLK 128 +#define GCC_BLSP1_UART6_APPS_CLK 129 +#define GCC_BLSP2_AHB_CLK 130 +#define GCC_BLSP2_SLEEP_CLK 131 +#define GCC_BLSP2_QUP1_SPI_APPS_CLK 132 +#define GCC_BLSP2_QUP1_I2C_APPS_CLK 133 +#define GCC_BLSP2_UART1_APPS_CLK 134 +#define GCC_BLSP2_QUP2_SPI_APPS_CLK 135 +#define GCC_BLSP2_QUP2_I2C_APPS_CLK 136 +#define GCC_BLSP2_UART2_APPS_CLK 137 +#define GCC_BLSP2_QUP3_SPI_APPS_CLK 138 +#define GCC_BLSP2_QUP3_I2C_APPS_CLK 139 +#define GCC_BLSP2_UART3_APPS_CLK 140 +#define GCC_BLSP2_QUP4_SPI_APPS_CLK 141 +#define GCC_BLSP2_QUP4_I2C_APPS_CLK 142 +#define GCC_BLSP2_UART4_APPS_CLK 143 +#define GCC_BLSP2_QUP5_SPI_APPS_CLK 144 +#define GCC_BLSP2_QUP5_I2C_APPS_CLK 145 +#define GCC_BLSP2_UART5_APPS_CLK 146 +#define GCC_BLSP2_QUP6_SPI_APPS_CLK 147 +#define GCC_BLSP2_QUP6_I2C_APPS_CLK 148 +#define GCC_BLSP2_UART6_APPS_CLK 149 +#define GCC_PDM_AHB_CLK 150 +#define GCC_PDM_XO4_CLK 151 +#define GCC_PDM2_CLK 152 +#define GCC_PRNG_AHB_CLK 153 +#define GCC_TSIF_AHB_CLK 154 +#define GCC_TSIF_REF_CLK 155 +#define GCC_TSIF_INACTIVITY_TIMERS_CLK 156 +#define GCC_TCSR_AHB_CLK 157 +#define GCC_BOOT_ROM_AHB_CLK 158 +#define GCC_MSG_RAM_AHB_CLK 159 +#define GCC_TLMM_AHB_CLK 160 +#define GCC_TLMM_CLK 161 +#define GCC_MPM_AHB_CLK 162 +#define GCC_SPMI_SER_CLK 163 +#define GCC_SPMI_CNOC_AHB_CLK 164 +#define GCC_BIMC_HMSS_AXI_CLK 165 +#define GCC_BIMC_GFX_CLK 166 +#define GCC_HMSS_AHB_CLK 167 +#define GCC_HMSS_SLV_AXI_CLK 168 +#define GCC_HMSS_MSTR_AXI_CLK 169 +#define GCC_HMSS_RBCPR_CLK 170 +#define GCC_GP1_CLK 171 +#define GCC_GP2_CLK 172 +#define GCC_GP3_CLK 173 +#define GCC_PCIE_0_SLV_AXI_CLK 174 +#define GCC_PCIE_0_MSTR_AXI_CLK 175 +#define GCC_PCIE_0_CFG_AHB_CLK 176 +#define GCC_PCIE_0_AUX_CLK 177 +#define GCC_PCIE_0_PIPE_CLK 178 +#define GCC_PCIE_1_SLV_AXI_CLK 179 +#define GCC_PCIE_1_MSTR_AXI_CLK 180 +#define GCC_PCIE_1_CFG_AHB_CLK 181 +#define GCC_PCIE_1_AUX_CLK 182 +#define GCC_PCIE_1_PIPE_CLK 183 +#define GCC_PCIE_2_SLV_AXI_CLK 184 +#define GCC_PCIE_2_MSTR_AXI_CLK 185 +#define GCC_PCIE_2_CFG_AHB_CLK 186 +#define GCC_PCIE_2_AUX_CLK 187 +#define GCC_PCIE_2_PIPE_CLK 188 +#define GCC_PCIE_PHY_CFG_AHB_CLK 189 +#define GCC_PCIE_PHY_AUX_CLK 190 +#define GCC_UFS_AXI_CLK 191 +#define GCC_UFS_AHB_CLK 192 +#define GCC_UFS_TX_CFG_CLK 193 +#define GCC_UFS_RX_CFG_CLK 194 +#define GCC_UFS_TX_SYMBOL_0_CLK 195 +#define GCC_UFS_RX_SYMBOL_0_CLK 196 +#define GCC_UFS_RX_SYMBOL_1_CLK 197 +#define GCC_UFS_UNIPRO_CORE_CLK 198 +#define GCC_UFS_ICE_CORE_CLK 199 +#define GCC_UFS_SYS_CLK_CORE_CLK 200 +#define GCC_UFS_TX_SYMBOL_CLK_CORE_CLK 201 +#define GCC_AGGRE0_SNOC_AXI_CLK 202 +#define GCC_AGGRE0_CNOC_AHB_CLK 203 +#define GCC_SMMU_AGGRE0_AXI_CLK 204 +#define GCC_SMMU_AGGRE0_AHB_CLK 205 +#define GCC_AGGRE2_UFS_AXI_CLK 206 +#define GCC_AGGRE2_USB3_AXI_CLK 207 +#define GCC_QSPI_AHB_CLK 208 +#define GCC_QSPI_SER_CLK 209 +#define GCC_USB3_CLKREF_CLK 210 +#define GCC_HDMI_CLKREF_CLK 211 +#define GCC_UFS_CLKREF_CLK 212 +#define GCC_PCIE_CLKREF_CLK 213 +#define GCC_RX2_USB2_CLKREF_CLK 214 +#define GCC_RX1_USB2_CLKREF_CLK 215 +#define GCC_AGGRE0_NOC_QOSGEN_EXTREF_CLK 216 +#define GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK 217 +#define GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK 218 +#define GCC_EDP_CLKREF_CLK 219 +#define GCC_MSS_CFG_AHB_CLK 220 +#define GCC_MSS_Q6_BIMC_AXI_CLK 221 +#define GCC_MSS_SNOC_AXI_CLK 222 +#define GCC_MSS_MNOC_BIMC_AXI_CLK 223 +#define GCC_DCC_AHB_CLK 224 +#define GCC_AGGRE0_NOC_MPU_CFG_AHB_CLK 225 +#define GCC_MMSS_GPLL0_DIV_CLK 226 +#define GPLL0_OUT_MSSCC_CLK 227 + +/* Block resets */ #define GCC_SYSTEM_NOC_BCR 0 #define GCC_CONFIG_NOC_BCR 1 #define GCC_PERIPH_NOC_BCR 2 From 999531d98eb2c6b5afcd7f934631b6f4465691e9 Mon Sep 17 00:00:00 2001 From: Amit Nischal Date: Wed, 21 Dec 2016 17:33:38 +0530 Subject: [PATCH 63/73] clk: qcom: Add smd-rpm voter & voter branch clocks for MSM8996 MSM8996 requires the voter & voter branch clocks to be available for clients to be able to enable/disable and set rate on these clocks. Also add support for keeping active set vote on mmssnoc and pnoc voter clocks. Change-Id: Ie596ddee60aac3e6fc996f9a3e8dc988b0f4aa88 Signed-off-by: Amit Nischal --- drivers/clk/qcom/clk-smd-rpm.c | 93 +++++++++++++++++++------- include/dt-bindings/clock/qcom,rpmcc.h | 1 + 2 files changed, 71 insertions(+), 23 deletions(-) diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index c6ea293a8df3..d14c32bffe14 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -551,6 +551,39 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, bb_clk2_pin, bb_clk2_a_pin, 2); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, rf_clk1_pin, rf_clk1_a_pin, 4); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, rf_clk2_pin, rf_clk2_a_pin, 5); +/* Voter clocks */ +static DEFINE_CLK_VOTER(mmssnoc_axi_clk, mmssnoc_axi_rpm_clk, 0); +static DEFINE_CLK_VOTER(mmssnoc_axi_a_clk, mmssnoc_axi_rpm_a_clk, 0); +static DEFINE_CLK_VOTER(mmssnoc_gds_clk, mmssnoc_axi_rpm_clk, 40000000); +static DEFINE_CLK_VOTER(bimc_msmbus_clk, bimc_clk, LONG_MAX); +static DEFINE_CLK_VOTER(bimc_msmbus_a_clk, bimc_a_clk, LONG_MAX); +static DEFINE_CLK_VOTER(cnoc_msmbus_clk, cnoc_clk, LONG_MAX); +static DEFINE_CLK_VOTER(cnoc_msmbus_a_clk, cnoc_a_clk, LONG_MAX); +static DEFINE_CLK_VOTER(snoc_msmbus_clk, snoc_clk, LONG_MAX); +static DEFINE_CLK_VOTER(snoc_msmbus_a_clk, snoc_a_clk, LONG_MAX); +static DEFINE_CLK_VOTER(cnoc_periph_keepalive_a_clk, cnoc_periph_a_clk, + LONG_MAX); +static DEFINE_CLK_VOTER(mcd_ce1_clk, ce1_clk, 85710000); +static DEFINE_CLK_VOTER(qcedev_ce1_clk, ce1_clk, 85710000); +static DEFINE_CLK_VOTER(qcrypto_ce1_clk, ce1_clk, 85710000); +static DEFINE_CLK_VOTER(qseecom_ce1_clk, ce1_clk, 85710000); +static DEFINE_CLK_VOTER(scm_ce1_clk, ce1_clk, 85710000); +static DEFINE_CLK_VOTER(pnoc_keepalive_a_clk, pnoc_a_clk, LONG_MAX); +static DEFINE_CLK_VOTER(pnoc_msmbus_clk, pnoc_clk, LONG_MAX); +static DEFINE_CLK_VOTER(pnoc_msmbus_a_clk, pnoc_a_clk, LONG_MAX); +static DEFINE_CLK_VOTER(pnoc_pm_clk, pnoc_clk, LONG_MAX); +static DEFINE_CLK_VOTER(pnoc_sps_clk, pnoc_clk, 0); +static DEFINE_CLK_VOTER(mmssnoc_a_clk_cpu_vote, mmssnoc_axi_rpm_a_clk, + 19200000); + +/* Voter Branch clocks */ +static DEFINE_CLK_BRANCH_VOTER(cxo_dwc3_clk, cxo); +static DEFINE_CLK_BRANCH_VOTER(cxo_lpm_clk, cxo); +static DEFINE_CLK_BRANCH_VOTER(cxo_otg_clk, cxo); +static DEFINE_CLK_BRANCH_VOTER(cxo_pil_lpass_clk, cxo); +static DEFINE_CLK_BRANCH_VOTER(cxo_pil_ssc_clk, cxo); +static DEFINE_CLK_BRANCH_VOTER(cxo_pil_cdsp_clk, cxo); + static struct clk_hw *msm8996_clks[] = { [RPM_XO_CLK_SRC] = &msm8996_cxo.hw, [RPM_XO_A_CLK_SRC] = &msm8996_cxo_a.hw, @@ -590,6 +623,31 @@ static struct clk_hw *msm8996_clks[] = { [RPM_DIV_CLK3_AO] = &msm8996_div_clk3_ao.hw, [RPM_LN_BB_CLK] = &msm8996_ln_bb_clk.hw, [RPM_LN_BB_A_CLK] = &msm8996_ln_bb_a_clk.hw, + [MMSSNOC_AXI_CLK] = &mmssnoc_axi_clk.hw, + [MMSSNOC_AXI_A_CLK] = &mmssnoc_axi_a_clk.hw, + [MMSSNOC_GDS_CLK] = &mmssnoc_gds_clk.hw, + [BIMC_MSMBUS_CLK] = &bimc_msmbus_clk.hw, + [BIMC_MSMBUS_A_CLK] = &bimc_msmbus_a_clk.hw, + [CNOC_MSMBUS_CLK] = &cnoc_msmbus_clk.hw, + [CNOC_MSMBUS_A_CLK] = &cnoc_msmbus_a_clk.hw, + [PNOC_KEEPALIVE_A_CLK] = &pnoc_keepalive_a_clk.hw, + [PNOC_MSMBUS_CLK] = &pnoc_msmbus_clk.hw, + [PNOC_MSMBUS_A_CLK] = &pnoc_msmbus_a_clk.hw, + [PNOC_PM_CLK] = &pnoc_pm_clk.hw, + [PNOC_SPS_CLK] = &pnoc_sps_clk.hw, + [MCD_CE1_CLK] = &mcd_ce1_clk.hw, + [QCEDEV_CE1_CLK] = &qcedev_ce1_clk.hw, + [QCRYPTO_CE1_CLK] = &qcrypto_ce1_clk.hw, + [QSEECOM_CE1_CLK] = &qseecom_ce1_clk.hw, + [SCM_CE1_CLK] = &scm_ce1_clk.hw, + [SNOC_MSMBUS_CLK] = &snoc_msmbus_clk.hw, + [SNOC_MSMBUS_A_CLK] = &snoc_msmbus_a_clk.hw, + [CXO_DWC3_CLK] = &cxo_dwc3_clk.hw, + [CXO_LPM_CLK] = &cxo_lpm_clk.hw, + [CXO_OTG_CLK] = &cxo_otg_clk.hw, + [CXO_PIL_LPASS_CLK] = &cxo_pil_lpass_clk.hw, + [CXO_PIL_SSC_CLK] = &cxo_pil_ssc_clk.hw, + [MMSSNOC_A_CLK_CPU_VOTE] = &mmssnoc_a_clk_cpu_vote.hw }; static const struct rpm_smd_clk_desc rpm_clk_msm8996 = { @@ -627,26 +685,6 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msmfalcon, ln_bb_clk2_pin, ln_bb_clk2_pin_ao, 0x2); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msmfalcon, ln_bb_clk3_pin, ln_bb_clk3_pin_ao, 0x3); -/* Voter clocks */ -static DEFINE_CLK_VOTER(bimc_msmbus_clk, bimc_clk, LONG_MAX); -static DEFINE_CLK_VOTER(bimc_msmbus_a_clk, bimc_a_clk, LONG_MAX); -static DEFINE_CLK_VOTER(cnoc_msmbus_clk, cnoc_clk, LONG_MAX); -static DEFINE_CLK_VOTER(cnoc_msmbus_a_clk, cnoc_a_clk, LONG_MAX); -static DEFINE_CLK_VOTER(snoc_msmbus_clk, snoc_clk, LONG_MAX); -static DEFINE_CLK_VOTER(snoc_msmbus_a_clk, snoc_a_clk, LONG_MAX); -static DEFINE_CLK_VOTER(cnoc_periph_keepalive_a_clk, cnoc_periph_a_clk, - LONG_MAX); -static DEFINE_CLK_VOTER(mcd_ce1_clk, ce1_clk, 85710000); -static DEFINE_CLK_VOTER(qcedev_ce1_clk, ce1_clk, 85710000); -static DEFINE_CLK_VOTER(qcrypto_ce1_clk, ce1_clk, 85710000); -static DEFINE_CLK_VOTER(qseecom_ce1_clk, ce1_clk, 85710000); -static DEFINE_CLK_VOTER(scm_ce1_clk, ce1_clk, 85710000); - -static DEFINE_CLK_BRANCH_VOTER(cxo_dwc3_clk, cxo); -static DEFINE_CLK_BRANCH_VOTER(cxo_lpm_clk, cxo); -static DEFINE_CLK_BRANCH_VOTER(cxo_otg_clk, cxo); -static DEFINE_CLK_BRANCH_VOTER(cxo_pil_lpass_clk, cxo); -static DEFINE_CLK_BRANCH_VOTER(cxo_pil_cdsp_clk, cxo); static struct clk_hw *msmfalcon_clks[] = { [RPM_XO_CLK_SRC] = &msmfalcon_cxo.hw, @@ -799,10 +837,19 @@ static int rpm_smd_clk_probe(struct platform_device *pdev) if (ret) goto err; - /* Keep an active vote on CXO in case no other driver votes for it */ - if (is_8996) + if (is_8996) { + /* + * Keep an active vote on CXO in case no other driver + * votes for it. + */ clk_prepare_enable(msm8996_cxo_a.hw.clk); - else if (is_falcon) { + + /* Hold an active set vote for the pnoc_keepalive_a_clk */ + clk_set_rate(pnoc_keepalive_a_clk.hw.clk, 19200000); + clk_prepare_enable(pnoc_keepalive_a_clk.hw.clk); + + clk_prepare_enable(mmssnoc_a_clk_cpu_vote.hw.clk); + } else if (is_falcon) { clk_prepare_enable(msmfalcon_cxo_a.hw.clk); /* Hold an active set vote for the cnoc_periph resource */ diff --git a/include/dt-bindings/clock/qcom,rpmcc.h b/include/dt-bindings/clock/qcom,rpmcc.h index bcaa1a552e8e..0f0c6300642c 100644 --- a/include/dt-bindings/clock/qcom,rpmcc.h +++ b/include/dt-bindings/clock/qcom,rpmcc.h @@ -128,5 +128,6 @@ #define CXO_PIL_SSC_CLK 83 #define CXO_PIL_CDSP_CLK 84 #define CNOC_PERIPH_KEEPALIVE_A_CLK 85 +#define MMSSNOC_A_CLK_CPU_VOTE 86 #endif From 88abb7ca686923e600c7d278c8ef44b9240e7ad4 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 22 Dec 2016 12:45:30 +0530 Subject: [PATCH 64/73] ARM: dts: msm: Enable audio internal codec nodes for msmfalcon Enable internal codec audio nodes and disable external codec nodes in internal codec platform. CRs-Fixed: 1094763 Change-Id: Ib17d8bbd5894be5fbf3fa0cafdbec958abc42649 Signed-off-by: Laxminath Kasam --- arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi | 5 +- .../dts/qcom/msmfalcon-internal-codec-cdp.dts | 48 ++++++++++++++++++ .../dts/qcom/msmfalcon-internal-codec-mtp.dts | 49 +++++++++++++++++++ .../dts/qcom/msmfalcon-internal-codec-rcm.dts | 48 ++++++++++++++++++ 4 files changed, 148 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi index bf367944f50c..df42ba124641 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi @@ -15,12 +15,13 @@ #include "msmfalcon-lpi.dtsi" &slim_aud { - msm_dai_slim { + status = "okay"; + dai_slim: msm_dai_slim { compatible = "qcom,msm-dai-slim"; elemental-addr = [ff ff ff fe 17 02]; }; - tasha_codec { + wcd9335: tasha_codec { compatible = "qcom,tasha-slim-pgd"; elemental-addr = [00 01 a0 01 17 02]; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-cdp.dts b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-cdp.dts index 108328bd91f0..fd5e298b572b 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-cdp.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-cdp.dts @@ -21,3 +21,51 @@ compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; qcom,board-id = <1 1>; }; + +&slim_aud { + status = "disabled"; +}; + +&dai_slim { + status = "disabled"; +}; + +&wcd9335 { + status = "disabled"; +}; + +&wcd934x_cdc { + status = "disabled"; +}; + +&clock_audio { + status = "disabled"; +}; + +&wcd_rst_gpio { + status = "disabled"; +}; + +&wcd9xxx_intc { + status = "disabled"; +}; + +&tasha_snd { + status = "disabled"; +}; + +&tavil_snd { + status = "disabled"; +}; + +&int_codec { + status = "okay"; +}; + +&pmic_analog_codec { + status = "okay"; +}; + +&msm_sdw_codec { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-mtp.dts b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-mtp.dts index 3697ee8f97a0..260278724087 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-mtp.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-mtp.dts @@ -21,3 +21,52 @@ compatible = "qcom,msmfalcon-mtp", "qcom,msmfalcon", "qcom,mtp"; qcom,board-id = <8 1>; }; + +&slim_aud { + status = "disabled"; +}; + +&dai_slim { + status = "disabled"; +}; + +&wcd9335 { + status = "disabled"; +}; + +&wcd934x_cdc { + status = "disabled"; +}; + +&clock_audio { + status = "disabled"; +}; + +&wcd_rst_gpio { + status = "disabled"; +}; + +&wcd9xxx_intc { + status = "disabled"; +}; + +&tasha_snd { + status = "disabled"; +}; + +&tavil_snd { + status = "disabled"; +}; + +&int_codec { + qcom,model = "msmfalcon-snd-card-mtp"; + status = "okay"; +}; + +&pmic_analog_codec { + status = "okay"; +}; + +&msm_sdw_codec { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-rcm.dts b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-rcm.dts index bbdc41b97574..3980b977228b 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-rcm.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-rcm.dts @@ -21,3 +21,51 @@ compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; qcom,board-id = <21 1>; }; + +&slim_aud { + status = "disabled"; +}; + +&dai_slim { + status = "disabled"; +}; + +&wcd9335 { + status = "disabled"; +}; + +&wcd934x_cdc { + status = "disabled"; +}; + +&clock_audio { + status = "disabled"; +}; + +&wcd_rst_gpio { + status = "disabled"; +}; + +&wcd9xxx_intc { + status = "disabled"; +}; + +&tasha_snd { + status = "disabled"; +}; + +&tavil_snd { + status = "disabled"; +}; + +&int_codec { + status = "okay"; +}; + +&pmic_analog_codec { + status = "okay"; +}; + +&msm_sdw_codec { + status = "okay"; +}; From ac038b44a9e26b611c19f63ad4c37cf58df2f9ed Mon Sep 17 00:00:00 2001 From: Amit Nischal Date: Tue, 20 Dec 2016 15:58:22 +0530 Subject: [PATCH 65/73] clk: qcom: Add FORCE_ENABLE_RCGR & CLK_ENABLE_HAND_OFF flag for MSMfalcon Some clocks are critical for system booting and should not be gated until a driver that knows best claims those clocks. Add CLK_ENABLE_HAND_OFF flag for system critical clocks. Also add FORCE_ENABLE_RCGR flag to force enable/disable RCG and fix camss_jpeg0 voter clock. Change-Id: I482bbf480d4129cdc6a1dfe08f37a1ec56c3131e Signed-off-by: Amit Nischal --- drivers/clk/qcom/gcc-msmfalcon.c | 6 +++++- drivers/clk/qcom/mmcc-msmfalcon.c | 11 ++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/clk/qcom/gcc-msmfalcon.c b/drivers/clk/qcom/gcc-msmfalcon.c index dfcd55ab2c26..1e1c871ef22c 100644 --- a/drivers/clk/qcom/gcc-msmfalcon.c +++ b/drivers/clk/qcom/gcc-msmfalcon.c @@ -1229,6 +1229,7 @@ static struct clk_branch gcc_blsp1_ahb_clk = { .enable_mask = BIT(17), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_ahb_clk", + .flags = CLK_ENABLE_HAND_OFF, .ops = &clk_branch2_ops, }, }, @@ -1422,6 +1423,7 @@ static struct clk_branch gcc_blsp2_ahb_clk = { .enable_mask = BIT(15), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_ahb_clk", + .flags = CLK_ENABLE_HAND_OFF, .ops = &clk_branch2_ops, }, }, @@ -2844,7 +2846,7 @@ static struct measure_clk_data debug_mux_priv = { static const char *const debug_mux_parent_names[] = { "snoc_clk", "cnoc_clk", - "cnoc_periph", + "cnoc_periph_clk", "bimc_clk", "ce1_clk", "ipa_clk", @@ -2924,6 +2926,7 @@ static const char *const debug_mux_parent_names[] = { "gcc_ufs_rx_symbol_1_clk", "gcc_ufs_tx_symbol_0_clk", "gcc_usb3_phy_pipe_clk", + "mmssnoc_axi_clk", "mmss_bimc_smmu_ahb_clk", "mmss_bimc_smmu_axi_clk", "mmss_camss_ahb_clk", @@ -3104,6 +3107,7 @@ static struct clk_debug_mux gcc_debug_mux = { { "gcc_ufs_rx_symbol_1_clk", 0x162 }, { "gcc_ufs_tx_symbol_0_clk", 0x0EC }, { "gcc_usb3_phy_pipe_clk", 0x040 }, + { "mmssnoc_axi_clk", 0x22, MMCC, 0x004 }, { "mmss_bimc_smmu_ahb_clk", 0x22, MMCC, 0x00C }, { "mmss_bimc_smmu_axi_clk", 0x22, MMCC, 0x00D }, { "mmss_camss_ahb_clk", 0x22, MMCC, 0x037 }, diff --git a/drivers/clk/qcom/mmcc-msmfalcon.c b/drivers/clk/qcom/mmcc-msmfalcon.c index 44611bfce0d1..59dbebd825fd 100644 --- a/drivers/clk/qcom/mmcc-msmfalcon.c +++ b/drivers/clk/qcom/mmcc-msmfalcon.c @@ -529,6 +529,7 @@ static struct clk_rcg2 ahb_clk_src = { .hid_width = 5, .parent_map = mmcc_parent_map_10, .freq_tbl = ftbl_ahb_clk_src, + .flags = FORCE_ENABLE_RCGR, .clkr.hw.init = &(struct clk_init_data){ .name = "ahb_clk_src", .parent_names = mmcc_parent_names_10, @@ -1281,6 +1282,7 @@ static struct clk_rcg2 video_core_clk_src = { .hid_width = 5, .parent_map = mmcc_parent_map_12, .freq_tbl = ftbl_video_core_clk_src, + .flags = FORCE_ENABLE_RCGR, .clkr.hw.init = &(struct clk_init_data){ .name = "video_core_clk_src", .parent_names = mmcc_parent_names_12, @@ -1323,6 +1325,7 @@ static struct clk_branch mmss_bimc_smmu_ahb_clk = { .parent_names = (const char *[]){ "ahb_clk_src", }, + .flags = CLK_ENABLE_HAND_OFF, .num_parents = 1, .ops = &clk_branch2_ops, }, @@ -1337,6 +1340,7 @@ static struct clk_branch mmss_bimc_smmu_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "mmss_bimc_smmu_axi_clk", + .flags = CLK_ENABLE_HAND_OFF, .ops = &clk_branch2_ops, }, }, @@ -2016,9 +2020,9 @@ static struct clk_branch mmss_camss_jpeg0_clk = { }, }; -static DEFINE_CLK_VOTER(mmss_camss_jpeg0_vote_clk, &mmss_camss_jpeg0_clk.c, 0); +static DEFINE_CLK_VOTER(mmss_camss_jpeg0_vote_clk, mmss_camss_jpeg0_clk, 0); static DEFINE_CLK_VOTER(mmss_camss_jpeg0_dma_vote_clk, - &mmss_camss_jpeg0_clk.c, 0); + mmss_camss_jpeg0_clk, 0); static struct clk_branch mmss_camss_jpeg_ahb_clk = { .halt_reg = 0x35b4, @@ -2318,6 +2322,7 @@ static struct clk_branch mmss_mdss_ahb_clk = { .parent_names = (const char *[]){ "ahb_clk_src", }, + .flags = CLK_ENABLE_HAND_OFF, .num_parents = 1, .ops = &clk_branch2_ops, }, @@ -2602,7 +2607,7 @@ static struct clk_branch mmss_mdss_mdp_clk = { "mdp_clk_src", }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_ENABLE_HAND_OFF, .ops = &clk_branch2_ops, }, }, From ace411555c8814c2cac6c10106e89434de11145c Mon Sep 17 00:00:00 2001 From: Liangliang Lu Date: Mon, 26 Dec 2016 15:42:32 +0800 Subject: [PATCH 66/73] ARM: dts: msm: enable vdd and vdd-io for sdhc_2 on msm8998 interposer This change enables vdd and vdd-io power supply for sdhc2 in msm8998 v2.1 interposer msmfalcon QRD dts file. CRs-Fixed: 1099484 Change-Id: I58c30a50c7834e7897daa2849b9885b3e797cf07 Signed-off-by: Liangliang Lu --- .../boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts index 44c4b74dd696..3de548ed1446 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts @@ -118,6 +118,11 @@ core-supply = <&pmfalcon_l1>; }; +&sdhc_2 { + vdd-supply = <&pm2falcon_l5>; + vdd-io-supply = <&pm2falcon_l2>; +}; + &pm2falcon_gpios { /* GPIO 7 for VOL_UP */ gpio@c600 { From da422925cd8f4ebdbc220c3add5e9e349f11b1fe Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Sun, 27 Nov 2016 12:27:17 +0530 Subject: [PATCH 67/73] ARM: dts: msm: Add support for CPU clocks for msmfalcon OSM cpu clock node is required by cpufreq client to be able to scale cpu frequency. Add tables of various speed bins supported and keep the status of the clock node disabled for now. Change-Id: I0aca021e51ef9ae59dedce855430a63937eb98c6 Signed-off-by: Taniya Das --- arch/arm/boot/dts/qcom/msmfalcon.dtsi | 95 +++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmfalcon.dtsi index c43781f3939e..b57e7d033c70 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon.dtsi @@ -1083,6 +1083,101 @@ }; }; + clock_cpu: qcom,clk-cpu-falcon@179c0000 { + compatible = "qcom,clk-cpu-osm"; + status = "disabled"; + reg = <0x179c0000 0x4000>, <0x17916000 0x1000>, + <0x17816000 0x1000>, <0x179d1000 0x1000>, + <0x00784130 0x8>; + reg-names = "osm", "pwrcl_pll", "perfcl_pll", + "apcs_common", "perfcl_efuse"; + + /* ToDo: Add power and perf supply rails */ + + interrupts = , + ; + interrupt-names = "pwrcl-irq", "perfcl-irq"; + + qcom,pwrcl-speedbin0-v0 = + < 300000000 0x0004000f 0x01200020 0x1 1 >, + < 633600000 0x05040021 0x03200020 0x1 1 >, + < 902400000 0x0404002f 0x04260026 0x1 2 >, + < 1113600000 0x0404003a 0x052e002e 0x2 3 >, + < 1401600000 0x04040049 0x073a003a 0x2 4 >, + < 1536000000 0x04040050 0x08400040 0x3 5 >, + < 1747200000 0x0404005b 0x09480048 0x3 6 >, + < 1843200000 0x04040060 0x094c004c 0x3 7 >; + + qcom,perfcl-speedbin0-v0 = + < 300000000 0x0004000f 0x01200020 0x1 1 >, + < 1113600000 0x0404003a 0x052e002e 0x1 1 >, + < 1401600000 0x04040049 0x073a003a 0x2 2 >, + < 1747200000 0x0404005b 0x09480048 0x2 3 >, + < 1958400000 0x04040066 0x0a510051 0x3 4 >, + < 2150400000 0x04040070 0x0b590059 0x3 5 >, + < 2457600000 0x04040080 0x0c660066 0x3 6 >; + + qcom,perfcl-speedbin1-v0 = + < 300000000 0x0004000f 0x01200020 0x1 1 >, + < 1113600000 0x0404003a 0x052e002e 0x1 1 >, + < 1401600000 0x04040049 0x073a003a 0x2 2 >, + < 1747200000 0x0404005b 0x09480048 0x2 3 >, + < 1958400000 0x04040066 0x0a510051 0x3 4 >, + < 2150400000 0x04040070 0x0b590059 0x3 5 >, + < 2208000000 0x04040073 0x0b5c005c 0x3 6 >; + + qcom,up-timer = <1000 1000>; + qcom,down-timer = <1000 1000>; + qcom,pc-override-index = <0 0>; + qcom,set-ret-inactive; + qcom,enable-llm-freq-vote; + qcom,llm-freq-up-timer = <327675 327675>; + qcom,llm-freq-down-timer = <327675 327675>; + qcom,enable-llm-volt-vote; + qcom,llm-volt-up-timer = <327675 327675>; + qcom,llm-volt-down-timer = <327675 327675>; + qcom,cc-reads = <10>; + qcom,cc-delay = <5>; + qcom,cc-factor = <100>; + qcom,osm-clk-rate = <200000000>; + qcom,xo-clk-rate = <19200000>; + + qcom,l-val-base = <0x17916004 0x17816004>; + qcom,apcs-itm-present = <0x179d143c 0x179d143c>; + qcom,apcs-pll-user-ctl = <0x1791600c 0x1781600c>; + qcom,apcs-cfg-rcgr = <0x17911054 0x17811054>; + qcom,apcs-cmd-rcgr = <0x17911050 0x17811050>; + qcom,apm-mode-ctl = <0x179d0004 0x179d0010>; + qcom,apm-ctrl-status = <0x179d000c 0x179d0018>; + + qcom,apm-threshold-voltage = <832000>; + qcom,boost-fsm-en; + qcom,safe-fsm-en; + qcom,ps-fsm-en; + qcom,droop-fsm-en; + qcom,wfx-fsm-en; + qcom,pc-fsm-en; + + qcom,pwrcl-apcs-mem-acc-cfg = + <0x179d1360 0x179d1364 0x179d1364>; + qcom,perfcl-apcs-mem-acc-cfg = + <0x179d1368 0x179d136C 0x179d1370>; + qcom,pwrcl-apcs-mem-acc-val = + <0x00000000 0x80000000 0x80000000>, + <0x00000000 0x00000000 0x00000000>, + <0x00000000 0x00000001 0x00000001>; + qcom,perfcl-apcs-mem-acc-val = + <0x00000000 0x00000000 0x80000000>, + <0x00000000 0x00000000 0x00000000>, + <0x00000000 0x00000000 0x00000001>; + + clock-names = "aux_clk", "xo_a"; + clocks = <&clock_gcc HMSS_GPLL0_CLK_SRC>, + <&clock_rpmcc RPM_XO_A_CLK_SRC>; + + #clock-cells = <1>; + }; + sdhc_1: sdhci@c0c4000 { compatible = "qcom,sdhci-msm-v5"; reg = <0xc0c4000 0x1000>, <0xc0c5000 0x1000>; From 221fbb9e16a3b67599660e29fb3b436660a67c13 Mon Sep 17 00:00:00 2001 From: Hamad Kadmany Date: Mon, 26 Dec 2016 10:33:29 +0200 Subject: [PATCH 68/73] wil6210: missing reinit_completion in wmi_call The code in wmi_call uses the wil->wmi_call completion structure to wait for a reply. In some scenarios, complete was called twice on the completion structure. This happened mainly with a disconnect event which can arrive both unsolicited and as a reply to a disconnect request. In this case the completion structure was left marked as "done" and the next wmi_call returned immediately with a corrupted reply buffer. This caused unexpected results including crashes. Fix this by adding the missing call to reinit_completion. CRs-Fixed: 1105246 Change-Id: I4de26881620dde4230d0a907bd0fd39bebe2bb3d Signed-off-by: Hamad Kadmany --- drivers/net/wireless/ath/wil6210/wmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index daa7a33d12d8..f5575747d11e 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -964,6 +964,7 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, wil->reply_id = reply_id; wil->reply_buf = reply; wil->reply_size = reply_size; + reinit_completion(&wil->wmi_call); spin_unlock(&wil->wmi_ev_lock); rc = __wmi_send(wil, cmdid, buf, len); From 78923e0bee41be31d55eb490ab45df5ad329bcfc Mon Sep 17 00:00:00 2001 From: cyizhao Date: Fri, 23 Dec 2016 10:28:17 +0800 Subject: [PATCH 69/73] ARM: dts: msm: disable soft hot JEITA for 8998 QRD SKUK and VR1 QRD SKUK and VR1 has fixed battery design and the batteries have defect of the NTC design which is very easy to hit soft hot threshold when charging at 1C while the battery cell is actually stay much cooler. Disable soft hot jeita threshold according to the battery vendor's and hardware team's suggestion to make sure the battery could sustain at 1C charging current longer. CRs-Fixed: 1104853 Change-Id: If624bf14e8588e50fa6a97d29b528d7d02ef64dc Signed-off-by: cyizhao --- arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi | 1 + arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi index feadeccb1561..22a72f8daef7 100644 --- a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi @@ -299,6 +299,7 @@ &pmi8998_fg { qcom,battery-data = <&qrd_batterydata>; + qcom,fg-jeita-thresholds = <0 5 55 55>; }; &pmi8998_haptics { diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi index 7b67bdb7243b..c67bbcefad80 100644 --- a/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi @@ -196,6 +196,7 @@ &pmi8998_fg { qcom,battery-data = <&qrd_batterydata>; + qcom,fg-jeita-thresholds = <0 5 55 55>; }; &pmi8998_haptics { From cbfc55e3b427700e3eb98765a9cf578041763873 Mon Sep 17 00:00:00 2001 From: cyizhao Date: Fri, 23 Dec 2016 16:45:22 +0800 Subject: [PATCH 70/73] ARM: dts: msm: set wled string/full scale current for QRD8998 SKUK Specify the number of strings and full scale current in WLED property according to the hardware design of QRD8998 SKUK. CRs-Fixed: 1104977 Change-Id: I575aecb616a56974ec2680e5888190adb40c969a Signed-off-by: cyizhao --- arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi index 22a72f8daef7..07a0e6e6d5ad 100644 --- a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi @@ -306,6 +306,11 @@ status = "okay"; }; +&pmi8998_wled { + qcom,led-strings-list = [00 01]; + qcom,fs-curr-ua = <20000>; +}; + &tlmm { /* add pingrp for touchscreen */ pmx_ts_rst_active { From f7ae4042cd2e1805a1e7afe317eb529c212ff486 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Wed, 21 Dec 2016 13:02:38 +0530 Subject: [PATCH 71/73] diag: dci: Fix possible dangling reference This patch prevents the arise of dangling pointer after kfree operation on pointer. CRs-Fixed: 1083444 Change-Id: Ie2702223379b9c77ce4fe30376d446c63223dbc8 Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_dci.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index 7af9d8184f97..f47b390375c4 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -771,6 +771,7 @@ static int diag_dci_remove_req_entry(unsigned char *buf, int len, if (*buf != 0x80) { list_del(&entry->track); kfree(entry); + entry = NULL; return 1; } @@ -788,6 +789,7 @@ static int diag_dci_remove_req_entry(unsigned char *buf, int len, if (delayed_rsp_id == 0) { list_del(&entry->track); kfree(entry); + entry = NULL; return 1; } @@ -801,6 +803,7 @@ static int diag_dci_remove_req_entry(unsigned char *buf, int len, if (rsp_count > 0 && rsp_count < 0x1000) { list_del(&entry->track); kfree(entry); + entry = NULL; return 1; } @@ -2682,10 +2685,12 @@ int diag_dci_init(void) err: pr_err("diag: Could not initialize diag DCI buffers"); kfree(driver->apps_dci_buf); + driver->apps_dci_buf = NULL; if (driver->diag_dci_wq) destroy_workqueue(driver->diag_dci_wq); kfree(partial_pkt.data); + partial_pkt.data = NULL; mutex_destroy(&driver->dci_mutex); mutex_destroy(&dci_log_mask_mutex); mutex_destroy(&dci_event_mask_mutex); @@ -2705,7 +2710,9 @@ void diag_dci_channel_init(void) void diag_dci_exit(void) { kfree(partial_pkt.data); + partial_pkt.data = NULL; kfree(driver->apps_dci_buf); + driver->apps_dci_buf = NULL; mutex_destroy(&driver->dci_mutex); mutex_destroy(&dci_log_mask_mutex); mutex_destroy(&dci_event_mask_mutex); @@ -2917,22 +2924,30 @@ fail_alloc: mutex_destroy(&proc_buf->health_mutex); if (proc_buf->buf_primary) { kfree(proc_buf->buf_primary->data); + proc_buf->buf_primary->data = NULL; mutex_destroy( &proc_buf->buf_primary->data_mutex); } kfree(proc_buf->buf_primary); + proc_buf->buf_primary = NULL; if (proc_buf->buf_cmd) { kfree(proc_buf->buf_cmd->data); + proc_buf->buf_cmd->data = NULL; mutex_destroy( &proc_buf->buf_cmd->data_mutex); } kfree(proc_buf->buf_cmd); + proc_buf->buf_cmd = NULL; } } kfree(new_entry->dci_event_mask); + new_entry->dci_event_mask = NULL; kfree(new_entry->dci_log_mask); + new_entry->dci_log_mask = NULL; kfree(new_entry->buffers); + new_entry->buffers = NULL; kfree(new_entry); + new_entry = NULL; } mutex_unlock(&driver->dci_mutex); return DIAG_DCI_NO_REG; @@ -2963,6 +2978,7 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry) * masks and send the masks to peripherals */ kfree(entry->dci_log_mask); + entry->dci_log_mask = NULL; diag_dci_invalidate_cumulative_log_mask(token); if (token == DCI_LOCAL_PROC) diag_update_userspace_clients(DCI_LOG_MASKS_TYPE); @@ -2971,6 +2987,7 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry) return ret; } kfree(entry->dci_event_mask); + entry->dci_event_mask = NULL; diag_dci_invalidate_cumulative_event_mask(token); if (token == DCI_LOCAL_PROC) diag_update_userspace_clients(DCI_EVENT_MASKS_TYPE); @@ -2986,6 +3003,7 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry) if (!list_empty(&req_entry->track)) list_del(&req_entry->track); kfree(req_entry); + req_entry = NULL; } } @@ -3001,6 +3019,7 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry) buf_entry->data = NULL; mutex_unlock(&buf_entry->data_mutex); kfree(buf_entry); + buf_entry = NULL; } else if (buf_entry->buf_type == DCI_BUF_CMD) { peripheral = buf_entry->data_source; if (peripheral == APPS_DATA) @@ -3027,14 +3046,17 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry) mutex_unlock(&buf_entry->data_mutex); mutex_destroy(&buf_entry->data_mutex); kfree(buf_entry); + buf_entry = NULL; } mutex_lock(&proc_buf->buf_primary->data_mutex); kfree(proc_buf->buf_primary->data); + proc_buf->buf_primary->data = NULL; mutex_unlock(&proc_buf->buf_primary->data_mutex); mutex_lock(&proc_buf->buf_cmd->data_mutex); kfree(proc_buf->buf_cmd->data); + proc_buf->buf_cmd->data = NULL; mutex_unlock(&proc_buf->buf_cmd->data_mutex); mutex_destroy(&proc_buf->health_mutex); @@ -3042,13 +3064,17 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry) mutex_destroy(&proc_buf->buf_cmd->data_mutex); kfree(proc_buf->buf_primary); + proc_buf->buf_primary = NULL; kfree(proc_buf->buf_cmd); + proc_buf->buf_cmd = NULL; mutex_unlock(&proc_buf->buf_mutex); } mutex_destroy(&entry->write_buf_mutex); kfree(entry->buffers); + entry->buffers = NULL; kfree(entry); + entry = NULL; if (driver->num_dci_client == 0) { diag_update_proc_vote(DIAG_PROC_DCI, VOTE_DOWN, token); From 118a4b58d1407934f1e1b9ea9ee7aace0a96553b Mon Sep 17 00:00:00 2001 From: Girish Mahadevan Date: Tue, 28 Jun 2016 10:50:38 -0600 Subject: [PATCH 72/73] spi: spi_qsd: Fix the register peek/poke debug feature The spi_qsd driver allows peeking/poking registers via debugfs. Currently a static variable is used as the user data to get to the spi controller data structure. Unfortunately this means that the last device to probe is always obtained. Fix this to use a member of the spi controller data structure instead. Change-Id: I711354941b4168f3f6ffe2d29185597bdad4da89 Signed-off-by: Girish Mahadevan --- drivers/spi/spi_qsd.c | 23 ++++++++------ drivers/spi/spi_qsd.h | 73 +++++++++++++++++++++---------------------- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c index a5d59e7f2d90..7aa04a4fa156 100644 --- a/drivers/spi/spi_qsd.c +++ b/drivers/spi/spi_qsd.c @@ -1830,15 +1830,15 @@ err_setup_exit: static int debugfs_iomem_x32_set(void *data, u64 val) { - struct msm_spi_regs *debugfs_spi_regs = (struct msm_spi_regs *)data; - struct msm_spi *dd = debugfs_spi_regs->dd; + struct msm_spi_debugfs_data *reg = (struct msm_spi_debugfs_data *)data; + struct msm_spi *dd = reg->dd; int ret; ret = pm_runtime_get_sync(dd->dev); if (ret < 0) return ret; - writel_relaxed(val, (dd->base + debugfs_spi_regs->offset)); + writel_relaxed(val, (dd->base + reg->offset)); /* Ensure the previous write completed. */ mb(); @@ -1849,14 +1849,14 @@ static int debugfs_iomem_x32_set(void *data, u64 val) static int debugfs_iomem_x32_get(void *data, u64 *val) { - struct msm_spi_regs *debugfs_spi_regs = (struct msm_spi_regs *)data; - struct msm_spi *dd = debugfs_spi_regs->dd; + struct msm_spi_debugfs_data *reg = (struct msm_spi_debugfs_data *)data; + struct msm_spi *dd = reg->dd; int ret; ret = pm_runtime_get_sync(dd->dev); if (ret < 0) return ret; - *val = readl_relaxed(dd->base + debugfs_spi_regs->offset); + *val = readl_relaxed(dd->base + reg->offset); /* Ensure the previous read completed. */ mb(); @@ -1870,18 +1870,21 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, debugfs_iomem_x32_get, static void spi_debugfs_init(struct msm_spi *dd) { - dd->dent_spi = debugfs_create_dir(dev_name(dd->dev), NULL); + char dir_name[20]; + + scnprintf(dir_name, sizeof(dir_name), "%s_dbg", dev_name(dd->dev)); + dd->dent_spi = debugfs_create_dir(dir_name, NULL); if (dd->dent_spi) { int i; for (i = 0; i < ARRAY_SIZE(debugfs_spi_regs); i++) { - debugfs_spi_regs[i].dd = dd; + dd->reg_data[i].offset = debugfs_spi_regs[i].offset; + dd->reg_data[i].dd = dd; dd->debugfs_spi_regs[i] = debugfs_create_file( debugfs_spi_regs[i].name, debugfs_spi_regs[i].mode, - dd->dent_spi, - debugfs_spi_regs+i, + dd->dent_spi, &dd->reg_data[i], &fops_iomem_x32); } } diff --git a/drivers/spi/spi_qsd.h b/drivers/spi/spi_qsd.h index fb906939c03a..444c7773f807 100644 --- a/drivers/spi/spi_qsd.h +++ b/drivers/spi/spi_qsd.h @@ -214,52 +214,48 @@ struct spi_cs_gpio { }; #ifdef CONFIG_DEBUG_FS +struct msm_spi_debugfs_data { + int offset; + struct msm_spi *dd; +}; /* Used to create debugfs entries */ static struct msm_spi_regs{ const char *name; mode_t mode; int offset; - struct msm_spi *dd; } debugfs_spi_regs[] = { - {"config", S_IRUGO | S_IWUSR, SPI_CONFIG, NULL}, - {"io_control", S_IRUGO | S_IWUSR, SPI_IO_CONTROL, NULL}, - {"io_modes", S_IRUGO | S_IWUSR, SPI_IO_MODES, NULL}, - {"sw_reset", S_IWUSR, SPI_SW_RESET, NULL}, - {"time_out_current", S_IRUGO, SPI_TIME_OUT_CURRENT, - NULL}, - {"mx_output_count", S_IRUGO | S_IWUSR, SPI_MX_OUTPUT_COUNT, - NULL}, - {"mx_output_cnt_current", S_IRUGO, SPI_MX_OUTPUT_CNT_CURRENT, - NULL}, - {"mx_input_count", S_IRUGO | S_IWUSR, SPI_MX_INPUT_COUNT, NULL}, - {"mx_input_cnt_current", S_IRUGO, SPI_MX_INPUT_CNT_CURRENT, - NULL}, - {"mx_read_count", S_IRUGO | S_IWUSR, SPI_MX_READ_COUNT, NULL}, - {"mx_read_cnt_current", S_IRUGO, SPI_MX_READ_CNT_CURRENT, - NULL}, - {"operational", S_IRUGO | S_IWUSR, SPI_OPERATIONAL, NULL}, - {"error_flags", S_IRUGO | S_IWUSR, SPI_ERROR_FLAGS, NULL}, - {"error_flags_en", S_IRUGO | S_IWUSR, SPI_ERROR_FLAGS_EN, NULL}, - {"deassert_wait", S_IRUGO | S_IWUSR, SPI_DEASSERT_WAIT, NULL}, - {"output_debug", S_IRUGO, SPI_OUTPUT_DEBUG, NULL}, - {"input_debug", S_IRUGO, SPI_INPUT_DEBUG, NULL}, - {"test_ctrl", S_IRUGO | S_IWUSR, SPI_TEST_CTRL, NULL}, - {"output_fifo", S_IWUSR, SPI_OUTPUT_FIFO, NULL}, - {"input_fifo" , S_IRUSR, SPI_INPUT_FIFO, NULL}, - {"spi_state", S_IRUGO | S_IWUSR, SPI_STATE, NULL}, + {"config", S_IRUGO | S_IWUSR, SPI_CONFIG }, + {"io_control", S_IRUGO | S_IWUSR, SPI_IO_CONTROL }, + {"io_modes", S_IRUGO | S_IWUSR, SPI_IO_MODES }, + {"sw_reset", S_IWUSR, SPI_SW_RESET }, + {"time_out_current", S_IRUGO, SPI_TIME_OUT_CURRENT }, + {"mx_output_count", S_IRUGO | S_IWUSR, SPI_MX_OUTPUT_COUNT }, + {"mx_output_cnt_current", S_IRUGO, + SPI_MX_OUTPUT_CNT_CURRENT }, + {"mx_input_count", S_IRUGO | S_IWUSR, SPI_MX_INPUT_COUNT }, + {"mx_input_cnt_current", S_IRUGO, SPI_MX_INPUT_CNT_CURRENT }, + {"mx_read_count", S_IRUGO | S_IWUSR, SPI_MX_READ_COUNT, }, + {"mx_read_cnt_current", S_IRUGO, SPI_MX_READ_CNT_CURRENT }, + {"operational", S_IRUGO | S_IWUSR, SPI_OPERATIONAL }, + {"error_flags", S_IRUGO | S_IWUSR, SPI_ERROR_FLAGS }, + {"error_flags_en", S_IRUGO | S_IWUSR, SPI_ERROR_FLAGS_EN }, + {"deassert_wait", S_IRUGO | S_IWUSR, SPI_DEASSERT_WAIT }, + {"output_debug", S_IRUGO, SPI_OUTPUT_DEBUG }, + {"input_debug", S_IRUGO, SPI_INPUT_DEBUG }, + {"test_ctrl", S_IRUGO | S_IWUSR, SPI_TEST_CTRL }, + {"output_fifo", S_IWUSR, SPI_OUTPUT_FIFO }, + {"input_fifo", S_IRUSR, SPI_INPUT_FIFO }, + {"spi_state", S_IRUGO | S_IWUSR, SPI_STATE }, #if defined(CONFIG_SPI_QSD) || defined(CONFIG_SPI_QSD_MODULE) - {"fifo_word_cnt", S_IRUGO, SPI_FIFO_WORD_CNT, NULL}, + {"fifo_word_cnt", S_IRUGO, SPI_FIFO_WORD_CNT }, #else - {"qup_config", S_IRUGO | S_IWUSR, QUP_CONFIG, NULL}, - {"qup_error_flags", S_IRUGO | S_IWUSR, QUP_ERROR_FLAGS, NULL}, - {"qup_error_flags_en", S_IRUGO | S_IWUSR, QUP_ERROR_FLAGS_EN, NULL}, - {"mx_write_cnt", S_IRUGO | S_IWUSR, QUP_MX_WRITE_COUNT, NULL}, - {"mx_write_cnt_current", S_IRUGO, QUP_MX_WRITE_CNT_CURRENT, - NULL}, - {"output_fifo_word_cnt", S_IRUGO, SPI_OUTPUT_FIFO_WORD_CNT, - NULL}, - {"input_fifo_word_cnt", S_IRUGO, SPI_INPUT_FIFO_WORD_CNT, - NULL}, + {"qup_config", S_IRUGO | S_IWUSR, QUP_CONFIG }, + {"qup_error_flags", S_IRUGO | S_IWUSR, QUP_ERROR_FLAGS }, + {"qup_error_flags_en", S_IRUGO | S_IWUSR, QUP_ERROR_FLAGS_EN }, + {"mx_write_cnt", S_IRUGO | S_IWUSR, QUP_MX_WRITE_COUNT }, + {"mx_write_cnt_current", S_IRUGO, QUP_MX_WRITE_CNT_CURRENT }, + {"output_fifo_word_cnt", S_IRUGO, SPI_OUTPUT_FIFO_WORD_CNT }, + {"input_fifo_word_cnt", S_IRUGO, SPI_INPUT_FIFO_WORD_CNT }, #endif }; #endif @@ -349,6 +345,7 @@ struct msm_spi { #ifdef CONFIG_DEBUG_FS struct dentry *dent_spi; struct dentry *debugfs_spi_regs[ARRAY_SIZE(debugfs_spi_regs)]; + struct msm_spi_debugfs_data reg_data[ARRAY_SIZE(debugfs_spi_regs)]; #endif struct msm_spi_platform_data *pdata; /* Platform data */ /* When set indicates multiple transfers in a single message */ From ea31a9294643707072ffb18794e5d91880ea962d Mon Sep 17 00:00:00 2001 From: Hamad Kadmany Date: Mon, 26 Dec 2016 14:57:52 +0200 Subject: [PATCH 73/73] msm_11ad: Add option to enable SMMU fastmap Option added not to bypass SMMU and use fastmap DMA APIs for 11ad use-cases. SMMU address range is changed to have the max possible. Change-Id: I073ab59cc4ef1b71545a9e77b76d94f09d659aac CRs-Fixed: 1105323 Signed-off-by: Hamad Kadmany --- drivers/platform/msm/msm_11ad/msm_11ad.c | 37 +++++++++++++++++------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/drivers/platform/msm/msm_11ad/msm_11ad.c b/drivers/platform/msm/msm_11ad/msm_11ad.c index 5810f7bf7f2f..b7fc68a6efdd 100644 --- a/drivers/platform/msm/msm_11ad/msm_11ad.c +++ b/drivers/platform/msm/msm_11ad/msm_11ad.c @@ -33,7 +33,7 @@ #define WIGIG_DEVICE (0x0310) #define SMMU_BASE 0x10000000 /* Device address range base */ -#define SMMU_SIZE 0x40000000 /* Device address range size */ +#define SMMU_SIZE ((SZ_1G * 4ULL) - SMMU_BASE) #define WIGIG_ENABLE_DELAY 50 #define PM_OPT_SUSPEND (MSM_PCIE_CONFIG_NO_CFG_RESTORE | \ @@ -87,6 +87,8 @@ struct msm11ad_ctx { /* SMMU */ bool use_smmu; /* have SMMU enabled? */ + int smmu_bypass; + int smmu_fast_map; struct dma_iommu_mapping *mapping; /* bus frequency scaling */ @@ -596,11 +598,13 @@ static int msm_11ad_smmu_init(struct msm11ad_ctx *ctx) { int atomic_ctx = 1; int rc; - int bypass_enable = 1; if (!ctx->use_smmu) return 0; + dev_info(ctx->dev, "Initialize SMMU, bypass = %d, fastmap = %d\n", + ctx->smmu_bypass, ctx->smmu_fast_map); + ctx->mapping = arm_iommu_create_mapping(&platform_bus_type, SMMU_BASE, SMMU_SIZE); if (IS_ERR_OR_NULL(ctx->mapping)) { @@ -608,7 +612,6 @@ static int msm_11ad_smmu_init(struct msm11ad_ctx *ctx) dev_err(ctx->dev, "Failed to create IOMMU mapping (%d)\n", rc); return rc; } - dev_info(ctx->dev, "IOMMU mapping created: %p\n", ctx->mapping); rc = iommu_domain_set_attr(ctx->mapping->domain, DOMAIN_ATTR_ATOMIC, @@ -619,13 +622,24 @@ static int msm_11ad_smmu_init(struct msm11ad_ctx *ctx) goto release_mapping; } - rc = iommu_domain_set_attr(ctx->mapping->domain, - DOMAIN_ATTR_S1_BYPASS, - &bypass_enable); - if (rc) { - dev_err(ctx->dev, "Set bypass attribute to SMMU failed (%d)\n", - rc); - goto release_mapping; + if (ctx->smmu_bypass) { + rc = iommu_domain_set_attr(ctx->mapping->domain, + DOMAIN_ATTR_S1_BYPASS, + &ctx->smmu_bypass); + if (rc) { + dev_err(ctx->dev, "Set bypass attribute to SMMU failed (%d)\n", + rc); + goto release_mapping; + } + } else if (ctx->smmu_fast_map) { + rc = iommu_domain_set_attr(ctx->mapping->domain, + DOMAIN_ATTR_FAST, + &ctx->smmu_fast_map); + if (rc) { + dev_err(ctx->dev, "Set fast attribute to SMMU failed (%d)\n", + rc); + goto release_mapping; + } } rc = arm_iommu_attach_device(&ctx->pcidev->dev, ctx->mapping); @@ -870,6 +884,9 @@ static int msm_11ad_probe(struct platform_device *pdev) ctx->use_smmu = of_property_read_bool(of_node, "qcom,smmu-support"); ctx->bus_scale = msm_bus_cl_get_pdata(pdev); + ctx->smmu_bypass = 1; + ctx->smmu_fast_map = 0; + /*== execute ==*/ /* turn device on */ rc = msm_11ad_init_vregs(ctx);