From ab5985e13e1c5502e289b2c65d7bf381fcbdfd71 Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Wed, 2 Nov 2016 10:09:41 -0700 Subject: icnss: Update WLFW header file to the latest and add fw_build_id Update WLFW header file to the latest and add fw_build_id in capability response message so that host could know which FW build it is. CRs-Fixed: 1082787 Change-Id: I8c8bcf9da42668f3964b4dffcbc1b15465ea8018 Signed-off-by: Yuanyuan Liu --- drivers/soc/qcom/icnss.c | 11 ++++- drivers/soc/qcom/wlan_firmware_service_v01.c | 62 ++++++++++++++++++++++++++++ drivers/soc/qcom/wlan_firmware_service_v01.h | 22 +++++++++- 3 files changed, 92 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index feeed645fc47..000ccaba8728 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -439,6 +439,7 @@ static struct icnss_priv { struct wlfw_rf_board_info_s_v01 board_info; struct wlfw_soc_info_s_v01 soc_info; struct wlfw_fw_version_info_s_v01 fw_version_info; + char fw_build_id[QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1]; u32 pwr_pin_result; u32 phy_io_pin_result; u32 rf_pin_result; @@ -1971,12 +1972,16 @@ static int wlfw_cap_send_sync_msg(void) penv->soc_info = resp.soc_info; if (resp.fw_version_info_valid) penv->fw_version_info = resp.fw_version_info; + if (resp.fw_build_id_valid) + strlcpy(penv->fw_build_id, resp.fw_build_id, + QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1); - icnss_pr_dbg("Capability, chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 0x%x, fw_version: 0x%x, fw_build_timestamp: %s", + icnss_pr_dbg("Capability, chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 0x%x, fw_version: 0x%x, fw_build_timestamp: %s, fw_build_id: %s", penv->chip_info.chip_id, penv->chip_info.chip_family, penv->board_info.board_id, penv->soc_info.soc_id, penv->fw_version_info.fw_version, - penv->fw_version_info.fw_build_timestamp); + penv->fw_version_info.fw_build_timestamp, + penv->fw_build_id); return 0; @@ -3929,6 +3934,8 @@ static int icnss_stats_show_capability(struct seq_file *s, priv->fw_version_info.fw_version); seq_printf(s, "Firmware Build Timestamp: %s\n", priv->fw_version_info.fw_build_timestamp); + seq_printf(s, "Firmware Build ID: %s\n", + priv->fw_build_id); } return 0; diff --git a/drivers/soc/qcom/wlan_firmware_service_v01.c b/drivers/soc/qcom/wlan_firmware_service_v01.c index f5f7ae8c9901..3e00d6c9d153 100644 --- a/drivers/soc/qcom/wlan_firmware_service_v01.c +++ b/drivers/soc/qcom/wlan_firmware_service_v01.c @@ -765,6 +765,24 @@ struct elem_info wlfw_cap_resp_msg_v01_ei[] = { fw_version_info), .ei_array = wlfw_fw_version_info_s_v01_ei, }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x14, + .offset = offsetof(struct wlfw_cap_resp_msg_v01, + fw_build_id_valid), + }, + { + .data_type = QMI_STRING, + .elem_len = QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1, + .elem_size = sizeof(char), + .is_array = NO_ARRAY, + .tlv_type = 0x14, + .offset = offsetof(struct wlfw_cap_resp_msg_v01, + fw_build_id), + }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, @@ -1588,3 +1606,47 @@ struct elem_info wlfw_vbatt_resp_msg_v01_ei[] = { .is_array = QMI_COMMON_TLV_TYPE, }, }; + +struct elem_info wlfw_mac_addr_req_msg_v01_ei[] = { + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wlfw_mac_addr_req_msg_v01, + mac_addr_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = QMI_WLFW_MAC_ADDR_SIZE_V01, + .elem_size = sizeof(uint8_t), + .is_array = STATIC_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wlfw_mac_addr_req_msg_v01, + mac_addr), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_mac_addr_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct wlfw_mac_addr_resp_msg_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; diff --git a/drivers/soc/qcom/wlan_firmware_service_v01.h b/drivers/soc/qcom/wlan_firmware_service_v01.h index 29bdfb23480a..47b315fce94c 100644 --- a/drivers/soc/qcom/wlan_firmware_service_v01.h +++ b/drivers/soc/qcom/wlan_firmware_service_v01.h @@ -24,6 +24,7 @@ #define QMI_WLFW_CAL_DOWNLOAD_RESP_V01 0x0027 #define QMI_WLFW_INI_RESP_V01 0x002F #define QMI_WLFW_CAL_REPORT_RESP_V01 0x0026 +#define QMI_WLFW_MAC_ADDR_RESP_V01 0x0033 #define QMI_WLFW_INITIATE_CAL_DOWNLOAD_IND_V01 0x0028 #define QMI_WLFW_MSA_READY_IND_V01 0x002B #define QMI_WLFW_ATHDIAG_WRITE_RESP_V01 0x0031 @@ -43,6 +44,7 @@ #define QMI_WLFW_CAP_RESP_V01 0x0024 #define QMI_WLFW_ATHDIAG_READ_RESP_V01 0x0030 #define QMI_WLFW_VBATT_REQ_V01 0x0032 +#define QMI_WLFW_MAC_ADDR_REQ_V01 0x0033 #define QMI_WLFW_VBATT_RESP_V01 0x0032 #define QMI_WLFW_MSA_INFO_REQ_V01 0x002D #define QMI_WLFW_CAL_DOWNLOAD_REQ_V01 0x0027 @@ -57,6 +59,8 @@ #define QMI_WLFW_MAX_TIMESTAMP_LEN_V01 32 #define QMI_WLFW_MAX_STR_LEN_V01 16 #define QMI_WLFW_MAX_NUM_SHADOW_REG_V01 24 +#define QMI_WLFW_MAC_ADDR_SIZE_V01 6 +#define QMI_WLFW_MAX_BUILD_ID_LEN_V01 128 #define QMI_WLFW_MAX_NUM_SVC_V01 24 enum wlfw_driver_mode_enum_v01 { @@ -99,6 +103,7 @@ enum wlfw_pipedir_enum_v01 { #define QMI_WLFW_ALREADY_REGISTERED_V01 ((uint64_t)0x01ULL) #define QMI_WLFW_FW_READY_V01 ((uint64_t)0x02ULL) +#define QMI_WLFW_MSA_READY_V01 ((uint64_t)0x04ULL) struct wlfw_ce_tgt_pipe_cfg_s_v01 { uint32_t pipe_num; @@ -243,8 +248,10 @@ struct wlfw_cap_resp_msg_v01 { struct wlfw_soc_info_s_v01 soc_info; uint8_t fw_version_info_valid; struct wlfw_fw_version_info_s_v01 fw_version_info; + uint8_t fw_build_id_valid; + char fw_build_id[QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1]; }; -#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 72 +#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 203 extern struct elem_info wlfw_cap_resp_msg_v01_ei[]; struct wlfw_bdf_download_req_msg_v01 { @@ -428,4 +435,17 @@ struct wlfw_vbatt_resp_msg_v01 { #define WLFW_VBATT_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_vbatt_resp_msg_v01_ei[]; +struct wlfw_mac_addr_req_msg_v01 { + uint8_t mac_addr_valid; + uint8_t mac_addr[QMI_WLFW_MAC_ADDR_SIZE_V01]; +}; +#define WLFW_MAC_ADDR_REQ_MSG_V01_MAX_MSG_LEN 9 +extern struct elem_info wlfw_mac_addr_req_msg_v01_ei[]; + +struct wlfw_mac_addr_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; +#define WLFW_MAC_ADDR_RESP_MSG_V01_MAX_MSG_LEN 7 +extern struct elem_info wlfw_mac_addr_resp_msg_v01_ei[]; + #endif -- cgit v1.2.3 From 9b67d14af22ee19a0477ace4729894ff9ab32132 Mon Sep 17 00:00:00 2001 From: Krishnankutty Kolathappilly Date: Fri, 28 Oct 2016 11:10:22 -0700 Subject: ARM: dts: msm: Add cpp src clock rates configuration for msmcobalt Add cpp src clock rates to device node configuration. Add separate cpp node for msmcobalt v2 as there is difference in clock rates. CRs-Fixed: 1079648 Change-Id: I436ad7fca01e599714f1bcb0abc06e5bc1165350 Signed-off-by: Krishnankutty Kolathappilly --- arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi | 2 + arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi | 71 +++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi index 27e537c9c702..6a0061e206ca 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi +++ b/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi @@ -422,6 +422,8 @@ qcom,msm-bus-vector-dyn-vote; resets = <&clock_mmss CAMSS_MICRO_BCR>; reset-names = "micro_iface_reset"; + qcom,src-clock-rates = <100000000 200000000 576000000 + 600000000>; qcom,cpp-fw-payload-info { qcom,stripe-base = <790>; qcom,plane-base = <715>; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi index fcc4d6d8ee2d..a81287c36266 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi +++ b/arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi @@ -116,5 +116,76 @@ 0 256000000 0>; status = "ok"; }; + + qcom,cpp@ca04000 { + cell-index = <0>; + compatible = "qcom,cpp"; + reg = <0xca04000 0x100>, + <0xca80000 0x3000>, + <0xca18000 0x3000>, + <0xc8c36d4 0x4>; + reg-names = "cpp", "cpp_vbif", "cpp_hw", "camss_cpp"; + interrupts = <0 294 0>; + interrupt-names = "cpp"; + smmu-vdd-supply = <&gdsc_bimc_smmu>; + camss-vdd-supply = <&gdsc_camss_top>; + vdd-supply = <&gdsc_cpp>; + qcom,vdd-names = "smmu-vdd", "camss-vdd", "vdd"; + clocks = <&clock_gcc clk_mmssnoc_axi_clk>, + <&clock_mmss clk_mmss_mnoc_ahb_clk>, + <&clock_mmss clk_mmss_camss_ahb_clk>, + <&clock_mmss clk_mmss_camss_top_ahb_clk>, + <&clock_mmss clk_cpp_clk_src>, + <&clock_mmss clk_mmss_camss_cpp_clk>, + <&clock_mmss clk_mmss_camss_cpp_ahb_clk>, + <&clock_mmss clk_mmss_camss_cpp_axi_clk>, + <&clock_mmss clk_mmss_camss_micro_ahb_clk>, + <&clock_mmss clk_mmss_bimc_smmu_axi_clk>, + <&clock_mmss clk_mmss_camss_cpp_vbif_ahb_clk>; + clock-names = "mmssnoc_axi_clk", + "mnoc_ahb_clk", + "camss_ahb_clk", "camss_top_ahb_clk", + "cpp_src_clk", + "cpp_core_clk", "camss_cpp_ahb_clk", + "camss_cpp_axi_clk", "micro_iface_clk", + "mmss_smmu_axi_clk", "cpp_vbif_ahb_clk"; + qcom,clock-rates = <0 0 0 0 200000000 200000000 0 0 0 0 0>; + qcom,min-clock-rate = <200000000>; + qcom,bus-master = <1>; + qcom,vbif-qos-setting = <0x20 0x10000000>, + <0x24 0x10000000>, + <0x28 0x10000000>, + <0x2C 0x10000000>; + status = "ok"; + qcom,msm-bus,name = "msm_camera_cpp"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <106 512 0 0>, + <106 512 0 0>; + qcom,msm-bus-vector-dyn-vote; + resets = <&clock_mmss CAMSS_MICRO_BCR>; + reset-names = "micro_iface_reset"; + qcom,src-clock-rates = <100000000 200000000 384000000 404000000 + 480000000 576000000 600000000>; + qcom,cpp-fw-payload-info { + qcom,stripe-base = <790>; + qcom,plane-base = <715>; + qcom,stripe-size = <63>; + qcom,plane-size = <25>; + qcom,fe-ptr-off = <11>; + qcom,we-ptr-off = <23>; + qcom,ref-fe-ptr-off = <17>; + qcom,ref-we-ptr-off = <36>; + qcom,we-meta-ptr-off = <42>; + qcom,fe-mmu-pf-ptr-off = <7>; + qcom,ref-fe-mmu-pf-ptr-off = <10>; + qcom,we-mmu-pf-ptr-off = <13>; + qcom,dup-we-mmu-pf-ptr-off = <18>; + qcom,ref-we-mmu-pf-ptr-off = <23>; + qcom,set-group-buffer-len = <135>; + qcom,dup-frame-indicator-off = <70>; + }; + }; }; -- cgit v1.2.3 From 17c4d6584e5ce7eb76de6b35290516a608fdd4f1 Mon Sep 17 00:00:00 2001 From: Krishnankutty Kolathappilly Date: Fri, 28 Oct 2016 11:13:37 -0700 Subject: msm: cpp: Use the src clock node to read the cpp src clock rate Use the src clock binding to read the cpp src clock rate intead of using the list rate api from clock driver. CRs-Fixed: 1079648 Change-Id: I2ebdc0c41c521e56a400d685b6254174cffdc14b Signed-off-by: Krishnankutty Kolathappilly --- .../devicetree/bindings/media/video/msm-cpp.txt | 4 ++ .../platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c | 74 ++++++++++++++++------ 2 files changed, 57 insertions(+), 21 deletions(-) diff --git a/Documentation/devicetree/bindings/media/video/msm-cpp.txt b/Documentation/devicetree/bindings/media/video/msm-cpp.txt index 52abf409cb65..ade5fbe8cbd7 100644 --- a/Documentation/devicetree/bindings/media/video/msm-cpp.txt +++ b/Documentation/devicetree/bindings/media/video/msm-cpp.txt @@ -26,6 +26,8 @@ Required properties: and reset lines used by this controller. - reset-names: reset signal name strings sorted in the same order as the resets property. +- qcom,src-clock-rates = This is an array which holds clock rates for cpp src + clocks. The maximum size for the array is 10. Required properties of the child node: - qcom,stripe-base = Base offset of stripes in cpp payload. @@ -107,6 +109,8 @@ Example: <0x24 0x10000000>, <0x28 0x10000000>, <0x2C 0x10000000>; + qcom,src-clock-rates = <100000000 200000000 384000000 404000000 + 480000000 576000000 600000000>; qcom,cpp-fw-payload-info { qcom,stripe-base = <553>; qcom,plane-base = <481>; 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 2c313016bc90..8213f736205a 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 @@ -66,39 +66,72 @@ int msm_cpp_get_clock_index(struct cpp_device *cpp_dev, const char *clk_name) return -EINVAL; } -static int cpp_get_clk_freq_tbl(struct clk *clk, struct cpp_hw_info *hw_info, - uint32_t min_clk_rate) +static int cpp_get_clk_freq_tbl_dt(struct cpp_device *cpp_dev) { - uint32_t i; + uint32_t i, count, min_clk_rate; uint32_t idx = 0; - signed long freq_tbl_entry = 0; + struct device_node *of_node; + uint32_t *rates; + int32_t rc = 0; + struct cpp_hw_info *hw_info; - if ((clk == NULL) || (hw_info == NULL) || (clk->ops == NULL) || - (clk->ops->list_rate == NULL)) { + if (cpp_dev == NULL) { pr_err("Bad parameter\n"); - return -EINVAL; + rc = -EINVAL; + goto err; } - for (i = 0; i < MAX_FREQ_TBL; i++) { - freq_tbl_entry = clk->ops->list_rate(clk, i); - pr_debug("entry=%ld\n", freq_tbl_entry); - if (freq_tbl_entry >= 0) { - if (freq_tbl_entry >= min_clk_rate) { - hw_info->freq_tbl[idx++] = freq_tbl_entry; - pr_debug("tbl[%d]=%ld\n", idx-1, - freq_tbl_entry); + of_node = cpp_dev->pdev->dev.of_node; + min_clk_rate = cpp_dev->min_clk_rate; + 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); + rc = -EINVAL; + goto err; + + } + count = of_property_count_u32_elems(of_node, "qcom,src-clock-rates"); + if ((count == 0) || (count > MAX_FREQ_TBL)) { + pr_err("Clock count is invalid\n"); + rc = -EINVAL; + goto err; + } + + rates = devm_kcalloc(&cpp_dev->pdev->dev, count, sizeof(uint32_t), + GFP_KERNEL); + if (!rates) { + rc = -ENOMEM; + goto err; + } + + rc = of_property_read_u32_array(of_node, "qcom,src-clock-rates", + rates, count); + if (rc) { + rc = -EINVAL; + goto mem_free; + } + + for (i = 0; i < count; i++) { + pr_debug("entry=%d\n", rates[i]); + if (rates[i] >= 0) { + if (rates[i] >= min_clk_rate) { + hw_info->freq_tbl[idx++] = rates[i]; + pr_debug("tbl[%d]=%d\n", idx-1, rates[i]); } } else { - pr_debug("freq table returned invalid entry/end %ld\n", - freq_tbl_entry); + pr_debug("rate is invalid entry/end %d\n", rates[i]); break; } } - pr_debug("%s: idx %d", __func__, idx); + pr_debug("%s: idx %d\n", __func__, idx); hw_info->freq_tbl_count = idx; - return 0; +mem_free: + devm_kfree(&cpp_dev->pdev->dev, rates); +err: + return rc; } int msm_cpp_set_micro_clk(struct cpp_device *cpp_dev) @@ -147,8 +180,7 @@ int msm_update_freq_tbl(struct cpp_device *cpp_dev) rc = msm_cpp_core_clk_idx; return rc; } - rc = cpp_get_clk_freq_tbl(cpp_dev->cpp_clk[msm_cpp_core_clk_idx], - &cpp_dev->hw_info, cpp_dev->min_clk_rate); + rc = cpp_get_clk_freq_tbl_dt(cpp_dev); if (rc < 0) { pr_err("%s: fail to get frequency table\n", __func__); return rc; -- cgit v1.2.3 From 39e8fe5924e7edeef614d049452c8b7b26f5655e Mon Sep 17 00:00:00 2001 From: Benjamin Chan Date: Tue, 8 Nov 2016 21:48:21 -0500 Subject: msm: sde: Fix SDE rotator context list locking During rotator IRQ handling, it is possible that the context list getting updated with open and close handling within the IRQ timeframe, so it is necessary to add the spinlock to protect the context list. CRs-Fixed: 1087423 Change-Id: I20a04c766e55c75db15662e9a13e20396b35f30e Signed-off-by: Benjamin Chan --- .../platform/msm/sde/rotator/sde_rotator_r3.c | 3 ++- .../msm/sde/rotator/sde_rotator_r3_internal.h | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c index 925b8497273a..4e86a3ff820d 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c @@ -1502,7 +1502,8 @@ static void sde_hw_rotator_free_rotctx(struct sde_hw_rotator *rot, ctx->q_id, ctx->timestamp, atomic_read(&ctx->hwres->num_active)); - rot->rotCtx[ctx->q_id][sde_hw_rotator_get_regdma_ctxidx(ctx)] = NULL; + /* Clear rotator context from lookup purpose */ + sde_hw_rotator_clr_ctx(ctx); devm_kfree(&rot->pdev->dev, ctx); } diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h index 91ac3d0371fa..7aecc3cee210 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h @@ -345,10 +345,32 @@ static inline void sde_hw_rotator_put_ctx(struct sde_hw_rotator_context *ctx) { struct sde_hw_rotator *rot = ctx->rot; u32 idx = sde_hw_rotator_get_regdma_ctxidx(ctx); + unsigned long flags; + spin_lock_irqsave(&rot->rotisr_lock, flags); rot->rotCtx[ctx->q_id][idx] = ctx; + spin_unlock_irqrestore(&rot->rotisr_lock, flags); + SDEROT_DBG("rotCtx[%d][%d] <== ctx:%p | session-id:%d\n", ctx->q_id, idx, ctx, ctx->session_id); } +/** + * sde_hw_rotator_clr_ctx(): Clearing rotator context according to its + * timestamp. + */ +static inline void sde_hw_rotator_clr_ctx(struct sde_hw_rotator_context *ctx) +{ + struct sde_hw_rotator *rot = ctx->rot; + u32 idx = sde_hw_rotator_get_regdma_ctxidx(ctx); + unsigned long flags; + + spin_lock_irqsave(&rot->rotisr_lock, flags); + rot->rotCtx[ctx->q_id][idx] = NULL; + spin_unlock_irqrestore(&rot->rotisr_lock, flags); + + SDEROT_DBG("rotCtx[%d][%d] <== null | session-id:%d\n", + ctx->q_id, idx, ctx->session_id); +} + #endif /*_SDE_ROTATOR_R3_INTERNAL_H */ -- cgit v1.2.3 From e146a32840b45f772c444a623172495bfb9fc183 Mon Sep 17 00:00:00 2001 From: Fenglin Wu Date: Tue, 8 Nov 2016 15:35:04 +0800 Subject: leds: qpnp-wled: Add support to configure VREF_CONTROL for pmicobalt WLED module in pmicobalt has different VREF_CONTROL settings with current WLED module which is existing in pmi8994/pmi8952, including min voltage, max voltage, step size and default voltage. Add support for it. CRs-Fixed: 1081738 Change-Id: Ibaa555cec8cfd296125af3e6277df5331f5c438b Signed-off-by: Fenglin Wu --- .../devicetree/bindings/leds/leds-qpnp-wled.txt | 8 ++- arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi | 2 +- arch/arm/boot/dts/qcom/msm-pmi8994.dtsi | 2 +- arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi | 2 +- drivers/leds/leds-qpnp-wled.c | 82 +++++++++++++++------- 5 files changed, 66 insertions(+), 30 deletions(-) diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt b/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt index ebbcfe5b2fd0..07f3fd274658 100644 --- a/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt +++ b/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt @@ -25,7 +25,11 @@ Optional properties for WLED: - linux,default-trigger : trigger for the backlight. default is NONE. - qcom,fdbk-output : string feedback current output for wled module. The accepted values are "wled1", "wled2", "wled3", "wled4" and "auto". default is "auto". -- qcom,vref-mv : maximum reference voltage in mv. default is 350. +- qcom,vref-uv : maximum reference voltage in uV. + For pmi8994/8952/8996, supported values are from 300000 to 675000 + with a step size of 25000, the default value is 350000. + For pmicobalt/pm2falcon, supported values are from 60000 to 397500 + with a step size of 22500, the default value is 127500. - qcom,switch-freq-khz : switch frequency in khz. default is 800. - qcom,ovp-mv : Over voltage protection threshold in mV. Default is 29500. Supported values are: @@ -94,7 +98,7 @@ Example: linux,name = "wled"; linux,default-trigger = "bkl-trigger"; qcom,fdbk-output = "auto"; - qcom,vref-mv = <350>; + qcom,vref-uv = <350000>; qcom,switch-freq-khz = <800>; qcom,ovp-mv = <29500>; qcom,ilim-ma = <980>; diff --git a/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi b/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi index 41589d02f6fc..4ab1b56bd48d 100644 --- a/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi @@ -234,7 +234,7 @@ linux,name = "wled"; linux,default-trigger = "bkl-trigger"; qcom,fdbk-output = "auto"; - qcom,vref-mv = <350>; + qcom,vref-uv = <127500>; qcom,switch-freq-khz = <800>; qcom,ovp-mv = <29600>; qcom,ilim-ma = <970>; diff --git a/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi b/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi index bba70329c819..ceb48109febb 100644 --- a/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi @@ -523,7 +523,7 @@ linux,name = "wled"; linux,default-trigger = "bkl-trigger"; qcom,fdbk-output = "auto"; - qcom,vref-mv = <350>; + qcom,vref-uv = <350000>; qcom,switch-freq-khz = <800>; qcom,ovp-mv = <29500>; qcom,ilim-ma = <980>; diff --git a/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi b/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi index a5243aff4282..8c0c65361f2c 100644 --- a/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi @@ -594,7 +594,7 @@ linux,name = "wled"; linux,default-trigger = "bkl-trigger"; qcom,fdbk-output = "auto"; - qcom,vref-mv = <350>; + qcom,vref-uv = <127500>; qcom,switch-freq-khz = <800>; qcom,ovp-mv = <29600>; qcom,ilim-ma = <970>; diff --git a/drivers/leds/leds-qpnp-wled.c b/drivers/leds/leds-qpnp-wled.c index 894c1d88b3ef..97cfa813f4ce 100644 --- a/drivers/leds/leds-qpnp-wled.c +++ b/drivers/leds/leds-qpnp-wled.c @@ -61,11 +61,7 @@ #define QPNP_WLED_EN_MASK 0x7F #define QPNP_WLED_EN_SHIFT 7 #define QPNP_WLED_FDBK_OP_MASK 0xF8 -#define QPNP_WLED_VREF_MASK 0xF0 -#define QPNP_WLED_VREF_STEP_MV 25 -#define QPNP_WLED_VREF_MIN_MV 300 -#define QPNP_WLED_VREF_MAX_MV 675 -#define QPNP_WLED_DFLT_VREF_MV 350 +#define QPNP_WLED_VREF_MASK GENMASK(3, 0) #define QPNP_WLED_VLOOP_COMP_RES_MASK 0xF0 #define QPNP_WLED_VLOOP_COMP_RES_OVERWRITE 0x80 @@ -275,6 +271,20 @@ static int qpnp_wled_ilim_settings_pmicobalt[NUM_SUPPORTED_ILIM_THRESHOLDS] = { 105, 280, 450, 620, 970, 1150, 1300, 1500, }; +struct wled_vref_setting { + u32 min_uv; + u32 max_uv; + u32 step_uv; + u32 default_uv; +}; + +static struct wled_vref_setting vref_setting_pmi8994 = { + 300000, 675000, 25000, 350000, +}; +static struct wled_vref_setting vref_setting_pmicobalt = { + 60000, 397500, 22500, 127500, +}; + /** * qpnp_wled - wed data structure * @ cdev - led class device @@ -294,7 +304,7 @@ static int qpnp_wled_ilim_settings_pmicobalt[NUM_SUPPORTED_ILIM_THRESHOLDS] = { * @ mod_freq_khz - modulator frequency in KHZ * @ hyb_thres - threshold for hybrid dimming * @ sync_dly_us - sync delay in us - * @ vref_mv - ref voltage in mv + * @ vref_uv - ref voltage in uv * @ vref_psm_mv - ref psm voltage in mv * @ loop_comp_res_kohm - control to select the compensation resistor * @ loop_ea_gm - control to select the gm for the gm stage in control loop @@ -337,7 +347,7 @@ struct qpnp_wled { u16 mod_freq_khz; u16 hyb_thres; u16 sync_dly_us; - u16 vref_mv; + u32 vref_uv; u16 vref_psm_mv; u16 loop_comp_res_kohm; u16 loop_ea_gm; @@ -1248,6 +1258,35 @@ static int qpnp_wled_ilim_config(struct qpnp_wled *wled) return rc; } +static int qpnp_wled_vref_config(struct qpnp_wled *wled) +{ + + struct wled_vref_setting vref_setting; + int rc; + u8 reg = 0; + + if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE || + wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) + vref_setting = vref_setting_pmicobalt; + else + vref_setting = vref_setting_pmi8994; + + if (wled->vref_uv < vref_setting.min_uv) + wled->vref_uv = vref_setting.min_uv; + else if (wled->vref_uv > vref_setting.max_uv) + wled->vref_uv = vref_setting.max_uv; + + reg |= DIV_ROUND_CLOSEST(wled->vref_uv - vref_setting.min_uv, + vref_setting.step_uv); + + rc = qpnp_wled_masked_write_reg(wled, QPNP_WLED_VREF_MASK, + ®, QPNP_WLED_VREF_REG(wled->ctrl_base)); + if (rc) + pr_err("Write VREF_REG failed, rc=%d\n", rc); + + return rc; +} + /* Configure WLED registers */ static int qpnp_wled_config(struct qpnp_wled *wled) { @@ -1272,22 +1311,11 @@ static int qpnp_wled_config(struct qpnp_wled *wled) return rc; /* Configure the VREF register */ - if (wled->vref_mv < QPNP_WLED_VREF_MIN_MV) - wled->vref_mv = QPNP_WLED_VREF_MIN_MV; - else if (wled->vref_mv > QPNP_WLED_VREF_MAX_MV) - wled->vref_mv = QPNP_WLED_VREF_MAX_MV; - - rc = qpnp_wled_read_reg(wled, ®, - QPNP_WLED_VREF_REG(wled->ctrl_base)); - if (rc < 0) - return rc; - reg &= QPNP_WLED_VREF_MASK; - temp = wled->vref_mv - QPNP_WLED_VREF_MIN_MV; - reg |= (temp / QPNP_WLED_VREF_STEP_MV); - rc = qpnp_wled_write_reg(wled, reg, - QPNP_WLED_VREF_REG(wled->ctrl_base)); - if (rc) + rc = qpnp_wled_vref_config(wled); + if (rc < 0) { + pr_err("Error in configuring wled vref, rc=%d\n", rc); return rc; + } /* Configure the ILIM register */ rc = qpnp_wled_ilim_config(wled); @@ -1714,11 +1742,15 @@ static int qpnp_wled_parse_dt(struct qpnp_wled *wled) return rc; } - wled->vref_mv = QPNP_WLED_DFLT_VREF_MV; + if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE || + wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) + wled->vref_uv = vref_setting_pmicobalt.default_uv; + else + wled->vref_uv = vref_setting_pmi8994.default_uv; rc = of_property_read_u32(pdev->dev.of_node, - "qcom,vref-mv", &temp_val); + "qcom,vref-uv", &temp_val); if (!rc) { - wled->vref_mv = temp_val; + wled->vref_uv = temp_val; } else if (rc != -EINVAL) { dev_err(&pdev->dev, "Unable to read vref\n"); return rc; -- cgit v1.2.3 From 5090370f0363ba2b07dfcbf906981770ab6893dd Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Tue, 4 Oct 2016 10:32:58 -0700 Subject: icnss: Collect ramdump from MSA memory space Collect ramdump from MSA memory space when Modem SSR happens. WLAN FW runs on modem and stores some data on APPS MSA memory space. In order to collect full data of FW during Modem SSR, ICNSS platform listens for Modem SSR notification and collects MSA ramdump. CRs-Fixed: 1088608 Change-Id: I9c014261f5e25b3ec4585747d324ea2cb6ab18fb Signed-off-by: Yuanyuan Liu --- drivers/soc/qcom/icnss.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index feeed645fc47..a40c75990bfb 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -45,6 +45,7 @@ #include #include #include +#include #include "wlan_firmware_service_v01.h" @@ -463,6 +464,7 @@ static struct icnss_priv { struct qpnp_vadc_chip *vadc_dev; uint64_t vph_pwr; atomic_t pm_count; + struct ramdump_device *msa0_dump_dev; } *penv; static void icnss_hw_write_reg(void *base, u32 offset, u32 val) @@ -2657,8 +2659,6 @@ static int icnss_driver_event_pd_service_down(struct icnss_priv *priv, out: ret = icnss_hw_power_off(priv); - icnss_remove_msa_permissions(priv); - kfree(data); return ret; @@ -2763,6 +2763,16 @@ static int icnss_qmi_wlfw_clnt_svc_event_notify(struct notifier_block *this, return ret; } +static int icnss_msa0_ramdump(struct icnss_priv *priv) +{ + struct ramdump_segment segment; + + memset(&segment, 0, sizeof(segment)); + segment.v_address = priv->msa_va; + segment.size = priv->msa_mem_size; + return do_ramdump(priv->msa0_dump_dev, &segment, 1); +} + static struct notifier_block wlfw_clnt_nb = { .notifier_call = icnss_qmi_wlfw_clnt_svc_event_notify, }; @@ -2778,9 +2788,19 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, icnss_pr_dbg("Modem-Notify: event %lu\n", code); + if (code == SUBSYS_AFTER_SHUTDOWN) { + icnss_remove_msa_permissions(priv); + icnss_pr_info("Collecting msa0 segment dump\n"); + icnss_msa0_ramdump(priv); + return NOTIFY_OK; + } + if (code != SUBSYS_BEFORE_SHUTDOWN) return NOTIFY_OK; + if (test_bit(ICNSS_PDR_ENABLED, &priv->state)) + return NOTIFY_OK; + icnss_pr_info("Modem went down, state: %lx\n", priv->state); event_data = kzalloc(sizeof(*data), GFP_KERNEL); @@ -2936,8 +2956,6 @@ static int icnss_get_service_location_notify(struct notifier_block *nb, set_bit(ICNSS_PDR_ENABLED, &priv->state); - icnss_modem_ssr_unregister_notifier(priv); - icnss_pr_dbg("PD restart enabled, state: 0x%lx\n", priv->state); return NOTIFY_OK; @@ -3000,6 +3018,11 @@ static int icnss_enable_recovery(struct icnss_priv *priv) goto enable_pdr; } + priv->msa0_dump_dev = create_ramdump_device("wcss_msa0", + &priv->pdev->dev); + if (!priv->msa0_dump_dev) + return -ENOMEM; + icnss_modem_ssr_register_notifier(priv); if (test_bit(SSR_ONLY, &quirks)) { icnss_pr_dbg("PDR disabled through module parameter\n"); @@ -4511,6 +4534,8 @@ static int icnss_remove(struct platform_device *pdev) icnss_modem_ssr_unregister_notifier(penv); + destroy_ramdump_device(penv->msa0_dump_dev); + icnss_pdr_unregister_notifier(penv); qmi_svc_event_notifier_unregister(WLFW_SERVICE_ID_V01, @@ -4522,6 +4547,8 @@ static int icnss_remove(struct platform_device *pdev) icnss_hw_power_off(penv); + icnss_remove_msa_permissions(penv); + dev_set_drvdata(&pdev->dev, NULL); return 0; -- cgit v1.2.3